import { FC, useCallback, useEffect, useRef, useState } from "react";
import { observer } from "mobx-react";
import { useRouter } from "next/router";
import { EditorRefApi } from "@plane/rich-text-editor";
import { TIssue } from "@plane/types";
import { Button, TOAST_TYPE, setToast } from "@plane/ui";
// components
import {
  InboxIssueTitle,
  InboxIssueDescription,
  InboxIssueProperties,
} from "@/components/inbox/modals/create-edit-modal";
// constants
import { ISSUE_UPDATED } from "@/constants/event-tracker";
// helpers
import { renderFormattedPayloadDate } from "@/helpers/date-time.helper";
// hooks
import { useEventTracker, useInboxIssues, useWorkspace } from "@/hooks/store";

type TInboxIssueEditRoot = {
  workspaceSlug: string;
  projectId: string;
  issueId: string;
  issue: Partial<TIssue>;
  handleModalClose: () => void;
  onSubmit?: () => void;
};

export const InboxIssueEditRoot: FC<TInboxIssueEditRoot> = observer((props) => {
  const { workspaceSlug, projectId, issueId, issue, handleModalClose, onSubmit } = props;
  const router = useRouter();
  // refs
  const descriptionEditorRef = useRef<EditorRefApi>(null);
  // hooks
  const { captureIssueEvent } = useEventTracker();
  const { updateProjectIssue } = useInboxIssues(issueId);
  const { getWorkspaceBySlug } = useWorkspace();
  const workspaceId = getWorkspaceBySlug(workspaceSlug)?.id;
  // states
  const [formSubmitting, setFormSubmitting] = useState(false);
  const [formData, setFormData] = useState<Partial<TIssue> | undefined>(undefined);
  const handleFormData = useCallback(
    <T extends keyof Partial<TIssue>>(issueKey: T, issueValue: Partial<TIssue>[T]) => {
      setFormData({
        ...formData,
        [issueKey]: issueValue,
      });
    },
    [formData]
  );

  useEffect(() => {
    if (formData?.id != issue?.id)
      setFormData({
        id: issue?.id || undefined,
        name: issue?.name ?? "",
        description_html: issue?.description_html ?? "<p></p>",
        priority: issue?.priority ?? "none",
        state_id: issue?.state_id ?? "",
        label_ids: issue?.label_ids ?? [],
        assignee_ids: issue?.assignee_ids ?? [],
        start_date: renderFormattedPayloadDate(issue?.start_date) ?? "",
        target_date: renderFormattedPayloadDate(issue?.target_date) ?? "",
      });
  }, [issue, formData]);

  const handleFormSubmit = async () => {
    const payload: Partial<TIssue> = {
      name: formData?.name || "",
      description_html: formData?.description_html || "<p></p>",
      priority: formData?.priority || "none",
      state_id: formData?.state_id || "",
      label_ids: formData?.label_ids || [],
      assignee_ids: formData?.assignee_ids || [],
      start_date: formData?.start_date || undefined,
      target_date: formData?.target_date || undefined,
      cycle_id: formData?.cycle_id || "",
      module_ids: formData?.module_ids || [],
      estimate_point: formData?.estimate_point || undefined,
      parent_id: formData?.parent_id || null,
    };
    setFormSubmitting(true);

    onSubmit && (await onSubmit());
    await updateProjectIssue(payload)
      .then(async () => {
        captureIssueEvent({
          eventName: ISSUE_UPDATED,
          payload: {
            ...formData,
            state: "SUCCESS",
            element: "Inbox page",
          },
          routePath: router.pathname,
        });
        setToast({
          type: TOAST_TYPE.SUCCESS,
          title: `${TOAST_TYPE.SUCCESS}!`,
          message: "Issue created successfully.",
        });
        descriptionEditorRef?.current?.clearEditor();
        handleModalClose();
      })
      .catch((error) => {
        console.error(error);
        captureIssueEvent({
          eventName: ISSUE_UPDATED,
          payload: {
            ...formData,
            state: "FAILED",
            element: "Inbox page",
          },
          routePath: router.pathname,
        });
        setToast({
          type: TOAST_TYPE.ERROR,
          title: `${TOAST_TYPE.ERROR}!`,
          message: "Some error occurred. Please try again.",
        });
      });
    setFormSubmitting(false);
  };

  const isTitleLengthMoreThan255Character = formData?.name ? formData.name.length > 255 : false;

  if (!workspaceSlug || !projectId || !workspaceId || !formData) return <></>;
  return (
    <div className="relative space-y-4">
      <InboxIssueTitle
        data={formData}
        handleData={handleFormData}
        isTitleLengthMoreThan255Character={isTitleLengthMoreThan255Character}
      />
      <InboxIssueDescription
        workspaceSlug={workspaceSlug}
        projectId={projectId}
        workspaceId={workspaceId}
        data={formData}
        handleData={handleFormData}
        editorRef={descriptionEditorRef}
      />
      <InboxIssueProperties projectId={projectId} data={formData} handleData={handleFormData} isVisible />
      <div className="relative flex justify-end items-center gap-3">
        <Button variant="neutral-primary" size="sm" type="button" onClick={handleModalClose}>
          Cancel
        </Button>
        <Button
          variant="primary"
          size="sm"
          type="button"
          loading={formSubmitting}
          disabled={isTitleLengthMoreThan255Character}
          onClick={handleFormSubmit}
        >
          {formSubmitting ? "Adding..." : "Add to project"}
        </Button>
      </div>
    </div>
  );
});