import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { memo, useState, useEffect, useRef, useCallback, useMemo } from 'react';
import { FileCode, Search } from 'lucide-react';
import { useFilePickerStore } from '../../stores/filePickerStore';
import { useFileBrowserStore } from '../../stores/fileBrowserStore';
import { useFiles } from '../../hooks/useFiles';
function fuzzyMatch(query, target) {
    const q = query.toLowerCase();
    const t = target.toLowerCase();
    if (q.length === 0)
        return { match: true, score: 0 };
    if (t.includes(q))
        return { match: true, score: 100 - t.indexOf(q) };
    let qi = 0;
    let score = 0;
    let lastMatchIdx = -1;
    for (let ti = 0; ti < t.length && qi < q.length; ti++) {
        if (t[ti] === q[qi]) {
            score += 10;
            if (lastMatchIdx === ti - 1)
                score += 5;
            if (ti === 0 || t[ti - 1] === '/' || t[ti - 1] === '.')
                score += 8;
            lastMatchIdx = ti;
            qi++;
        }
    }
    return { match: qi === q.length, score };
}
export const QuickFilePicker = memo(function QuickFilePicker() {
    const isOpen = useFilePickerStore((s) => s.isOpen);
    const close = useFilePickerStore((s) => s.close);
    const openFile = useFileBrowserStore((s) => s.openFile);
    const expandSidebar = useFileBrowserStore((s) => s.expandSidebar);
    const [query, setQuery] = useState('');
    const [selectedIndex, setSelectedIndex] = useState(0);
    const inputRef = useRef(null);
    const listRef = useRef(null);
    const { data: filesData } = useFiles();
    const ignoredSet = useMemo(() => new Set(filesData?.ignoredFiles ?? []), [filesData?.ignoredFiles]);
    const filtered = useMemo(() => {
        if (!filesData?.files)
            return [];
        if (!query)
            return filesData.files.slice(0, 50);
        const results = filesData.files
            .map((file) => ({ file, ...fuzzyMatch(query, file) }))
            .filter((r) => r.match)
            .sort((a, b) => b.score - a.score)
            .slice(0, 50);
        return results.map((r) => r.file);
    }, [filesData?.files, query]);
    useEffect(() => {
        if (isOpen) {
            setQuery('');
            setSelectedIndex(0);
            setTimeout(() => inputRef.current?.focus(), 0);
        }
    }, [isOpen]);
    useEffect(() => {
        const item = listRef.current?.children[selectedIndex];
        item?.scrollIntoView({ block: 'nearest' });
    }, [selectedIndex]);
    const handleSelect = useCallback((file) => {
        expandSidebar();
        openFile(file);
        close();
    }, [expandSidebar, openFile, close]);
    const handleKeyDown = useCallback((e) => {
        if (e.key === 'ArrowDown' || (e.ctrlKey && e.key === 'j')) {
            e.preventDefault();
            setSelectedIndex((i) => Math.min(i + 1, filtered.length - 1));
        }
        else if (e.key === 'ArrowUp' || (e.ctrlKey && e.key === 'k')) {
            e.preventDefault();
            setSelectedIndex((i) => Math.max(i - 1, 0));
        }
        else if (e.key === 'Enter' && filtered[selectedIndex]) {
            e.preventDefault();
            handleSelect(filtered[selectedIndex]);
        }
        else if (e.key === 'Escape') {
            e.preventDefault();
            close();
        }
    }, [filtered, selectedIndex, handleSelect, close]);
    const handleBackdropClick = useCallback((e) => {
        if (e.target === e.currentTarget)
            close();
    }, [close]);
    if (!isOpen)
        return null;
    return (_jsx("div", { role: "dialog", "aria-modal": "true", className: "fixed inset-0 bg-black/50 flex items-start justify-center z-[60] pt-[15vh]", onClick: handleBackdropClick, onKeyDown: (e) => {
            if (e.key === 'Escape')
                close();
        }, children: _jsxs("div", { className: "bg-background border border-border rounded-lg shadow-2xl w-full max-w-lg overflow-hidden", children: [_jsxs("div", { className: "flex items-center gap-2 px-3 border-b border-border", children: [_jsx(Search, { className: "w-4 h-4 text-muted-foreground flex-shrink-0" }), _jsx("input", { ref: inputRef, type: "text", value: query, onChange: (e) => {
                                setQuery(e.target.value);
                                setSelectedIndex(0);
                            }, onKeyDown: handleKeyDown, placeholder: "Search files by name...", className: "flex-1 bg-transparent py-3 text-sm text-foreground placeholder-muted-foreground outline-none" }), _jsx("kbd", { className: "text-[10px] text-muted-foreground bg-muted px-1.5 py-0.5 rounded border border-border font-mono", children: "ESC" })] }), _jsx("div", { ref: listRef, className: "max-h-[40vh] overflow-y-auto", children: filtered.length === 0 ? (_jsx("div", { className: "px-4 py-8 text-center text-sm text-muted-foreground", children: query ? 'No matching files' : 'No files found' })) : (filtered.map((file, idx) => {
                        const isIgnored = ignoredSet.has(file);
                        return (_jsxs("button", { type: "button", onClick: () => handleSelect(file), className: `w-full text-left flex items-center gap-2 px-3 py-2 text-sm transition-colors ${idx === selectedIndex
                                ? 'bg-accent text-accent-foreground'
                                : 'text-foreground/80 hover:bg-muted/50'} ${isIgnored ? 'opacity-40' : ''}`, children: [_jsx(FileCode, { className: "w-3.5 h-3.5 text-muted-foreground flex-shrink-0" }), _jsx(HighlightedPath, { path: file, query: query }), isIgnored && (_jsx("span", { className: "ml-auto text-[10px] text-muted-foreground italic", children: "ignored" }))] }, file));
                    })) }), filtered.length > 0 && (_jsxs("div", { className: "px-3 py-2 border-t border-border text-xs text-muted-foreground flex items-center gap-3", children: [_jsxs("span", { children: [_jsx("kbd", { className: "bg-muted px-1 py-0.5 rounded border border-border font-mono", children: "\u2191\u2193" }), ' ', "navigate"] }), _jsxs("span", { children: [_jsx("kbd", { className: "bg-muted px-1 py-0.5 rounded border border-border font-mono", children: "\u21B5" }), ' ', "open"] }), _jsxs("span", { className: "ml-auto", children: [filtered.length, " files"] })] }))] }) }));
});
function HighlightedPath({ path, query }) {
    if (!query) {
        return _jsx("span", { className: "truncate font-mono text-xs", children: path });
    }
    const lowerPath = path.toLowerCase();
    const lowerQuery = query.toLowerCase();
    const idx = lowerPath.indexOf(lowerQuery);
    if (idx >= 0) {
        return (_jsxs("span", { className: "truncate font-mono text-xs", children: [path.slice(0, idx), _jsx("span", { className: "text-primary font-semibold", children: path.slice(idx, idx + query.length) }), path.slice(idx + query.length)] }));
    }
    return _jsx("span", { className: "truncate font-mono text-xs", children: path });
}
//# sourceMappingURL=QuickFilePicker.js.map