import { type Component, createSignal, For, createEffect } from "solid-js";
import { Search, Save, FolderOpen, Tag, Settings, Database, Server, RefreshCw, Cpu, ChevronRight, X, Calendar, Pen, Type, Underline, Strikethrough, Code, Quote, ImageIcon, Heading1, Heading2, Heading3, Link, CheckSquare, List, ListOrdered, Film, AppWindow, Minus, Grid3X3, AlignLeft, AlignCenter, AlignRight, FileText, Delete, Trash2, Highlighter, Bold, Italic, ListTodo } from "lucide-solid";
import { cn } from "@/lib/utils";

export interface CommandItem {
    title: string;
    description: string;
    aliases?: string[];
    icon: any;
    command: (props: { editor: any; range: any }) => void;
}

export const getSuggestionItems = ({ query }: { query: string }): CommandItem[] => {
    return [
        {
            title: "Text",
            description: "Just start typing with plain text.",
            icon: Type,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).setNode("paragraph").run();
            },
        },
        {
            title: "Bold",
            description: "Strong text. (**text**)",
            aliases: ["b", "strong"],
            icon: Bold,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).toggleBold().run();
            },
        },
        {
            title: "Italic",
            description: "Emphasized text. (*text*)",
            aliases: ["i", "emphasis"],
            icon: Italic,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).toggleItalic().run();
            },
        },
        {
            title: "Underline",
            description: "Underlined text.",
            aliases: ["u"],
            icon: Underline,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).toggleUnderline().run();
            },
        },
        {
            title: "Heading 1",
            description: "Big section heading.",
            aliases: ["h1"],
            icon: Heading1,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).setNode("heading", { level: 1 }).run();
            },
        },
        {
            title: "Heading 2",
            description: "Medium section heading.",
            aliases: ["h2"],
            icon: Heading2,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).setNode("heading", { level: 2 }).run();
            },
        },
        {
            title: "Heading 3",
            description: "Small section heading.",
            aliases: ["h3"],
            icon: Heading3,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).setNode("heading", { level: 3 }).run();
            },
        },
        {
            title: "Bullet List",
            description: "Create a simple bulleted list.",
            icon: List,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).toggleBulletList().run();
            },
        },
        {
            title: "Checklist",
            description: "Insert a checklist.",
            icon: ListTodo,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).toggleTaskList().run();
            },
        },
        {
            title: "Code Block",
            description: "Capture a code snippet.",
            icon: Code,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).toggleCodeBlock().run();
            },
        },
        {
            title: "Blockquote",
            description: "Capture a quote.",
            icon: Quote,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).toggleBlockquote().run();
            },
        },
        {
            title: "Image",
            description: "Upload an image.",
            icon: ImageIcon,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).uploadImage().run();
            },
        },
        {
            title: "Video",
            description: "Upload a video.",
            aliases: ["movie", "mp4", "mov"],
            icon: Film,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).uploadVideo().run();
            },
        },
        {
            title: "File",
            description: "Upload a document or file.",
            aliases: ["file", "pdf", "doc", "upload"],
            icon: FileText,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).uploadFile().run();
            },
        },
        {
            title: "Job File",
            description: "Embed a job file from Prism.",
            aliases: ["job", "jobfile", "prism"],
            icon: AppWindow,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).insertFileViewer().run();
            },
        },
        {
            title: "Divider",
            description: "Insert a horizontal rule.",
            icon: Minus,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).setHorizontalRule().run();
            },
        },
        {
            title: "Table",
            description: "Insert a 3x3 table.",
            aliases: ["grid", "table"],
            icon: Grid3X3,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();
            },
        },
        {
            title: "Highlight",
            description: "Highlight selected text.",
            aliases: ["mark"],
            icon: Highlighter,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).toggleHighlight().run();
            },
        },
        {
            title: "Align Left",
            description: "Align text to the left.",
            icon: AlignLeft,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).setTextAlign("left").run();
            },
        },
        {
            title: "Align Center",
            description: "Align text to the center.",
            icon: AlignCenter,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).setTextAlign("center").run();
            },
        },
        {
            title: "Align Right",
            description: "Align text to the right.",
            icon: AlignRight,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).setTextAlign("right").run();
            },
        },
        {
            title: "Add Row Above",
            description: "Insert a new row above the cursor.",
            icon: Grid3X3,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).addRowBefore().run();
            },
        },
        {
            title: "Add Row Below",
            description: "Insert a new row below the cursor.",
            icon: Grid3X3,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).addRowAfter().run();
            },
        },
        {
            title: "Delete Row",
            description: "Delete the current row.",
            icon: Trash2,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).deleteRow().run();
            },
        },
        {
            title: "Add Column Left",
            description: "Insert a new column to the left.",
            icon: Grid3X3,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).addColumnBefore().run();
            },
        },
        {
            title: "Add Column Right",
            description: "Insert a new column to the right.",
            icon: Grid3X3,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).addColumnAfter().run();
            },
        },
        {
            title: "Delete Column",
            description: "Delete the current column.",
            icon: Trash2,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).deleteColumn().run();
            },
        },
        {
            title: "Delete Table",
            description: "Delete the entire table.",
            icon: Trash2,
            command: ({ editor, range }: { editor: any, range: any }) => {
                editor.chain().focus().deleteRange(range).deleteTable().run();
            },
        },
    ].filter(item => {
        const lowerQuery = query.toLowerCase();
        return item.title.toLowerCase().startsWith(lowerQuery) ||
            item.aliases?.some(alias => alias.toLowerCase().startsWith(lowerQuery));
    });
};

export const SlashMenu: Component<{
    items: CommandItem[];
    command: (item: CommandItem) => void;
    editor: any;
    ref: (handlers: { onKeyDown: (e: KeyboardEvent) => boolean }) => void;
}> = (props) => {
    const [selectedIndex, setSelectedIndex] = createSignal(0);

    // Auto-select the first item when the list changes (filtering)
    createEffect(() => {
        // We track props.items. When it changes, we reset.
        props.items;
        setSelectedIndex(0);
    });

    const selectItem = (index: number) => {
        const item = props.items[index];
        if (item) {
            props.command(item);
        }
    };

    // Expose handlers to the parent via the ref prop
    props.ref({
        onKeyDown: (e: KeyboardEvent) => {
            if (e.key === "ArrowUp") {
                setSelectedIndex((prev) => (prev + props.items.length - 1) % props.items.length);
                return true;
            }
            if (e.key === "ArrowDown") {
                setSelectedIndex((prev) => (prev + 1) % props.items.length);
                return true;
            }
            if (e.key === "Enter") {
                selectItem(selectedIndex());
                return true;
            }
            return false;
        }
    });

    return (
        <div
            class="z-[200] w-64 bg-popover border border-border rounded-lg shadow-xl overflow-hidden p-1 bg-background pointer-events-auto"
            onMouseDown={(e) => e.stopPropagation()}
            onWheel={(e) => e.stopPropagation()}
        >
            <div class="max-h-[300px] overflow-y-auto scrollbar-thin scrollbar-thumb-muted-foreground/20 overscroll-contain">
                <For each={props.items}>
                    {(item, index) => (
                        <button
                            class={cn(
                                "flex items-center gap-3 w-full px-2 py-1.5 text-left rounded-md transition-colors outline-none",
                                index() === selectedIndex() ? "bg-accent text-accent-foreground" : "hover:bg-muted"
                            )}
                            onMouseDown={(e) => {
                                // Prevent editor focus loss and side-sheet closure
                                e.preventDefault();
                                e.stopPropagation();
                                selectItem(index());
                            }}
                            onMouseEnter={() => setSelectedIndex(index())}
                        >
                            <div class="flex items-center justify-center w-8 h-8 rounded border border-border bg-muted/50 text-muted-foreground shrink-0">
                                <item.icon size={16} />
                            </div>
                            <div class="flex flex-col min-w-0 overflow-hidden">
                                <span class="text-sm font-medium leading-none">{item.title}</span>
                                <span class="text-[0.6875rem] text-muted-foreground truncate mt-1">{item.description}</span>
                            </div>
                        </button>
                    )}
                </For>
                {props.items.length === 0 && (
                    <div class="p-2 text-xs text-muted-foreground text-center">No results found</div>
                )}
            </div>
        </div>
    );
};
