import { Command } from "cmdk";
import {
    ArchiveIcon,
    BookOpenIcon,
    EarthIcon,
    FileTextIcon,
    InboxIcon,
    InfoIcon,
    PaperclipIcon,
    PlusIcon,
    SearchIcon,
    SettingsIcon,
} from "lucide-react";
import { useCallback, useEffect, useRef, useState } from "react";
import { useNavigate } from "react-router-dom";
import { memoServiceClient } from "@/service";
import { create } from "@bufbuild/protobuf";
import { ListMemosRequestSchema } from "@/types/proto/api/v1/memo_service_pb";
import useCurrentUser from "@/hooks/useCurrentUser";
import { ROUTES } from "@/router/routes";

// Helper to extract plain text snippet from memo content
function getSnippet(content: string, maxLen = 80): string {
    const plain = content
        .replace(/[#*_~`>\[\]()!]/g, "")
        .replace(/\n+/g, " ")
        .trim();
    return plain.length > maxLen ? plain.slice(0, maxLen) + "…" : plain;
}

const CommandPalette = () => {
    const [open, setOpen] = useState(false);
    const [query, setQuery] = useState("");
    const [memos, setMemos] = useState<Array<{ name: string; snippet: string }>>([]);
    const [loading, setLoading] = useState(false);
    const navigate = useNavigate();
    const currentUser = useCurrentUser();
    const debounceRef = useRef<ReturnType<typeof setTimeout>>();

    // Global ⌘K / Ctrl+K shortcut
    useEffect(() => {
        const handler = (e: KeyboardEvent) => {
            if ((e.metaKey || e.ctrlKey) && e.key === "k") {
                e.preventDefault();
                setOpen((prev) => !prev);
            }
        };
        document.addEventListener("keydown", handler);
        return () => document.removeEventListener("keydown", handler);
    }, []);

    // Search memos when query changes
    const searchMemos = useCallback(
        async (searchQuery: string) => {
            if (!searchQuery.trim() || !currentUser) {
                setMemos([]);
                return;
            }
            setLoading(true);
            try {
                const response = await memoServiceClient.listMemos(
                    create(ListMemosRequestSchema, {
                        pageSize: 8,
                        filter: `creator == "${currentUser.name}" && content_search == ["${searchQuery.trim()}"]`,
                    }),
                );
                setMemos(
                    response.memos.map((m) => ({
                        name: m.name,
                        snippet: getSnippet(m.content),
                    })),
                );
            } catch {
                setMemos([]);
            } finally {
                setLoading(false);
            }
        },
        [currentUser],
    );

    // Debounced search
    useEffect(() => {
        if (debounceRef.current) clearTimeout(debounceRef.current);
        debounceRef.current = setTimeout(() => searchMemos(query), 250);
        return () => {
            if (debounceRef.current) clearTimeout(debounceRef.current);
        };
    }, [query, searchMemos]);

    const goTo = (path: string) => {
        navigate(path);
        setOpen(false);
        setQuery("");
    };

    if (!open) return null;

    return (
        <div className="fixed inset-0 z-[999]" onClick={() => setOpen(false)}>
            <div className="fixed inset-0 bg-black/50 backdrop-blur-sm animate-in fade-in duration-150" />
            <div className="fixed inset-0 flex items-start justify-center pt-[20vh]">
                <div
                    className="w-full max-w-lg animate-in slide-in-from-top-4 fade-in duration-200"
                    onClick={(e) => e.stopPropagation()}
                >
                    <Command
                        className="rounded-xl border border-border bg-background shadow-2xl overflow-hidden"
                        shouldFilter={false}
                    >
                        {/* Search Input */}
                        <div className="flex items-center gap-2 border-b border-border px-4 py-3">
                            <SearchIcon className="w-5 h-5 text-muted-foreground shrink-0" />
                            <Command.Input
                                value={query}
                                onValueChange={setQuery}
                                placeholder="Search memos, navigate pages..."
                                className="flex-1 bg-transparent text-sm text-foreground placeholder:text-muted-foreground outline-none"
                                autoFocus
                            />
                            <kbd className="hidden sm:inline-flex h-5 items-center gap-1 rounded border border-border bg-muted px-1.5 text-[10px] font-medium text-muted-foreground">
                                ESC
                            </kbd>
                        </div>

                        <Command.List className="max-h-80 overflow-y-auto p-2">
                            {/* No results */}
                            <Command.Empty className="py-8 text-center text-sm text-muted-foreground">
                                {loading ? (
                                    <span className="flex items-center justify-center gap-2">
                                        <span className="w-4 h-4 border-2 border-amber-500 border-t-transparent rounded-full animate-spin" />
                                        Searching...
                                    </span>
                                ) : query ? (
                                    "No results found."
                                ) : (
                                    "Type to search memos..."
                                )}
                            </Command.Empty>

                            {/* Memo results */}
                            {memos.length > 0 && (
                                <Command.Group heading="Memos">
                                    {memos.map((memo) => {
                                        const memoPath = memo.name.startsWith("memos/") ? memo.name : `memos/${memo.name}`;
                                        return (
                                            <Command.Item
                                                key={memo.name}
                                                value={memo.name}
                                                onSelect={() => goTo(`/app/${memoPath}`)}
                                                className="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm cursor-pointer select-none transition-colors data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground hover:bg-accent/50"
                                            >
                                                <FileTextIcon className="w-4 h-4 text-amber-500 shrink-0" />
                                                <span className="truncate text-foreground">{memo.snippet}</span>
                                            </Command.Item>
                                        );
                                    })}
                                </Command.Group>
                            )}

                            {/* Navigation */}
                            {!query && (
                                <>
                                    <Command.Group heading="Navigate">
                                        <Command.Item
                                            onSelect={() => goTo(ROUTES.ROOT)}
                                            className="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm cursor-pointer select-none transition-colors data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground hover:bg-accent/50"
                                        >
                                            <BookOpenIcon className="w-4 h-4 text-muted-foreground" />
                                            <span>Home</span>
                                            <kbd className="ml-auto text-[10px] text-muted-foreground">→</kbd>
                                        </Command.Item>
                                        <Command.Item
                                            onSelect={() => goTo(ROUTES.EXPLORE)}
                                            className="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm cursor-pointer select-none transition-colors data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground hover:bg-accent/50"
                                        >
                                            <EarthIcon className="w-4 h-4 text-muted-foreground" />
                                            <span>Explore</span>
                                        </Command.Item>
                                        <Command.Item
                                            onSelect={() => goTo(ROUTES.INBOX)}
                                            className="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm cursor-pointer select-none transition-colors data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground hover:bg-accent/50"
                                        >
                                            <InboxIcon className="w-4 h-4 text-muted-foreground" />
                                            <span>Inbox</span>
                                        </Command.Item>
                                        <Command.Item
                                            onSelect={() => goTo(ROUTES.ARCHIVED)}
                                            className="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm cursor-pointer select-none transition-colors data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground hover:bg-accent/50"
                                        >
                                            <ArchiveIcon className="w-4 h-4 text-muted-foreground" />
                                            <span>Archived</span>
                                        </Command.Item>
                                        <Command.Item
                                            onSelect={() => goTo(ROUTES.ATTACHMENTS)}
                                            className="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm cursor-pointer select-none transition-colors data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground hover:bg-accent/50"
                                        >
                                            <PaperclipIcon className="w-4 h-4 text-muted-foreground" />
                                            <span>Attachments</span>
                                        </Command.Item>
                                        <Command.Item
                                            onSelect={() => goTo(ROUTES.SETTING)}
                                            className="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm cursor-pointer select-none transition-colors data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground hover:bg-accent/50"
                                        >
                                            <SettingsIcon className="w-4 h-4 text-muted-foreground" />
                                            <span>Settings</span>
                                        </Command.Item>
                                        <Command.Item
                                            onSelect={() => goTo(ROUTES.ABOUT)}
                                            className="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm cursor-pointer select-none transition-colors data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground hover:bg-accent/50"
                                        >
                                            <InfoIcon className="w-4 h-4 text-muted-foreground" />
                                            <span>About</span>
                                        </Command.Item>
                                    </Command.Group>

                                    <Command.Group heading="Quick Actions">
                                        <Command.Item
                                            onSelect={() => {
                                                goTo(ROUTES.ROOT);
                                            }}
                                            className="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm cursor-pointer select-none transition-colors data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground hover:bg-accent/50"
                                        >
                                            <PlusIcon className="w-4 h-4 text-amber-500" />
                                            <span>New Memo</span>
                                            <kbd className="ml-auto text-[10px] text-muted-foreground">Ctrl+N</kbd>
                                        </Command.Item>
                                    </Command.Group>
                                </>
                            )}
                        </Command.List>

                        {/* Footer */}
                        <div className="border-t border-border px-4 py-2 flex items-center justify-between text-[11px] text-muted-foreground">
                            <div className="flex items-center gap-3">
                                <span className="flex items-center gap-1">
                                    <kbd className="px-1 py-0.5 rounded border border-border bg-muted text-[10px]">↑↓</kbd>
                                    navigate
                                </span>
                                <span className="flex items-center gap-1">
                                    <kbd className="px-1 py-0.5 rounded border border-border bg-muted text-[10px]">↵</kbd>
                                    select
                                </span>
                            </div>
                            <span className="flex items-center gap-1">
                                <kbd className="px-1 py-0.5 rounded border border-border bg-muted text-[10px]">Ctrl K</kbd>
                                toggle
                            </span>
                        </div>
                    </Command>
                </div>
            </div>
        </div>
    );
};

export default CommandPalette;
