import { Dispatch, MutableRefObject, SetStateAction, useRef, useState } from "react";
import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
// icons
import { ChevronRight, MoreHorizontal } from "lucide-react";
// constants
import { SPREADSHEET_PROPERTY_LIST } from "constants/spreadsheet";
// components
import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-HOC";
import RenderIfVisible from "components/core/render-if-visible-HOC";
import { IssueColumn } from "./issue-column";
// ui
import { ControlLink, Tooltip } from "@plane/ui";
// hooks
import useOutsideClickDetector from "hooks/use-outside-click-detector";
import { useIssueDetail, useProject } from "hooks/store";
// helper
import { cn } from "helpers/common.helper";
// types
import { IIssueDisplayProperties, TIssue } from "@plane/types";
import { EIssueActions } from "../types";

interface Props {
  displayProperties: IIssueDisplayProperties;
  isEstimateEnabled: boolean;
  quickActions: (
    issue: TIssue,
    customActionButton?: React.ReactElement,
    portalElement?: HTMLDivElement | null
  ) => React.ReactNode;
  canEditProperties: (projectId: string | undefined) => boolean;
  handleIssues: (issue: TIssue, action: EIssueActions) => Promise<void>;
  portalElement: React.MutableRefObject<HTMLDivElement | null>;
  nestingLevel: number;
  issueId: string;
  isScrolled: MutableRefObject<boolean>;
  containerRef: MutableRefObject<HTMLTableElement | null>;
  issueIds: string[];
}

export const SpreadsheetIssueRow = observer((props: Props) => {
  const {
    displayProperties,
    issueId,
    isEstimateEnabled,
    nestingLevel,
    portalElement,
    handleIssues,
    quickActions,
    canEditProperties,
    isScrolled,
    containerRef,
    issueIds,
  } = props;

  const [isExpanded, setExpanded] = useState<boolean>(false);
  const { subIssues: subIssuesStore } = useIssueDetail();

  const subIssues = subIssuesStore.subIssuesByIssueId(issueId);

  return (
    <>
      {/* first column/ issue name and key column */}
      <RenderIfVisible
        as="tr"
        defaultHeight="calc(2.75rem - 1px)"
        root={containerRef}
        placeholderChildren={<td colSpan={100} className="border-b-[0.5px] border-custom-border-200" />}
        changingReference={issueIds}
      >
        <IssueRowDetails
          issueId={issueId}
          displayProperties={displayProperties}
          quickActions={quickActions}
          canEditProperties={canEditProperties}
          nestingLevel={nestingLevel}
          isEstimateEnabled={isEstimateEnabled}
          handleIssues={handleIssues}
          portalElement={portalElement}
          isScrolled={isScrolled}
          isExpanded={isExpanded}
          setExpanded={setExpanded}
        />
      </RenderIfVisible>

      {isExpanded &&
        subIssues &&
        subIssues.length > 0 &&
        subIssues.map((subIssueId: string) => (
          <SpreadsheetIssueRow
            key={subIssueId}
            issueId={subIssueId}
            displayProperties={displayProperties}
            quickActions={quickActions}
            canEditProperties={canEditProperties}
            nestingLevel={nestingLevel + 1}
            isEstimateEnabled={isEstimateEnabled}
            handleIssues={handleIssues}
            portalElement={portalElement}
            isScrolled={isScrolled}
            containerRef={containerRef}
            issueIds={issueIds}
          />
        ))}
    </>
  );
});

interface IssueRowDetailsProps {
  displayProperties: IIssueDisplayProperties;
  isEstimateEnabled: boolean;
  quickActions: (
    issue: TIssue,
    customActionButton?: React.ReactElement,
    portalElement?: HTMLDivElement | null
  ) => React.ReactNode;
  canEditProperties: (projectId: string | undefined) => boolean;
  handleIssues: (issue: TIssue, action: EIssueActions) => Promise<void>;
  portalElement: React.MutableRefObject<HTMLDivElement | null>;
  nestingLevel: number;
  issueId: string;
  isScrolled: MutableRefObject<boolean>;
  isExpanded: boolean;
  setExpanded: Dispatch<SetStateAction<boolean>>;
}

const IssueRowDetails = observer((props: IssueRowDetailsProps) => {
  const {
    displayProperties,
    issueId,
    isEstimateEnabled,
    nestingLevel,
    portalElement,
    handleIssues,
    quickActions,
    canEditProperties,
    isScrolled,
    isExpanded,
    setExpanded,
  } = props;
  // router
  const router = useRouter();
  const { workspaceSlug } = router.query;
  //hooks
  const { getProjectById } = useProject();
  const { peekIssue, setPeekIssue } = useIssueDetail();
  // states
  const [isMenuActive, setIsMenuActive] = useState(false);
  const menuActionRef = useRef<HTMLDivElement | null>(null);

  const handleIssuePeekOverview = (issue: TIssue) => {
    if (workspaceSlug && issue && issue.project_id && issue.id)
      setPeekIssue({ workspaceSlug: workspaceSlug.toString(), projectId: issue.project_id, issueId: issue.id });
  };

  const { subIssues: subIssuesStore, issue } = useIssueDetail();

  const issueDetail = issue.getIssueById(issueId);

  const paddingLeft = `${nestingLevel * 54}px`;

  useOutsideClickDetector(menuActionRef, () => setIsMenuActive(false));

  const handleToggleExpand = () => {
    setExpanded((prevState) => {
      if (!prevState && workspaceSlug && issueDetail)
        subIssuesStore.fetchSubIssues(workspaceSlug.toString(), issueDetail.project_id, issueDetail.id);
      return !prevState;
    });
  };

  const customActionButton = (
    <div
      ref={menuActionRef}
      className={`w-full cursor-pointer rounded p-1 text-custom-sidebar-text-400 hover:bg-custom-background-80 ${
        isMenuActive ? "bg-custom-background-80 text-custom-text-100" : "text-custom-text-200"
      }`}
      onClick={() => setIsMenuActive(!isMenuActive)}
    >
      <MoreHorizontal className="h-3.5 w-3.5" />
    </div>
  );
  if (!issueDetail) return null;

  const disableUserActions = !canEditProperties(issueDetail.project_id);

  return (
    <>
      <td
        className={cn(
          "sticky group left-0 h-11  w-[28rem] flex items-center bg-custom-background-100 text-sm after:absolute border-r-[0.5px] border-custom-border-200",
          {
            "border-b-[0.5px]": peekIssue?.issueId !== issueDetail.id,
          },
          {
            "border border-custom-primary-70 hover:border-custom-primary-70": peekIssue?.issueId === issueDetail.id,
          },
          {
            "shadow-[8px_22px_22px_10px_rgba(0,0,0,0.05)]": isScrolled.current,
          }
        )}
        tabIndex={0}
      >
        <WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="key">
          <div
            className="flex min-w-min items-center gap-1.5 px-4 py-2.5 pr-0"
            style={issueDetail.parent_id && nestingLevel !== 0 ? { paddingLeft } : {}}
          >
            <div className="relative flex cursor-pointer items-center text-center text-xs hover:text-custom-text-100">
              <span
                className={`flex items-center justify-center font-medium  group-hover:opacity-0 ${
                  isMenuActive ? "opacity-0" : "opacity-100"
                }`}
              >
                {getProjectById(issueDetail.project_id)?.identifier}-{issueDetail.sequence_id}
              </span>

              {canEditProperties(issueDetail.project_id) && (
                <div className={`absolute left-2.5 top-0 hidden group-hover:block ${isMenuActive ? "!block" : ""}`}>
                  {quickActions(issueDetail, customActionButton, portalElement.current)}
                </div>
              )}
            </div>

            {issueDetail.sub_issues_count > 0 && (
              <div className="flex h-6 w-6 items-center justify-center">
                <button
                  className="h-5 w-5 cursor-pointer rounded-sm hover:bg-custom-background-90 hover:text-custom-text-100"
                  onClick={() => handleToggleExpand()}
                >
                  <ChevronRight className={`h-3.5 w-3.5 ${isExpanded ? "rotate-90" : ""}`} />
                </button>
              </div>
            )}
          </div>
        </WithDisplayPropertiesHOC>
        <ControlLink
          href={`/${workspaceSlug}/projects/${issueDetail.project_id}/issues/${issueId}`}
          target="_blank"
          onClick={() => handleIssuePeekOverview(issueDetail)}
          className="clickable w-full line-clamp-1 cursor-pointer text-sm text-custom-text-100"
        >
          <div className="w-full overflow-hidden">
            <Tooltip tooltipHeading="Title" tooltipContent={issueDetail.name}>
              <div className="h-full w-full cursor-pointer truncate px-4 py-2.5 text-left text-[0.825rem] text-custom-text-100" tabIndex={-1}>
                {issueDetail.name}
              </div>
            </Tooltip>
          </div>
        </ControlLink>
      </td>
      {/* Rest of the columns */}
      {SPREADSHEET_PROPERTY_LIST.map((property) => (
          <IssueColumn
            displayProperties={displayProperties}
            issueDetail={issueDetail}
            disableUserActions={disableUserActions}
            property={property}
            handleIssues={handleIssues}
            isEstimateEnabled={isEstimateEnabled}
          />
        ))}
    </>
  );
});