import React from "react";
import {
  ArrayIcon,
  CopyIcon,
  DeleteIcon,
  DublicateIcon,
  FlipXAxisIcon,
  FlipZAxisIcon,
  FocusIcon,
  GroupIcon,
  ModifiersIcon,
  MoveIcon,
  PasteIcon,
  RenameIcon,
  RotateIcon,
  SubMenuIcon,
  TransformIcon,
} from "../../icons/ContextMenuIcons";

// Union of valid visibility keys
type VisibilityKey =
  | "rename"
  | "focus"
  | "flipX"
  | "flipZ"
  | "move"
  | "rotate"
  | "duplicate"
  | "copy"
  | "paste"
  | "modifier"
  | "group"
  | "array"
  | "delete"
  | "transform" // virtual key for submenu
  | "groupArray"; // virtual key for submenu

type ContextMenuProps = {
  visibility: Record<
    Exclude<VisibilityKey, "transform" | "groupArray">,
    boolean
  >;
  onRename: () => void;
  onFocus: () => void;
  onFlipX: () => void;
  onFlipZ: () => void;
  onMove: () => void;
  onRotate: () => void;
  onDuplicate: () => void;
  onCopy: () => void;
  onPaste: () => void;
  onGroup: () => void;
  onArray: () => void;
  onDelete: () => void;
};

type MenuItem = {
  key: VisibilityKey;
  label: string;
  icon?: React.ReactNode;
  shortcut?: string;
  onClick?: () => void;
  submenuIcon?: React.ReactNode;
  children?: MenuItem[];
};

const ContextMenu: React.FC<ContextMenuProps> = ({
  visibility,
  onRename,
  onFocus,
  onFlipX,
  onFlipZ,
  onMove,
  onRotate,
  onDuplicate,
  onCopy,
  onPaste,
  onGroup,
  onArray,
  onDelete,
}) => {
  const items: MenuItem[] = [
    {
      key: "rename",
      label: "Rename",
      icon: <RenameIcon />,
      shortcut: "F2",
      onClick: onRename,
    },
    {
      key: "focus",
      label: "Focus",
      icon: <FocusIcon />,
      shortcut: "F",
      onClick: onFocus,
    },
    {
      key: "flipX",
      label: "Flip to X axis",
      icon: <FlipXAxisIcon />,
      onClick: onFlipX,
    },
    {
      key: "flipZ",
      label: "Flip to Z axis",
      icon: <FlipZAxisIcon />,
      onClick: onFlipZ,
    },
    {
      key: "transform",
      label: "Transform",
      icon: <TransformIcon />,
      submenuIcon: <SubMenuIcon />,
      children: [
        {
          key: "move",
          label: "Move",
          icon: <MoveIcon />,
          shortcut: "G",
          onClick: onMove,
        },
        {
          key: "rotate",
          label: "Rotate",
          icon: <RotateIcon />,
          shortcut: "R",
          onClick: onRotate,
        },
      ],
    },
    {
      key: "duplicate",
      label: "Duplicate",
      icon: <DublicateIcon />,
      shortcut: "Ctrl + D",
      onClick: onDuplicate,
    },
    {
      key: "copy",
      label: "Copy Objects",
      icon: <CopyIcon />,
      shortcut: "Ctrl + C",
      onClick: onCopy,
    },
    {
      key: "paste",
      label: "Paste Objects",
      icon: <PasteIcon />,
      shortcut: "Ctrl + V",
      onClick: onPaste,
    },
    { key: "modifier", label: "Modifiers", icon: <ModifiersIcon /> },
    {
      key: "groupArray",
      label: "Group / Array",
      children: [
        {
          key: "group",
          label: "Group",
          icon: <GroupIcon />,
          shortcut: "Ctrl + G",
          onClick: onGroup,
        },
        { key: "array", label: "Array", icon: <ArrayIcon />, onClick: onArray },
      ],
    },
    {
      key: "delete",
      label: "Delete",
      icon: <DeleteIcon />,
      shortcut: "X",
      onClick: onDelete,
    },
  ];

  const renderItem = (item: MenuItem): React.ReactNode => {
    if (item.children) {
      const children = item.children.filter(
        (child) => visibility[child.key as keyof typeof visibility]
      );
      if (!children.length) return null;

      return (
        <div className="menuItem" key={item.key}>
          <button className="button more">
            <div className="value">
              <div className="icon">{item.icon}</div>
              <span>{item.label}</span>
            </div>
            {item.submenuIcon && <div className="more">{item.submenuIcon}</div>}
          </button>
          <div className="submenu">{children.map(renderItem)}</div>
        </div>
      );
    }

    if (!visibility[item.key as keyof typeof visibility]) return null;

    return (
      <div className="menuItem" key={item.key}>
        <button
          className={`${item.key === "delete" ? "delete " : ""}button`}
          onClick={item.onClick}
        >
          <div className="icon">{item.icon}</div>
          <span>{item.label}</span>
        </button>
        {item.shortcut && <span className="shortcut">{item.shortcut}</span>}
      </div>
    );
  };

  return <div className="context-menu">{items.map(renderItem)}</div>;
};

export default ContextMenu;
