

import { Clock, FileStack, MoreHorizontal, MoveRight } from "lucide-react";
import { observer } from "mobx-react";
import { useCallback, useEffect, useState } from "react";
// buzzwareTech imports
import { EUserPermissions, EUserPermissionsLevel } from "@buzzwaretech/constants";
import { useTranslation } from "@buzzwaretech/i18n";
import { Button } from "@buzzwaretech/propel/button";
import { IconButton, getIconButtonStyling } from "@buzzwaretech/propel/icon-button";
import {
    CheckCircleFilledIcon,
    ChevronDownIcon,
    ChevronUpIcon,
    CloseCircleFilledIcon,
    CopyIcon,
    LinkIcon,
    NewTabIcon,
    TrashIcon,
} from "@buzzwaretech/propel/icons";
import { TOAST_TYPE, setToast } from "@buzzwaretech/propel/toast";
import type { TNameDescriptionLoader } from "@buzzwaretech/types";
import { EInboxIssueStatus } from "@buzzwaretech/types";
import { ControlLink, CustomMenu, Row } from "@buzzwaretech/ui";
import {
    copyUrlToClipboard,
    findHowManyDaysLeft,
    generateWorkItemLink,
} from "@buzzwaretech/utils";
// components
import { CreateUpdateIssueModal } from "@/components/issues/issue-modal/modal";
import { NameDescriptionUpdateStatus } from "@/components/issues/issue-update-status";
// hooks
import { useProject } from "@/hooks/store/use-project";
import { useProjectInbox } from "@/hooks/store/use-project-inbox";
import { useUser, useUserPermissions } from "@/hooks/store/user";
import { useAppRouter } from "@/hooks/use-app-router";
// store
import type { IInboxIssueStore } from "@/store/inbox/inbox-issue.store";
// local imports
import { InboxIssueStatus } from "../inbox-issue-status";
import { DeclineIssueModal } from "../modals/decline-issue-modal";
import { DeleteInboxIssueModal } from "../modals/delete-issue-modal";
import { SelectDuplicateInboxIssueModal } from "../modals/select-duplicate";
import { InboxIssueSnoozeModal } from "../modals/snooze-issue-modal";
import { InboxIssueActionsMobileHeader } from "./inbox-issue-mobile-header";

type TInboxIssueActionsHeader = {
  workspaceSlug: string;
  projectId: string;
  inboxIssue: IInboxIssueStore | undefined;
  isSubmitting: TNameDescriptionLoader;
  isMobileSidebar: boolean;
  setIsMobileSidebar: (value: boolean) => void;
  isNotificationEmbed: boolean;
  embedRemoveCurrentNotification?: () => void;
};

export const InboxIssueActionsHeader = observer(
  function InboxIssueActionsHeader(props: TInboxIssueActionsHeader) {
    const {
      workspaceSlug,
      projectId,
      inboxIssue,
      isSubmitting,
      isMobileSidebar,
      setIsMobileSidebar,
      isNotificationEmbed = false,
      embedRemoveCurrentNotification,
    } = props;
    // states
    const [isSnoozeDateModalOpen, setIsSnoozeDateModalOpen] = useState(false);
    const [selectDuplicateIssue, setSelectDuplicateIssue] = useState(false);
    const [acceptIssueModal, setAcceptIssueModal] = useState(false);
    const [declineIssueModal, setDeclineIssueModal] = useState(false);
    const [deleteIssueModal, setDeleteIssueModal] = useState(false);
    // store
    const { currentTab, deleteInboxIssue, filteredInboxIssueIds } =
      useProjectInbox();
    const { data: currentUser } = useUser();
    const { allowPermissions } = useUserPermissions();
    const { getPartialProjectById } = useProject();
    const currentProjectDetails = getPartialProjectById(projectId);
    const { t } = useTranslation();

    const router = useAppRouter();
    const { getProjectById } = useProject();

    const issue = inboxIssue?.issue;
    // derived values
    const isAllowed = allowPermissions(
      [EUserPermissions.ADMIN, EUserPermissions.MEMBER],
      EUserPermissionsLevel.PROJECT,
      workspaceSlug,
      projectId,
    );
    const canMarkAsDuplicate =
      isAllowed && (inboxIssue?.status === 0 || inboxIssue?.status === -2);
    const canMarkAsAccepted =
      isAllowed && (inboxIssue?.status === 0 || inboxIssue?.status === -2);
    const canMarkAsDeclined =
      isAllowed && (inboxIssue?.status === 0 || inboxIssue?.status === -2);
    // can delete only if admin or is creator of the issue
    const canDelete =
      allowPermissions(
        [EUserPermissions.ADMIN],
        EUserPermissionsLevel.PROJECT,
        workspaceSlug,
        projectId,
      ) || issue?.created_by === currentUser?.id;
    const isProjectAdmin = allowPermissions(
      [EUserPermissions.ADMIN],
      EUserPermissionsLevel.PROJECT,
      workspaceSlug,
      projectId,
    );
    const isAcceptedOrDeclined = inboxIssue?.status
      ? [-1, 1, 2].includes(inboxIssue.status)
      : undefined;
    // days left for snooze
    const numberOfDaysLeft = findHowManyDaysLeft(inboxIssue?.snoozed_till);

    const currentInboxIssueId = inboxIssue?.issue?.id;

    const redirectIssue = (): string | undefined => {
      let nextOrPreviousIssueId: string | undefined = undefined;
      const currentIssueIndex = filteredInboxIssueIds.findIndex(
        (id) => id === currentInboxIssueId,
      );
      if (filteredInboxIssueIds[currentIssueIndex + 1])
        nextOrPreviousIssueId = filteredInboxIssueIds[currentIssueIndex + 1];
      else if (filteredInboxIssueIds[currentIssueIndex - 1])
        nextOrPreviousIssueId = filteredInboxIssueIds[currentIssueIndex - 1];
      else nextOrPreviousIssueId = undefined;
      return nextOrPreviousIssueId;
    };

    const handleRedirection = (nextOrPreviousIssueId: string | undefined) => {
      if (!isNotificationEmbed) {
        if (nextOrPreviousIssueId)
          router.push(
            `/${workspaceSlug}/projects/${projectId}/intake?currentTab=${currentTab}&inboxIssueId=${nextOrPreviousIssueId}`,
          );
        else
          router.push(
            `/${workspaceSlug}/projects/${projectId}/intake?currentTab=${currentTab}`,
          );
      }
    };

    const handleInboxIssueAccept = async () => {
      const nextOrPreviousIssueId = redirectIssue();
      await inboxIssue?.updateInboxIssueStatus(EInboxIssueStatus.ACCEPTED);
      setAcceptIssueModal(false);
      handleRedirection(nextOrPreviousIssueId);
    };

    const handleInboxIssueDecline = async () => {
      const nextOrPreviousIssueId = redirectIssue();
      await inboxIssue?.updateInboxIssueStatus(EInboxIssueStatus.DECLINED);
      setDeclineIssueModal(false);
      handleRedirection(nextOrPreviousIssueId);
    };

    const handleInboxIssueSnooze = async (date: Date) => {
      const nextOrPreviousIssueId = redirectIssue();
      await inboxIssue?.updateInboxIssueSnoozeTill(date);
      setIsSnoozeDateModalOpen(false);
      handleRedirection(nextOrPreviousIssueId);
    };

    const handleInboxIssueDuplicate = async (issueId: string) => {
      await inboxIssue?.updateInboxIssueDuplicateTo(issueId);
    };

    const handleInboxIssueDelete = async () => {
      if (!inboxIssue || !currentInboxIssueId) return;
      await deleteInboxIssue(
        workspaceSlug,
        projectId,
        currentInboxIssueId,
      ).then(() => {
        if (!isNotificationEmbed)
          router.push(`/${workspaceSlug}/projects/${projectId}/intake`);
      });
    };

    const handleIssueSnoozeAction = async () => {
      if (
        inboxIssue?.snoozed_till &&
        numberOfDaysLeft &&
        numberOfDaysLeft > 0
      ) {
        const nextOrPreviousIssueId = redirectIssue();
        await inboxIssue?.updateInboxIssueSnoozeTill(undefined);
        handleRedirection(nextOrPreviousIssueId);
      } else {
        setIsSnoozeDateModalOpen(true);
      }
    };

    const handleCopyIssueLink = (path: string) =>
      copyUrlToClipboard(path).then(() =>
        setToast({
          type: TOAST_TYPE.SUCCESS,
          title: t("common.link_copied"),
          message: t("common.copied_to_clipboard"),
        }),
      );

    const currentIssueIndex =
      filteredInboxIssueIds.findIndex(
        (issueId) => issueId === currentInboxIssueId,
      ) ?? 0;

    const handleInboxIssueNavigation = useCallback(
      (direction: "next" | "prev") => {
        if (!filteredInboxIssueIds || !currentInboxIssueId) return;
        const activeElement = document.activeElement as HTMLElement;
        if (
          activeElement &&
          (activeElement.classList.contains("tiptap") ||
            activeElement.id === "title-input")
        )
          return;
        const nextIssueIndex =
          direction === "next"
            ? (currentIssueIndex + 1) % filteredInboxIssueIds.length
            : (currentIssueIndex - 1 + filteredInboxIssueIds.length) %
              filteredInboxIssueIds.length;
        const nextIssueId = filteredInboxIssueIds[nextIssueIndex];
        if (!nextIssueId) return;
        router.push(
          `/${workspaceSlug}/projects/${projectId}/intake?inboxIssueId=${nextIssueId}`,
        );
      },
      [
        currentInboxIssueId,
        currentIssueIndex,
        filteredInboxIssueIds,
        projectId,
        router,
        workspaceSlug,
      ],
    );

    const onKeyDown = useCallback(
      (e: KeyboardEvent) => {
        if (e.key === "ArrowUp") {
          handleInboxIssueNavigation("prev");
        } else if (e.key === "ArrowDown") {
          handleInboxIssueNavigation("next");
        }
      },
      [handleInboxIssueNavigation],
    );

    const handleActionWithPermission = (
      isAdmin: boolean,
      action: () => void,
      errorMessage: string,
    ) => {
      if (isAdmin) action();
      else {
        setToast({
          type: TOAST_TYPE.ERROR,
          title: "Permission denied",
          message: errorMessage,
        });
      }
    };

    useEffect(() => {
      if (isSubmitting === "submitting") return;
      if (!isNotificationEmbed) document.addEventListener("keydown", onKeyDown);
      return () => {
        if (!isNotificationEmbed)
          document.removeEventListener("keydown", onKeyDown);
      };
    }, [onKeyDown, isNotificationEmbed, isSubmitting]);

    if (!inboxIssue) return null;

    const workItemLink = generateWorkItemLink({
      workspaceSlug: workspaceSlug?.toString(),
      projectId: issue?.project_id,
      issueId: currentInboxIssueId,
      projectIdentifier: currentProjectDetails?.identifier,
      sequenceId: issue?.sequence_id,
    });

    return (
      <>
        <>
          <SelectDuplicateInboxIssueModal
            isOpen={selectDuplicateIssue}
            onClose={() => setSelectDuplicateIssue(false)}
            value={inboxIssue?.duplicate_to}
            onSubmit={handleInboxIssueDuplicate}
          />
          <CreateUpdateIssueModal
            data={inboxIssue?.issue}
            isOpen={acceptIssueModal}
            onClose={() => setAcceptIssueModal(false)}
            beforeFormSubmit={handleInboxIssueAccept}
            withDraftIssueWrapper={false}
            fetchIssueDetails={false}
            showActionItemsOnUpdate
            modalTitle={t("inbox_issue.actions.move", {
              value: `${currentProjectDetails?.identifier}-${issue?.sequence_id}`,
            })}
            primaryButtonText={{
              default: t("add_to_project"),
              loading: t("adding"),
            }}
          />
          <DeclineIssueModal
            data={inboxIssue?.issue || {}}
            isOpen={declineIssueModal}
            onClose={() => setDeclineIssueModal(false)}
            onSubmit={handleInboxIssueDecline}
          />
          <DeleteInboxIssueModal
            data={inboxIssue?.issue}
            isOpen={deleteIssueModal}
            onClose={() => setDeleteIssueModal(false)}
            onSubmit={handleInboxIssueDelete}
          />
          <InboxIssueSnoozeModal
            isOpen={isSnoozeDateModalOpen}
            handleClose={() => setIsSnoozeDateModalOpen(false)}
            value={inboxIssue?.snoozed_till}
            onConfirm={handleInboxIssueSnooze}
          />
        </>

        <Row className="relative z-15 hidden h-full w-full items-center justify-between gap-2 border-b border-subtle bg-surface-1 lg:flex">
          <div className="flex items-center gap-4">
            {isNotificationEmbed && (
              <button onClick={embedRemoveCurrentNotification}>
                <MoveRight className="h-4 w-4 text-tertiary hover:text-secondary" />
              </button>
            )}
            {issue?.project_id && issue.sequence_id && (
              <h3 className="flex-shrink-0 text-14 font-medium text-tertiary">
                {getProjectById(issue.project_id)?.identifier}-
                {issue.sequence_id}
              </h3>
            )}
            <InboxIssueStatus inboxIssue={inboxIssue} iconSize={12} />
            <div className="flex w-full items-center justify-end">
              <NameDescriptionUpdateStatus isSubmitting={isSubmitting} />
            </div>
          </div>

          <div className="flex items-center gap-2">
            {!isNotificationEmbed && (
              <div className="flex items-center gap-x-2">
                <IconButton
                  variant="secondary"
                  size="lg"
                  icon={ChevronUpIcon}
                  aria-label="Previous work item"
                  onClick={() => handleInboxIssueNavigation("prev")}
                />
                <IconButton
                  variant="secondary"
                  size="lg"
                  icon={ChevronDownIcon}
                  aria-label="Next work item"
                  onClick={() => handleInboxIssueNavigation("next")}
                />
              </div>
            )}

            <div className="flex flex-wrap items-center gap-2">
              {canMarkAsAccepted && (
                <Button
                  variant="secondary"
                  size="lg"
                  onClick={() =>
                    handleActionWithPermission(
                      isProjectAdmin,
                      () => setAcceptIssueModal(true),
                      t("inbox_issue.errors.accept_permission"),
                    )
                  }
                >
                  <CheckCircleFilledIcon className="size-4 shrink-0 text-success-secondary" />
                  {t("inbox_issue.actions.accept")}
                </Button>
              )}

              {canMarkAsDeclined && (
                <Button
                  variant="secondary"
                  size="lg"
                  onClick={() =>
                    handleActionWithPermission(
                      isProjectAdmin,
                      () => setDeclineIssueModal(true),
                      t("inbox_issue.errors.decline_permission"),
                    )
                  }
                >
                  <CloseCircleFilledIcon className="size-4 shrink-0 text-danger-secondary" />
                  {t("inbox_issue.actions.decline")}
                </Button>
              )}

              {isAcceptedOrDeclined ? (
                <div className="flex items-center gap-2">
                  <Button
                    variant="secondary"
                    size="lg"
                    prependIcon={<LinkIcon className="h-2.5 w-2.5" />}
                    onClick={() => handleCopyIssueLink(workItemLink)}
                  >
                    {t("inbox_issue.actions.copy")}
                  </Button>
                  <ControlLink
                    href={workItemLink}
                    onClick={() => router.push(workItemLink)}
                    target="_self"
                  >
                    <Button
                      variant="secondary"
                      size="lg"
                      prependIcon={<NewTabIcon className="h-2.5 w-2.5" />}
                    >
                      {t("inbox_issue.actions.open")}
                    </Button>
                  </ControlLink>
                </div>
              ) : (
                <>
                  {isAllowed && (
                    <CustomMenu
                      customButton={<MoreHorizontal className="size-4" />}
                      customButtonClassName={getIconButtonStyling(
                        "secondary",
                        "lg",
                      )}
                      placement="bottom-start"
                    >
                      {canMarkAsAccepted && (
                        <CustomMenu.MenuItem
                          onClick={() =>
                            handleActionWithPermission(
                              isProjectAdmin,
                              handleIssueSnoozeAction,
                              t("inbox_issue.errors.snooze_permission"),
                            )
                          }
                        >
                          <div className="flex items-center gap-2">
                            <Clock size={14} strokeWidth={2} />
                            {inboxIssue?.snoozed_till &&
                            numberOfDaysLeft &&
                            numberOfDaysLeft > 0
                              ? t("inbox_issue.actions.unsnooze")
                              : t("inbox_issue.actions.snooze")}
                          </div>
                        </CustomMenu.MenuItem>
                      )}
                      {canMarkAsDuplicate && (
                        <CustomMenu.MenuItem
                          onClick={() =>
                            handleActionWithPermission(
                              isProjectAdmin,
                              () => setSelectDuplicateIssue(true),
                              "Only project admins can mark work item as duplicate",
                            )
                          }
                        >
                          <div className="flex items-center gap-2">
                            <FileStack size={14} strokeWidth={2} />
                            {t("inbox_issue.actions.mark_as_duplicate")}
                          </div>
                        </CustomMenu.MenuItem>
                      )}
                      <CustomMenu.MenuItem
                        onClick={() => handleCopyIssueLink(workItemLink)}
                      >
                        <div className="flex items-center gap-2">
                          <CopyIcon width={14} height={14} strokeWidth={2} />
                          {t("inbox_issue.actions.copy")}
                        </div>
                      </CustomMenu.MenuItem>
                      {canDelete && (
                        <CustomMenu.MenuItem
                          onClick={() => setDeleteIssueModal(true)}
                        >
                          <div className="flex items-center gap-2">
                            <TrashIcon width={14} height={14} strokeWidth={2} />
                            {t("inbox_issue.actions.delete")}
                          </div>
                        </CustomMenu.MenuItem>
                      )}
                    </CustomMenu>
                  )}
                </>
              )}
            </div>
          </div>
        </Row>

        <div className="lg:hidden">
          <InboxIssueActionsMobileHeader
            inboxIssue={inboxIssue}
            isSubmitting={isSubmitting}
            handleCopyIssueLink={() => handleCopyIssueLink(workItemLink)}
            setAcceptIssueModal={setAcceptIssueModal}
            setDeclineIssueModal={setDeclineIssueModal}
            handleIssueSnoozeAction={handleIssueSnoozeAction}
            setSelectDuplicateIssue={setSelectDuplicateIssue}
            setDeleteIssueModal={setDeleteIssueModal}
            canMarkAsAccepted={canMarkAsAccepted}
            canMarkAsDeclined={canMarkAsDeclined}
            canMarkAsDuplicate={canMarkAsDuplicate}
            canDelete={canDelete}
            isAcceptedOrDeclined={isAcceptedOrDeclined}
            handleInboxIssueNavigation={handleInboxIssueNavigation}
            workspaceSlug={workspaceSlug}
            isMobileSidebar={isMobileSidebar}
            setIsMobileSidebar={setIsMobileSidebar}
            isNotificationEmbed={isNotificationEmbed}
            embedRemoveCurrentNotification={embedRemoveCurrentNotification}
            isProjectAdmin={isProjectAdmin}
            handleActionWithPermission={handleActionWithPermission}
          />
        </div>
      </>
    );
  },
);
