"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Popover } from "@base-ui/react/popover";
import { cn } from "@stigmer/theme";
import { useStigmerPortalContainer } from "../portal-container.js";
import { useModelRegistry } from "./useModelRegistry.js";
import { HARNESS_META, HARNESS_OPTIONS } from "./harness.js";
const COST_TIER_LABEL = {
    economy: "$",
    standard: "$$",
    premium: "$$$",
};
const SPEED_TIER_LABEL = {
    fastest: "Fastest",
    fast: "Fast",
    balanced: "Balanced",
    slow: "Powerful",
};
/**
 * Combined harness + model picker with a compact trigger button.
 *
 * Shows a harness dropdown at the top of the popover (when not locked
 * to a single harness), followed by a curated model list scoped to
 * the selected harness. Supports search and progressive disclosure
 * via "Show All Models."
 *
 * The trigger button displays the current selection in compact format:
 * `Harness · Model Name ▾` (or just `Model Name ▾` when harness is locked).
 *
 * @example
 * ```tsx
 * <ModelSelector
 *   value={modelId}
 *   onValueChange={setModelId}
 *   harness={harness}
 *   onHarnessChange={setHarness}
 * />
 * ```
 */
export function ModelSelector({ value, onValueChange, harness, initialHarness, onHarnessChange, onHarnessResolved, availableHarnesses, curatedModels, groupBy = "provider", showSpeedBadge = true, showDescriptions = true, compact = false, className, disabled, }) {
    const portalContainer = useStigmerPortalContainer();
    const isHarnessLocked = harness !== undefined;
    const [internalHarness, setInternalHarness] = useState(harness ?? initialHarness ?? "native");
    const activeHarness = harness ?? internalHarness;
    useEffect(() => {
        if (!isHarnessLocked && initialHarness !== undefined) {
            setInternalHarness(initialHarness);
        }
    }, [initialHarness, isHarnessLocked]);
    const { models, featured, defaultModel, getModel, byProvider, isLoading, error, refetch } = useModelRegistry({ harness: activeHarness });
    const [open, setOpen] = useState(false);
    const [harnessOpen, setHarnessOpen] = useState(false);
    const [searchQuery, setSearchQuery] = useState("");
    const [showAll, setShowAll] = useState(false);
    const [highlightIdx, setHighlightIdx] = useState(-1);
    const searchRef = useRef(null);
    const listRef = useRef(null);
    const resolvedHarnesses = useMemo(() => {
        if (availableHarnesses)
            return availableHarnesses;
        // For now, show native and cursor (the two harnesses with models in the registry).
        // Future harnesses will be added to the registry and appear here automatically.
        return HARNESS_OPTIONS.filter((h) => h === "native" || h === "cursor");
    }, [availableHarnesses]);
    const selectedModel = (value ? getModel(value) : undefined) ?? defaultModel ?? undefined;
    const isSearching = searchQuery.length > 0;
    const lowerQuery = searchQuery.toLowerCase();
    const curatedSet = useMemo(() => {
        if (curatedModels)
            return new Set(curatedModels);
        return null;
    }, [curatedModels]);
    const featuredModels = useMemo(() => {
        if (curatedSet) {
            return models.filter((m) => curatedSet.has(m.modelId));
        }
        return featured;
    }, [models, featured, curatedSet]);
    const visibleModels = useMemo(() => {
        if (isSearching) {
            return models.filter((m) => m.displayName.toLowerCase().includes(lowerQuery)
                || m.modelId.toLowerCase().includes(lowerQuery)
                || m.shortDescription.toLowerCase().includes(lowerQuery));
        }
        if (showAll)
            return models;
        return featuredModels.length > 0 ? featuredModels : models;
    }, [models, featuredModels, isSearching, showAll, lowerQuery]);
    const groupedModels = useMemo(() => {
        if (!showAll || groupBy === "none" || isSearching)
            return null;
        const groups = new Map();
        for (const model of models) {
            const key = groupBy === "provider" ? model.provider : model.costTier;
            const group = groups.get(key);
            if (group) {
                group.push(model);
            }
            else {
                groups.set(key, [model]);
            }
        }
        return groups;
    }, [models, showAll, groupBy, isSearching]);
    useEffect(() => {
        setHighlightIdx(-1);
    }, [visibleModels]);
    useEffect(() => {
        if (!open) {
            setSearchQuery("");
            setShowAll(false);
            setHighlightIdx(-1);
            setHarnessOpen(false);
        }
    }, [open]);
    useEffect(() => {
        if (open) {
            requestAnimationFrame(() => searchRef.current?.focus());
        }
    }, [open]);
    const handleHarnessChange = useCallback((newHarness) => {
        setInternalHarness(newHarness);
        onHarnessChange?.(newHarness);
        onHarnessResolved?.(newHarness);
        setShowAll(false);
        setSearchQuery("");
    }, [onHarnessChange, onHarnessResolved]);
    const selectModel = useCallback((model) => {
        onValueChange(model.modelId);
        setOpen(false);
    }, [onValueChange]);
    const scrollHighlightIntoView = useCallback((idx) => {
        const container = listRef.current;
        if (!container)
            return;
        const items = container.querySelectorAll("[data-model-option]");
        items[idx]?.scrollIntoView({ block: "nearest" });
    }, []);
    const handleKeyDown = useCallback((e) => {
        const len = visibleModels.length;
        if (len === 0)
            return;
        switch (e.key) {
            case "ArrowDown": {
                e.preventDefault();
                const next = highlightIdx < len - 1 ? highlightIdx + 1 : 0;
                setHighlightIdx(next);
                scrollHighlightIntoView(next);
                break;
            }
            case "ArrowUp": {
                e.preventDefault();
                const prev = highlightIdx > 0 ? highlightIdx - 1 : len - 1;
                setHighlightIdx(prev);
                scrollHighlightIntoView(prev);
                break;
            }
            case "Enter": {
                e.preventDefault();
                const target = highlightIdx >= 0 ? visibleModels[highlightIdx] : visibleModels[0];
                if (target)
                    selectModel(target);
                break;
            }
            case "Escape":
                e.preventDefault();
                setOpen(false);
                break;
        }
    }, [visibleModels, highlightIdx, selectModel, scrollHighlightIntoView]);
    const showShowAllButton = !isSearching && !showAll && featuredModels.length > 0 && featuredModels.length < models.length;
    const triggerLabel = selectedModel?.displayName ?? "Select model";
    const triggerHarness = !isHarnessLocked ? HARNESS_META[activeHarness].label : undefined;
    return (_jsxs(Popover.Root, { open: open, onOpenChange: setOpen, children: [_jsxs(Popover.Trigger, { disabled: disabled, className: cn("inline-flex items-center gap-1.5 rounded-md border border-border", "bg-background px-2.5 py-1.5 text-xs text-foreground", "hover:bg-accent-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", "disabled:pointer-events-none disabled:opacity-50", "transition-colors max-w-[20rem] max-sm:max-w-[12rem]", className), children: [triggerHarness && (_jsx("span", { className: "shrink-0 text-muted-foreground", children: triggerHarness })), triggerHarness && (_jsx("span", { className: "shrink-0 text-border", "aria-hidden": true, children: "\u00B7" })), _jsx("span", { className: "truncate", children: triggerLabel }), _jsx(ChevronIcon, {})] }), _jsx(Popover.Portal, { container: portalContainer, children: _jsx(Popover.Positioner, { sideOffset: 4, children: _jsxs(Popover.Popup, { role: "dialog", "aria-label": "Model selector", className: cn("z-popover w-72 rounded-lg border border-border bg-popover shadow-md", "text-popover-foreground"), children: [_jsxs("div", { className: "relative flex items-center justify-between border-b border-border px-3 py-2", children: [_jsx("span", { className: "text-xs text-muted-foreground", children: "Harness" }), _jsxs("button", { type: "button", "aria-haspopup": "listbox", "aria-expanded": harnessOpen, "aria-label": "Select harness", disabled: isHarnessLocked, className: cn("inline-flex items-center gap-1.5 rounded-md border border-border", "bg-background px-2.5 py-1.5 text-xs text-foreground", "transition-colors", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", isHarnessLocked
                                            ? "cursor-not-allowed opacity-50"
                                            : "hover:bg-accent-hover"), onClick: () => {
                                            if (!isHarnessLocked)
                                                setHarnessOpen(!harnessOpen);
                                        }, onKeyDown: (e) => {
                                            if (e.key === "Escape" && harnessOpen) {
                                                e.stopPropagation();
                                                setHarnessOpen(false);
                                            }
                                        }, children: [_jsx("span", { children: HARNESS_META[activeHarness].label }), !isHarnessLocked && _jsx(ChevronIcon, {})] }), !isHarnessLocked && harnessOpen && (_jsx("div", { role: "listbox", "aria-label": "Available harnesses", className: cn("absolute right-3 top-full z-10 mt-1 overflow-hidden rounded-md border border-border", "bg-popover shadow-md"), children: resolvedHarnesses.map((h) => {
                                            const isActive = h === activeHarness;
                                            return (_jsxs("button", { type: "button", role: "option", "aria-selected": isActive, className: cn("flex w-full items-center gap-2 px-2.5 py-1.5 text-xs transition-colors", "hover:bg-accent-hover", isActive && "font-medium"), onClick: () => {
                                                    handleHarnessChange(h);
                                                    setHarnessOpen(false);
                                                }, children: [_jsx("span", { className: "flex-1 text-left", children: HARNESS_META[h].label }), isActive && _jsx(CheckIcon, { className: "shrink-0 text-primary" })] }, h));
                                        }) }))] }), _jsx("div", { className: "border-b border-border px-3 py-1.5", children: _jsx("input", { ref: searchRef, role: "searchbox", "aria-label": "Search models", placeholder: "Search models\u2026", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), onKeyDown: handleKeyDown, className: cn("w-full bg-transparent text-xs text-foreground placeholder:text-muted-foreground", "outline-none") }) }), _jsxs("div", { ref: listRef, role: "listbox", "aria-label": "Available models", className: "max-h-72 overflow-y-auto p-1", children: [visibleModels.length === 0 && isLoading && (_jsxs("div", { className: "flex items-center justify-center gap-2 px-2 py-3", children: [_jsx("div", { className: "size-3 animate-spin rounded-full border border-muted border-t-primary" }), _jsx("span", { className: "text-xs text-muted-foreground", children: "Loading models\u2026" })] })), visibleModels.length === 0 && !isLoading && error != null && (_jsxs("div", { className: "flex flex-col items-center gap-1.5 px-2 py-3", children: [_jsx("span", { className: "text-xs text-muted-foreground", children: "Failed to load models" }), _jsx("button", { type: "button", className: cn("rounded-md border border-border bg-background px-2.5 py-1 text-xs text-foreground", "hover:bg-accent-hover transition-colors cursor-pointer"), onClick: refetch, children: "Retry" })] })), visibleModels.length === 0 && !isLoading && error == null && (_jsx("div", { className: "px-2 py-3 text-center text-xs text-muted-foreground", children: "No models found" })), groupedModels ? (Array.from(groupedModels.entries()).map(([group, groupModels]) => (_jsxs("div", { children: [_jsx("div", { className: "px-2 pb-0.5 pt-2 text-[0.6rem] font-medium uppercase tracking-wider text-muted-foreground", children: group }), groupModels.map((model) => (_jsx(ModelRow, { model: model, isSelected: model.modelId === selectedModel?.modelId, showDescription: false, showSpeedBadge: showSpeedBadge, onClick: () => selectModel(model) }, model.modelId)))] }, group)))) : (visibleModels.map((model, idx) => (_jsx(ModelRow, { model: model, isSelected: model.modelId === selectedModel?.modelId, isHighlighted: idx === highlightIdx, showDescription: showDescriptions && !compact && !isSearching && !showAll, showSpeedBadge: showSpeedBadge, onClick: () => selectModel(model), onMouseEnter: () => setHighlightIdx(idx) }, model.modelId)))), showShowAllButton && (_jsx("button", { type: "button", className: cn("mt-1 flex w-full items-center justify-center rounded-md border border-dashed border-border", "px-2 py-1.5 text-xs text-muted-foreground", "hover:bg-accent-hover hover:text-foreground transition-colors cursor-pointer"), onClick: () => setShowAll(true), children: "Show all models" }))] })] }) }) })] }));
}
function ModelRow({ model, isSelected, isHighlighted, showDescription, showSpeedBadge, onClick, onMouseEnter, }) {
    return (_jsxs("button", { "data-model-option": "", role: "option", "aria-selected": isSelected, type: "button", className: cn("flex w-full cursor-pointer flex-col rounded-md px-2 py-1.5 text-xs outline-none", "transition-colors", isHighlighted && "bg-accent text-accent-foreground", !isHighlighted && "hover:bg-accent-hover"), onClick: onClick, onMouseEnter: onMouseEnter, children: [_jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx("span", { className: "flex-1 truncate text-left font-medium", children: model.displayName }), _jsx("span", { className: "shrink-0 text-[0.6rem] text-muted-foreground", children: showSpeedBadge
                            ? `${SPEED_TIER_LABEL[model.speedTier]} ${COST_TIER_LABEL[model.costTier]}`
                            : COST_TIER_LABEL[model.costTier] }), isSelected && _jsx(CheckIcon, { className: "shrink-0 text-primary" })] }), showDescription && model.shortDescription && (_jsx("span", { className: "mt-0.5 block text-left text-[0.65rem] text-muted-foreground", children: model.shortDescription }))] }));
}
function ChevronIcon() {
    return (_jsx("svg", { className: "shrink-0 text-muted-foreground", width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("path", { d: "M2.5 3.75L5 6.25L7.5 3.75" }) }));
}
function CheckIcon({ className }) {
    return (_jsx("svg", { className: className, width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("path", { d: "M2 6L5 9L10 3" }) }));
}
//# sourceMappingURL=ModelSelector.js.map