/**
 * Copyright (c) 2023-present Plane Software, Inc. and contributors
 * SPDX-License-Identifier: AGPL-3.0-only
 * See the LICENSE file for details.
 */

import type { Dispatch, SetStateAction } from "react";
import { useEffect, useRef } from "react";
import { observer } from "mobx-react";
import { useTranslation } from "@plane/i18n";
// plane imports
import type { EditorRefApi } from "@plane/editor";
import type { TNameDescriptionLoader } from "@plane/types";
import { EFileAssetType, EInboxIssueSource, EInboxIssueStatus } from "@plane/types";
import { getTextContent } from "@plane/utils";
// components
import { DescriptionVersionsRoot } from "@/components/core/description-versions";
import { DescriptionInput } from "@/components/editor/rich-text/description-input";
import { DescriptionInputLoader } from "@/components/editor/rich-text/description-input/loader";
import { IssueAttachmentRoot } from "@/components/issues/attachment";
import type { TIssueOperations } from "@/components/issues/issue-detail";
import { IssueActivity } from "@/components/issues/issue-detail/issue-activity";
import { IssueReaction } from "@/components/issues/issue-detail/reactions";
import type { TPeekModes } from "@/components/issues/peek-overview/header";
import { IssueTitleInput } from "@/components/issues/title-input";
// hooks
import { useIssueDetail } from "@/hooks/store/use-issue-detail";
import { useMember } from "@/hooks/store/use-member";
import { useProject } from "@/hooks/store/use-project";
import { useProjectInbox } from "@/hooks/store/use-project-inbox";
import { useUser } from "@/hooks/store/user";
import useReloadConfirmations from "@/hooks/use-reload-confirmation";
// store types
import { DeDupeIssuePopoverRoot } from "@/plane-web/components/de-dupe/duplicate-popover";
import { useDebouncedDuplicateIssues } from "@/plane-web/hooks/use-debounced-duplicate-issues";
// services
import { IntakeWorkItemVersionService } from "@/services/inbox";
// stores
import type { IInboxIssueStore } from "@/store/inbox/inbox-issue.store";
// local imports
import { InboxIssueContentProperties } from "./issue-properties";
// services init
const intakeWorkItemVersionService = new IntakeWorkItemVersionService();

type Props = {
  workspaceSlug: string;
  projectId: string;
  inboxIssue: IInboxIssueStore;
  isEditable: boolean;
  isSubmitting: TNameDescriptionLoader;
  setIsSubmitting: Dispatch<SetStateAction<TNameDescriptionLoader>>;
  issueOperations: TIssueOperations;
  peekMode: TPeekModes;
};

export const InboxIssueMainContent = observer(function InboxIssueMainContent(props: Props) {
  const { workspaceSlug, projectId, inboxIssue, isEditable, isSubmitting, setIsSubmitting, issueOperations, peekMode } =
    props;
  const { t } = useTranslation();
  // refs
  const editorRef = useRef<EditorRefApi>(null);
  // store hooks
  const { data: currentUser } = useUser();
  const { getUserDetails } = useMember();
  const { loader } = useProjectInbox();
  const { getProjectById } = useProject();
  const {
    issue: { getIssueById },
  } = useIssueDetail();
  // reload confirmation
  const { setShowAlert } = useReloadConfirmations(isSubmitting === "submitting");

  useEffect(() => {
    if (isSubmitting === "submitted") {
      setShowAlert(false);
      setTimeout(async () => {
        setIsSubmitting("saved");
      }, 3000);
    } else if (isSubmitting === "submitting") {
      setShowAlert(true);
    }
  }, [isSubmitting, setShowAlert, setIsSubmitting]);

  // derived values
  const issue = (inboxIssue.issue.id ? getIssueById(inboxIssue.issue.id) : undefined) ?? inboxIssue.issue;
  const projectDetails = issue?.project_id ? getProjectById(issue?.project_id) : undefined;
  const isIntakeAccepted = inboxIssue.status === EInboxIssueStatus.ACCEPTED;

  // debounced duplicate issues swr
  const { duplicateIssues } = useDebouncedDuplicateIssues(
    workspaceSlug,
    projectDetails?.workspace.toString(),
    projectId,
    {
      name: issue?.name,
      description_html: getTextContent(issue?.description_html),
      issueId: issue?.id,
    }
  );

  if (!issue) return <></>;

  if (!issue?.project_id || !issue?.id) return <></>;

  const detailsContent = (
    <div className="space-y-2">
      <IssueTitleInput
        workspaceSlug={workspaceSlug}
        projectId={issue.project_id}
        issueId={issue.id}
        isSubmitting={isSubmitting}
        setIsSubmitting={(value) => setIsSubmitting(value)}
        issueOperations={issueOperations}
        disabled={!isEditable}
        value={issue.name}
        containerClassName="-ml-3"
      />

      {loader === "issue-loading" || issue.description_html === undefined ? (
        <DescriptionInputLoader />
      ) : (
        <DescriptionInput
          issueSequenceId={issue.sequence_id}
          containerClassName="-ml-3 border-none"
          disabled={!isEditable}
          editorRef={editorRef}
          entityId={issue.id}
          fileAssetType={EFileAssetType.ISSUE_DESCRIPTION}
          initialValue={issue.description_html ?? "<p></p>"}
          key={issue.id}
          onSubmit={async (value, isMigrationUpdate) => {
            if (!issue.id || !issue.project_id) return;
            await issueOperations.update(workspaceSlug, issue.project_id, issue.id, {
              description_html: value.description_html,
              ...(isMigrationUpdate ? { skip_activity: "true" } : {}),
            });
          }}
          projectId={issue.project_id}
          setIsSubmitting={(value) => setIsSubmitting(value)}
          workspaceSlug={workspaceSlug}
        />
      )}

      <div className="flex items-center justify-between gap-2">
        {currentUser && (
          <IssueReaction
            workspaceSlug={workspaceSlug}
            projectId={projectId}
            issueId={issue.id}
            currentUser={currentUser}
          />
        )}
        {isEditable && (
          <DescriptionVersionsRoot
            className="flex-shrink-0"
            entityInformation={{
              createdAt: issue.created_at ? new Date(issue.created_at) : new Date(),
              createdByDisplayName:
                inboxIssue.source === EInboxIssueSource.FORMS
                  ? t("inbox_issue.source.form_user")
                  : (getUserDetails(issue.created_by ?? "")?.display_name ?? ""),
              id: issue.id,
              isRestoreDisabled: !isEditable,
            }}
            fetchHandlers={{
              listDescriptionVersions: (issueId) =>
                intakeWorkItemVersionService.listDescriptionVersions(workspaceSlug, projectId, issueId),
              retrieveDescriptionVersion: (issueId, versionId) =>
                intakeWorkItemVersionService.retrieveDescriptionVersion(workspaceSlug, projectId, issueId, versionId),
            }}
            handleRestore={(descriptionHTML) => editorRef.current?.setEditorValue(descriptionHTML, true)}
            projectId={projectId}
            workspaceSlug={workspaceSlug}
          />
        )}
      </div>
    </div>
  );

  const attachmentContent = (
    <div className="py-2">
      <IssueAttachmentRoot workspaceSlug={workspaceSlug} projectId={projectId} issueId={issue.id} disabled={!isEditable} />
    </div>
  );

  const propertiesContent = (
    <InboxIssueContentProperties
      workspaceSlug={workspaceSlug}
      projectId={projectId}
      issue={issue}
      issueOperations={issueOperations}
      isEditable={isEditable}
      duplicateIssueDetails={inboxIssue?.duplicate_issue_detail}
      isIntakeAccepted={isIntakeAccepted}
    />
  );

  const activityContent = (
    <IssueActivity workspaceSlug={workspaceSlug} projectId={projectId} issueId={issue.id} isIntakeIssue compactComposer />
  );

  if (peekMode === "full-screen") {
    return (
      <div className="vertical-scrollbar flex h-full w-full overflow-auto">
        <div className="relative h-full w-full space-y-6 overflow-auto p-4 py-5">
          {duplicateIssues.length > 0 && (
            <DeDupeIssuePopoverRoot
              workspaceSlug={workspaceSlug}
              projectId={issue.project_id}
              rootIssueId={issue.id}
              issues={duplicateIssues}
              issueOperations={issueOperations}
              isIntakeIssue
            />
          )}

          <div className="space-y-3">
            {detailsContent}
            {attachmentContent}
            {activityContent}
          </div>
        </div>

        <div className={`vertical-scrollbar scrollbar-sm h-full !w-[400px] flex-shrink-0 overflow-hidden border-l border-subtle p-4 py-5 ${!isEditable ? "opacity-60" : ""}`}>
          {propertiesContent}
        </div>
      </div>
    );
  }

  return (
    <div className="relative flex flex-col gap-4 space-y-3 px-8 py-6">
      {duplicateIssues.length > 0 && (
        <DeDupeIssuePopoverRoot
          workspaceSlug={workspaceSlug}
          projectId={issue.project_id}
          rootIssueId={issue.id}
          issues={duplicateIssues}
          issueOperations={issueOperations}
          isIntakeIssue
        />
      )}

      {detailsContent}
      {attachmentContent}
      {propertiesContent}
      {activityContent}
    </div>
  );
});
