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

import { useEffect, useMemo } from "react";
import { observer } from "mobx-react";
import useSWR from "swr";
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import type { TIssue } from "@plane/types";
// hooks
import { useIssueDetail } from "@/hooks/store/use-issue-detail";
import { useProjectInbox } from "@/hooks/store/use-project-inbox";
import { useUser, useUserPermissions } from "@/hooks/store/user";
import { useAppRouter } from "@/hooks/use-app-router";
import { IssueView } from "@/components/issues/peek-overview/view";
import type { TIssueOperations } from "@/components/issues/issue-detail";
import { EInboxIssueStatus } from "@plane/types";
// local imports
import { InboxIssueActionsHeader } from "./inbox-issue-header";
import { InboxIssueMainContent } from "./issue-root";

type TInboxContentRoot = {
  workspaceSlug: string;
  projectId: string;
  inboxIssueId: string;
  isMobileSidebar: boolean;
  setIsMobileSidebar: (value: boolean) => void;
  isNotificationEmbed?: boolean;
  embedRemoveCurrentNotification?: () => void;
};

export const InboxContentRoot = observer(function InboxContentRoot(props: TInboxContentRoot) {
  const {
    workspaceSlug,
    projectId,
    inboxIssueId,
    isMobileSidebar,
    setIsMobileSidebar,
    isNotificationEmbed = false,
    embedRemoveCurrentNotification,
  } = props;
  /// router
  const router = useAppRouter();
  const { t } = useTranslation();
  // hooks
  const { data: currentUser } = useUser();
  const { fetchInboxIssueById, getIssueInboxByIssueId, getIsIssueAvailable } = useProjectInbox();
  const { removeIssue, archiveIssue } = useIssueDetail();
  const inboxIssue = getIssueInboxByIssueId(inboxIssueId);
  const { allowPermissions, getProjectRoleByWorkspaceSlugAndProjectId } = useUserPermissions();

  // derived values
  const isIssueAvailable = getIsIssueAvailable(inboxIssueId?.toString() || "");

  useEffect(() => {
    if (!isIssueAvailable && inboxIssueId && !isNotificationEmbed) {
      router.replace(`/${workspaceSlug}/projects/${projectId}/intake`);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isIssueAvailable, isNotificationEmbed]);

  useSWR(
    workspaceSlug && projectId && inboxIssueId
      ? `PROJECT_INBOX_ISSUE_DETAIL_${workspaceSlug}_${projectId}_${inboxIssueId}`
      : null,
    workspaceSlug && projectId && inboxIssueId
      ? () => fetchInboxIssueById(workspaceSlug, projectId, inboxIssueId)
      : null,
    {
      revalidateOnFocus: false,
      revalidateIfStale: false,
    }
  );

  const isEditable =
    allowPermissions([EUserPermissions.ADMIN], EUserPermissionsLevel.PROJECT, workspaceSlug, projectId) ||
    inboxIssue?.issue.created_by === currentUser?.id;

  const isGuest = getProjectRoleByWorkspaceSlugAndProjectId(workspaceSlug, projectId) === EUserPermissions.GUEST;
  const isOwner = inboxIssue?.issue.created_by === currentUser?.id;
  const readOnly = !isOwner && isGuest;

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

  const isIssueDisabled = [-1, 1, 2].includes(inboxIssue.status);
  const canEditIssue = isEditable && !isIssueDisabled && !readOnly;

  const issueOperations: TIssueOperations = useMemo(
    () => ({
      fetch: async () => {
        return;
      },
      remove: async (_workspaceSlug: string, _projectId: string, _issueId: string) => {
        try {
          await removeIssue(workspaceSlug, projectId, _issueId);
          setToast({
            title: t("success"),
            type: TOAST_TYPE.SUCCESS,
            message: t("inbox_issue.modals.delete.success"),
          });
        } catch (error) {
          console.error("Error in deleting work item:", error);
          setToast({
            title: t("error"),
            type: TOAST_TYPE.ERROR,
            message: t("something_went_wrong_please_try_again"),
          });
        }
      },
      update: async (_workspaceSlug: string, _projectId: string, _issueId: string, data: Partial<TIssue>) => {
        try {
          if (inboxIssue.status === EInboxIssueStatus.ACCEPTED) {
            await inboxIssue.updateProjectIssue(data);
          } else {
            await inboxIssue.updateIssue(data);
          }
        } catch (_error) {
          setToast({
            title: t("error"),
            type: TOAST_TYPE.ERROR,
            message: t("issue_could_not_be_updated"),
          });
        }
      },
      archive: async (_workspaceSlug: string, _projectId: string, _issueId: string) => {
        try {
          await archiveIssue(workspaceSlug, projectId, _issueId);
        } catch (error) {
          console.error("Error in archiving issue:", error);
        }
      },
    }),
    [archiveIssue, inboxIssue, projectId, removeIssue, t, workspaceSlug]
  );

  const handleCloseIssueView = () => {
    if (isNotificationEmbed) {
      embedRemoveCurrentNotification?.();
      return;
    }

    router.push(`/${workspaceSlug}/projects/${projectId}/intake`);
  };

  return (
    <div className="relative flex h-full w-full min-h-0 justify-end overflow-hidden">
      <IssueView
        workspaceSlug={workspaceSlug}
        projectId={projectId}
        issueId={inboxIssueId}
        is_archived={!!inboxIssue.issue.archived_at}
        disabled={!canEditIssue}
        embedIssue
        interactiveEmbeddedLayout
        issueOperations={issueOperations}
        renderHeader={({ peekMode, setPeekMode, removeRoutePeekId, isSubmitting }) => (
          <InboxIssueActionsHeader
            setIsMobileSidebar={setIsMobileSidebar}
            isMobileSidebar={isMobileSidebar}
            workspaceSlug={workspaceSlug}
            projectId={projectId}
            inboxIssue={inboxIssue}
            isSubmitting={isSubmitting}
            isNotificationEmbed={isNotificationEmbed || false}
            embedRemoveCurrentNotification={embedRemoveCurrentNotification}
            peekMode={peekMode}
            setPeekMode={setPeekMode}
            removeRoutePeekId={removeRoutePeekId ?? handleCloseIssueView}
            disabled={!canEditIssue}
          />
        )}
        renderContent={({ peekMode, isSubmitting, setIsSubmitting }) => (
          <InboxIssueMainContent
            workspaceSlug={workspaceSlug}
            projectId={projectId}
            inboxIssue={inboxIssue}
            isEditable={canEditIssue}
            isSubmitting={isSubmitting}
            setIsSubmitting={setIsSubmitting}
            issueOperations={issueOperations}
            peekMode={peekMode}
          />
        )}
        embedRemoveCurrentNotification={handleCloseIssueView}
      />
    </div>
  );
});
