import {
  ArrowDownWideNarrow,
  ArrowUpNarrowWide,
  CheckIcon,
  ChevronDownIcon,
  Eraser,
  ListFilter,
  MoveRight,
} from "lucide-react";
// hooks
import useLocalStorage from "hooks/use-local-storage";
// components
import {
  SpreadsheetAssigneeColumn,
  SpreadsheetAttachmentColumn,
  SpreadsheetCreatedOnColumn,
  SpreadsheetDueDateColumn,
  SpreadsheetEstimateColumn,
  SpreadsheetLabelColumn,
  SpreadsheetLinkColumn,
  SpreadsheetPriorityColumn,
  SpreadsheetStartDateColumn,
  SpreadsheetStateColumn,
  SpreadsheetSubIssueColumn,
  SpreadsheetUpdatedOnColumn,
} from "components/issues";
// ui
import { CustomMenu } from "@plane/ui";
// types
import { IIssue, IIssueDisplayFilterOptions, IIssueLabel, IState, IUserLite, TIssueOrderByOptions } from "types";
// constants
import { SPREADSHEET_PROPERTY_DETAILS } from "constants/spreadsheet";

type Props = {
  canEditProperties: (projectId: string | undefined) => boolean;
  displayFilters: IIssueDisplayFilterOptions;
  expandedIssues: string[];
  handleDisplayFilterUpdate: (data: Partial<IIssueDisplayFilterOptions>) => void;
  handleUpdateIssue: (issue: IIssue, data: Partial<IIssue>) => void;
  issues: IIssue[] | undefined;
  property: string;
  members?: IUserLite[] | undefined;
  labels?: IIssueLabel[] | undefined;
  states?: IState[] | undefined;
};

export const SpreadsheetColumn: React.FC<Props> = (props) => {
  const {
    canEditProperties,
    displayFilters,
    expandedIssues,
    handleDisplayFilterUpdate,
    handleUpdateIssue,
    issues,
    property,
    members,
    labels,
    states,
  } = props;

  const { storedValue: selectedMenuItem, setValue: setSelectedMenuItem } = useLocalStorage(
    "spreadsheetViewSorting",
    ""
  );
  const { storedValue: activeSortingProperty, setValue: setActiveSortingProperty } = useLocalStorage(
    "spreadsheetViewActiveSortingProperty",
    ""
  );

  const handleOrderBy = (order: TIssueOrderByOptions, itemKey: string) => {
    handleDisplayFilterUpdate({ order_by: order });

    setSelectedMenuItem(`${order}_${itemKey}`);
    setActiveSortingProperty(order === "-created_at" ? "" : itemKey);
  };

  const propertyDetails = SPREADSHEET_PROPERTY_DETAILS[property];

  return (
    <div className="flex h-max w-full max-w-max flex-col bg-custom-background-100">
      <div className="sticky top-0 z-[1] flex h-11 w-full min-w-[8rem] items-center border border-l-0 border-custom-border-100 bg-custom-background-90 px-4 py-1 text-sm font-medium">
        <CustomMenu
          customButtonClassName="!w-full"
          className="!w-full"
          customButton={
            <div className="flex w-full cursor-pointer items-center justify-between gap-1.5 py-2 text-sm text-custom-text-200 hover:text-custom-text-100">
              <div className="flex items-center gap-1.5">
                {<propertyDetails.icon className="h-4 w-4 text-custom-text-400" />}
                {propertyDetails.title}
              </div>
              <div className="ml-3 flex">
                {activeSortingProperty === property && (
                  <div className="flex h-3.5 w-3.5 items-center justify-center rounded-full">
                    <ListFilter className="h-3 w-3" />
                  </div>
                )}
                <ChevronDownIcon className="h-3 w-3" aria-hidden="true" />
              </div>
            </div>
          }
          width="xl"
          placement="bottom-end"
        >
          <CustomMenu.MenuItem onClick={() => handleOrderBy(propertyDetails.ascendingOrderKey, property)}>
            <div
              className={`flex items-center justify-between gap-1.5 px-1 ${
                selectedMenuItem === `${propertyDetails.ascendingOrderKey}_${property}`
                  ? "text-custom-text-100"
                  : "text-custom-text-200 hover:text-custom-text-100"
              }`}
            >
              <div className="flex items-center gap-2">
                <ArrowDownWideNarrow className="h-3 w-3 stroke-[1.5]" />
                <span>{propertyDetails.ascendingOrderTitle}</span>
                <MoveRight className="h-3 w-3" />
                <span>{propertyDetails.descendingOrderTitle}</span>
              </div>

              {selectedMenuItem === `${propertyDetails.ascendingOrderKey}_${property}` && (
                <CheckIcon className="h-3 w-3" />
              )}
            </div>
          </CustomMenu.MenuItem>
          <CustomMenu.MenuItem onClick={() => handleOrderBy(propertyDetails.descendingOrderKey, property)}>
            <div
              className={`flex items-center justify-between gap-1.5 px-1 ${
                selectedMenuItem === `${propertyDetails.descendingOrderKey}_${property}`
                  ? "text-custom-text-100"
                  : "text-custom-text-200 hover:text-custom-text-100"
              }`}
            >
              <div className="flex items-center gap-2">
                <ArrowUpNarrowWide className="h-3 w-3 stroke-[1.5]" />
                <span>{propertyDetails.descendingOrderTitle}</span>
                <MoveRight className="h-3 w-3" />
                <span>{propertyDetails.ascendingOrderTitle}</span>
              </div>

              {selectedMenuItem === `${propertyDetails.descendingOrderKey}_${property}` && (
                <CheckIcon className="h-3 w-3" />
              )}
            </div>
          </CustomMenu.MenuItem>
          {selectedMenuItem &&
            selectedMenuItem !== "" &&
            displayFilters?.order_by !== "-created_at" &&
            selectedMenuItem.includes(property) && (
              <CustomMenu.MenuItem
                className={`mt-0.5 ${selectedMenuItem === `-created_at_${property}` ? "bg-custom-background-80" : ""}`}
                key={property}
                onClick={() => handleOrderBy("-created_at", property)}
              >
                <div className="flex items-center gap-2 px-1">
                  <Eraser className="h-3 w-3" />
                  <span>Clear sorting</span>
                </div>
              </CustomMenu.MenuItem>
            )}
        </CustomMenu>
      </div>

      <div className="h-full w-full min-w-[8rem]">
        {issues?.map((issue) => {
          const disableUserActions = !canEditProperties(issue.project);
          return (
            <div key={`${property}-${issue.id}`} className={`h-fit ${disableUserActions ? "" : "cursor-pointer"}`}>
              {property === "state" ? (
                <SpreadsheetStateColumn
                  disabled={disableUserActions}
                  expandedIssues={expandedIssues}
                  issue={issue}
                  onChange={(issue: IIssue, data: Partial<IIssue>) => handleUpdateIssue(issue, data)}
                  states={states}
                />
              ) : property === "priority" ? (
                <SpreadsheetPriorityColumn
                  disabled={disableUserActions}
                  expandedIssues={expandedIssues}
                  issue={issue}
                  onChange={(issue: IIssue, data: Partial<IIssue>) => handleUpdateIssue(issue, data)}
                />
              ) : property === "estimate" ? (
                <SpreadsheetEstimateColumn
                  disabled={disableUserActions}
                  expandedIssues={expandedIssues}
                  issue={issue}
                  onChange={(issue: IIssue, data: Partial<IIssue>) => handleUpdateIssue(issue, data)}
                />
              ) : property === "assignee" ? (
                <SpreadsheetAssigneeColumn
                  disabled={disableUserActions}
                  expandedIssues={expandedIssues}
                  issue={issue}
                  members={members}
                  onChange={(issue: IIssue, data: Partial<IIssue>) => handleUpdateIssue(issue, data)}
                />
              ) : property === "labels" ? (
                <SpreadsheetLabelColumn
                  disabled={disableUserActions}
                  expandedIssues={expandedIssues}
                  issue={issue}
                  labels={labels}
                  onChange={(issue: IIssue, data: Partial<IIssue>) => handleUpdateIssue(issue, data)}
                />
              ) : property === "start_date" ? (
                <SpreadsheetStartDateColumn
                  disabled={disableUserActions}
                  expandedIssues={expandedIssues}
                  issue={issue}
                  onChange={(issue: IIssue, data: Partial<IIssue>) => handleUpdateIssue(issue, data)}
                />
              ) : property === "due_date" ? (
                <SpreadsheetDueDateColumn
                  disabled={disableUserActions}
                  expandedIssues={expandedIssues}
                  issue={issue}
                  onChange={(issue: IIssue, data: Partial<IIssue>) => handleUpdateIssue(issue, data)}
                />
              ) : property === "created_on" ? (
                <SpreadsheetCreatedOnColumn expandedIssues={expandedIssues} issue={issue} />
              ) : property === "updated_on" ? (
                <SpreadsheetUpdatedOnColumn expandedIssues={expandedIssues} issue={issue} />
              ) : property === "link" ? (
                <SpreadsheetLinkColumn expandedIssues={expandedIssues} issue={issue} />
              ) : property === "attachment_count" ? (
                <SpreadsheetAttachmentColumn expandedIssues={expandedIssues} issue={issue} />
              ) : property === "sub_issue_count" ? (
                <SpreadsheetSubIssueColumn expandedIssues={expandedIssues} issue={issue} />
              ) : null}
            </div>
          );
        })}
      </div>
    </div>
  );
};
