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

import { useEffect, useState } from "react";
import { observer } from "mobx-react";
import useSWR from "swr";
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import type { TNameDescriptionLoader } from "@plane/types";
import { useProjectExternalContours } from "@/hooks/store/use-project-external-contours";
import { useUser, useUserPermissions } from "@/hooks/store/user";
import { useAppRouter } from "@/hooks/use-app-router";
import { ExternalContoursPeekShell } from "./peek-shell";
import { ExternalContoursIssueMainContent } from "./issue-root";

type Props = {
  workspaceSlug: string;
  projectId: string;
  inboxIssueId: string;
  embedIssue?: boolean;
  embedRemoveCurrentNotification?: () => void;
};

export const ExternalContoursContentRoot = observer(function ExternalContoursContentRoot(props: Props) {
  const {
    workspaceSlug,
    projectId,
    inboxIssueId,
    embedIssue = false,
    embedRemoveCurrentNotification,
  } = props;
  const router = useAppRouter();
  const [isSubmitting, setIsSubmitting] = useState<TNameDescriptionLoader>("saved");
  const [isDetailResolved, setIsDetailResolved] = useState(false);
  const { data: currentUser } = useUser();
  const { fetchRequestById, getRequestById } = useProjectExternalContours();
  const contourRequest = getRequestById(inboxIssueId);
  const issue = contourRequest?.issue;
  const targetProjectId = issue?.project_id || projectId;
  const { allowPermissions, getProjectRoleByWorkspaceSlugAndProjectId } = useUserPermissions();
  const hasDirectTargetAccess = !!(
    targetProjectId && getProjectRoleByWorkspaceSlugAndProjectId(workspaceSlug, targetProjectId) !== undefined
  );

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

  useSWR(
    workspaceSlug && projectId && inboxIssueId
      ? `PROJECT_EXTERNAL_CONTOUR_DETAIL_${workspaceSlug}_${projectId}_${inboxIssueId}`
      : null,
    workspaceSlug && projectId && inboxIssueId
      ? async () => {
          const request = await fetchRequestById(workspaceSlug, projectId, inboxIssueId);
          setIsDetailResolved(true);
          return request;
        }
      : null,
    {
      revalidateOnFocus: !hasDirectTargetAccess,
      revalidateIfStale: !hasDirectTargetAccess,
      refreshInterval: hasDirectTargetAccess ? 0 : 15000,
    }
  );

  const isEditable =
    hasDirectTargetAccess &&
    (allowPermissions([EUserPermissions.ADMIN], EUserPermissionsLevel.PROJECT, workspaceSlug, targetProjectId) ||
      issue?.created_by === currentUser?.id);
  const sourceRequesterId = contourRequest?.requested_by_id || issue?.created_by || contourRequest?.created_by;
  const isSourceEditable =
    !hasDirectTargetAccess &&
    contourRequest?.status === "open" &&
    !!currentUser?.id &&
    String(sourceRequesterId) === String(currentUser.id);

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

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

  return (
    <ExternalContoursPeekShell
      workspaceSlug={workspaceSlug}
      projectId={projectId}
      contourRequest={contourRequest}
      hasDirectTargetAccess={hasDirectTargetAccess}
      isSubmitting={isSubmitting}
      embedIssue={embedIssue}
      embedRemoveCurrentNotification={embedRemoveCurrentNotification}
      onClose={() => router.replace(`/${workspaceSlug}/projects/${projectId}/external-contours`)}
    >
      <ExternalContoursIssueMainContent
        workspaceSlug={workspaceSlug}
        sourceProjectId={projectId}
        contourRequest={contourRequest}
        hasDirectTargetAccess={hasDirectTargetAccess}
        isEditable={!!isEditable && !readOnly}
        isSourceEditable={isSourceEditable}
        isSubmitting={isSubmitting}
        setIsSubmitting={setIsSubmitting}
      />
    </ExternalContoursPeekShell>
  );
});
