import { useAppStore } from "../store";

const MenuItem = ({
  onClick,
  children,
  className = "",
}: {
  onClick: () => void;
  children: React.ReactNode;
  className?: string;
}) => (
  <button
    className={`w-full text-left px-4 py-1.5 hover:bg-accent-blue hover:text-white transition-colors ${className}`}
    onPointerUp={(e) => {
      e.stopPropagation();
      if (e.button === 0 || e.button === 2) {
        onClick();
      }
    }}
    onClick={(e) => e.preventDefault()}
    onContextMenu={(e) => e.preventDefault()}
  >
    {children}
  </button>
);

export const ContextMenu = () => {
  const {
    contextMenu,
    setContextMenu,
    setImages,
    selectedNodeIds,
    setZoom,
    setPan,
    zoom,
    pan,
    setPalettes,
    images,
    setIsAnnotationMode,
    setAnnotations,
    setTextNotes,
  } = useAppStore();

  if (!contextMenu) return null;

  const handleDelete = () => {
    setImages((prev) =>
      prev.filter((img) => !selectedNodeIds.includes(img.id)),
    );
    setTextNotes((prev) =>
      prev.filter((note) => !selectedNodeIds.includes(note.id)),
    );
    setAnnotations((prev) =>
      prev.filter((ann) => !selectedNodeIds.includes(ann.id)),
    );
    setPalettes((prev) =>
      prev.filter((p) => !selectedNodeIds.includes(p.imageId)),
    );
    setContextMenu(null);
  };

  const handleDesaturate = () => {
    setImages((prev) =>
      prev.map((img) =>
        selectedNodeIds.includes(img.id)
          ? { ...img, isDesaturated: !img.isDesaturated }
          : img,
      ),
    );
    setContextMenu(null);
  };

  const handleFlipH = () => {
    setImages((prev) =>
      prev.map((img) =>
        selectedNodeIds.includes(img.id)
          ? { ...img, isFlippedH: !img.isFlippedH }
          : img,
      ),
    );
    setContextMenu(null);
  };

  const handleFlipV = () => {
    setImages((prev) =>
      prev.map((img) =>
        selectedNodeIds.includes(img.id)
          ? { ...img, isFlippedV: !img.isFlippedV }
          : img,
      ),
    );
    setContextMenu(null);
  };

  const handleBringToFront = () => {
    setImages((prev) => {
      const selected = prev.filter((img) => selectedNodeIds.includes(img.id));
      const others = prev.filter((img) => !selectedNodeIds.includes(img.id));
      return [...others, ...selected];
    });
    setTextNotes((prev) => {
      const selected = prev.filter((n) => selectedNodeIds.includes(n.id));
      const others = prev.filter((n) => !selectedNodeIds.includes(n.id));
      return [...others, ...selected];
    });
    setContextMenu(null);
  };

  const handleSendToBack = () => {
    setImages((prev) => {
      const selected = prev.filter((img) => selectedNodeIds.includes(img.id));
      const others = prev.filter((img) => !selectedNodeIds.includes(img.id));
      return [...selected, ...others];
    });
    setTextNotes((prev) => {
      const selected = prev.filter((n) => selectedNodeIds.includes(n.id));
      const others = prev.filter((n) => !selectedNodeIds.includes(n.id));
      return [...selected, ...others];
    });
    setContextMenu(null);
  };

  const handleFit = () => {
    setZoom(1);
    setPan({ x: 0, y: 0 });
    setContextMenu(null);
  };

  const handleExtractPalette = () => {
    if (contextMenu.imageId) {
      const img = images.find((i) => i.id === contextMenu.imageId);
      if (img) {
        // Mock palette extraction with aesthetic colors
        const aestheticPalettes = [
          ["#2A363B", "#E84A5F", "#FF847C", "#FECEAB", "#99B898"],
          ["#F8B195", "#F67280", "#C06C84", "#6C5B7B", "#355C7D"],
          ["#1A1A1D", "#4E4E50", "#6F2232", "#950740", "#C3073F"],
        ];
        setPalettes((prev) => {
          const existing = prev.filter((p) => p.imageId !== img.id);
          return [
            ...existing,
            {
              imageId: img.id,
              colors:
                aestheticPalettes[
                  Math.floor(Math.random() * aestheticPalettes.length)
                ],
              x: img.x,
              y: img.y + img.height + 20,
            },
          ];
        });
      }
    }
    setContextMenu(null);
  };

  const handleGroup = () => {
    const groupId = Math.random().toString(36).substr(2, 9);
    setImages((prev) =>
      prev.map((img) =>
        selectedNodeIds.includes(img.id) ? { ...img, groupId } : img,
      ),
    );
    setTextNotes((prev) =>
      prev.map((n) =>
        selectedNodeIds.includes(n.id) ? { ...n, groupId } : n,
      ),
    );
    setAnnotations((prev) =>
      prev.map((ann) =>
        selectedNodeIds.includes(ann.id) ? { ...ann, groupId } : ann,
      ),
    );
    setContextMenu(null);
  };

  const handleUngroup = () => {
    setImages((prev) =>
      prev.map((img) =>
        selectedNodeIds.includes(img.id)
          ? { ...img, groupId: undefined }
          : img,
      ),
    );
    setTextNotes((prev) =>
      prev.map((n) =>
        selectedNodeIds.includes(n.id)
          ? { ...n, groupId: undefined }
          : n,
      ),
    );
    setAnnotations((prev) =>
      prev.map((ann) =>
        selectedNodeIds.includes(ann.id)
          ? { ...ann, groupId: undefined }
          : ann,
      ),
    );
    setContextMenu(null);
  };

  const handleAddTextNote = () => {
    const newX = (contextMenu.x - pan.x) / zoom;
    const newY = (contextMenu.y - pan.y) / zoom;
    setTextNotes((prev) => [
      ...prev,
      {
        id: Math.random().toString(36).substr(2, 9),
        text: "New Note",
        x: newX,
        y: newY,
        width: 200,
      },
    ]);
    setContextMenu(null);
  };

  return (
    <>
      <div
        className="fixed inset-0 z-[60]"
        onPointerDown={(e) => {
          e.stopPropagation();
          if (e.button === 0) setContextMenu(null);
        }}
        onContextMenu={(e) => {
          e.preventDefault();
          setContextMenu(null);
        }}
      />
      <div
        className="fixed bg-panel-bg border border-panel-border shadow-2xl rounded-md py-1.5 w-48 z-[70] text-[13px] text-ui-primary"
        style={{ top: contextMenu.y, left: contextMenu.x }}
      >
        {contextMenu.imageId ? (
          <>
            <MenuItem onClick={handleFit}>Fit to canvas</MenuItem>
            <MenuItem onClick={handleDesaturate}>Desaturate / Restore</MenuItem>
            <div className="h-px bg-panel-border my-1.5" />
            <MenuItem onClick={handleFlipH}>Flip horizontal</MenuItem>
            <MenuItem onClick={handleFlipV}>Flip vertical</MenuItem>
            <div className="h-px bg-panel-border my-1.5" />
            <MenuItem onClick={handleExtractPalette}>Extract palette</MenuItem>
            <MenuItem
              onClick={() => {
                setIsAnnotationMode(true);
                setContextMenu(null);
              }}
            >
              Add annotation
            </MenuItem>
            <MenuItem
              onClick={async () => {
                if (contextMenu.imageId) {
                  const img = images.find((i) => i.id === contextMenu.imageId);
                  if (img) {
                    try {
                      const response = await fetch(img.url);
                      const blob = await response.blob();
                      await navigator.clipboard.write([
                        new ClipboardItem({
                          [blob.type]: blob,
                        }),
                      ]);
                    } catch (err) {
                      // fallback to URL if image is cross-origin restricted
                      navigator.clipboard.writeText(img.url);
                    }
                  }
                }
                setContextMenu(null);
              }}
            >
              Copy image
            </MenuItem>
            <MenuItem
              onClick={() => {
                window.open(
                  images.find((i) => i.id === contextMenu.imageId)?.url,
                  "_blank",
                );
                setContextMenu(null);
              }}
            >
              Open source URL
            </MenuItem>
            <div className="h-px bg-panel-border my-1.5" />
            {selectedNodeIds.length > 1 && (
              <>
                <MenuItem
                  onClick={() => {
                    // Layout in Row
                    const selected = images.filter((img) =>
                      selectedNodeIds.includes(img.id),
                    );
                    if (selected.length < 2) return;

                    // Sort by current X position
                    selected.sort((a, b) => a.x - b.x);

                    const startX = selected[0].x;
                    const startY = selected[0].y;
                    const targetHeight = selected[0].height;

                    let currentX = startX;
                    const gap = 20;

                    const newImages = images.map((img) => {
                      if (selectedNodeIds.includes(img.id)) {
                        const sortedIndex = selected.findIndex(
                          (s) => s.id === img.id,
                        );
                        // Scale to match height
                        const scale = targetHeight / img.height;
                        const newWidth = img.width * scale;

                        // we have to calculate the X position based on all previous items' widths
                        let curX = startX;
                        for (let i = 0; i < sortedIndex; i++) {
                          curX +=
                            selected[i].width *
                              (targetHeight / selected[i].height) +
                            gap;
                        }

                        return {
                          ...img,
                          x: curX,
                          y: startY,
                          width: newWidth,
                          height: targetHeight,
                        };
                      }
                      return img;
                    });
                    setImages(newImages);
                    setContextMenu(null);
                  }}
                >
                  Organize in Row
                </MenuItem>
                <MenuItem onClick={handleGroup}>Group selection</MenuItem>
              </>
            )}
            <MenuItem onClick={handleUngroup}>Ungroup</MenuItem>
            <div className="h-px bg-panel-border my-1.5" />
            <MenuItem onClick={handleBringToFront}>Bring to front</MenuItem>
            <MenuItem onClick={handleSendToBack}>Send to back</MenuItem>
            <div className="h-px bg-panel-border my-1.5" />
            <MenuItem
              className="text-[#FF453A] hover:bg-[#FF453A]"
              onClick={handleDelete}
            >
              Delete selection
            </MenuItem>
          </>
        ) : (
          <>
            <MenuItem onClick={handleFit}>Fit to canvas (Reset View)</MenuItem>
            <MenuItem
              onClick={() => {
                setAnnotations([]);
                setContextMenu(null);
              }}
            >
              Clear all annotations
            </MenuItem>
            <div className="h-px bg-panel-border my-1.5" />
            <MenuItem onClick={handleAddTextNote}>Add Text Note</MenuItem>
            <MenuItem
              onClick={() => {
                setIsAnnotationMode(true);
                setContextMenu(null);
              }}
            >
              Add annotation
            </MenuItem>
          </>
        )}
      </div>
    </>
  );
};
