import { jsx, jsxs } from "react/jsx-runtime";
import ShieldOutlined from "@mui/icons-material/ShieldOutlined";
import Box from "@mui/material/Box";
import { useVirtualizer } from "@tanstack/react-virtual";
import react, { useEffect, useMemo, useRef } from "react";
import { GROUP_LABELS } from "../i18n.js";
import { GroupHeader } from "./GroupHeader.js";
import { DENSE_OPTION_HEIGHT, FULL_OPTION_HEIGHT, ModelOptionRow } from "./ModelOptionRow.js";
const BYO_GROUP_KEY = 'byo';
const DEFAULT_LIST_MAX_HEIGHT = 362;
function groupLeadingIcon(groupKey) {
    if (groupKey === BYO_GROUP_KEY) return /*#__PURE__*/ jsx(ShieldOutlined, {
        sx: {
            fontSize: 14
        }
    });
    return null;
}
const GROUP_HINT_DESCRIPTORS = {
    recommended: GROUP_LABELS.recommendedHint,
    preview: GROUP_LABELS.previewHint,
    byo: GROUP_LABELS.byoHint,
    more: GROUP_LABELS.moreHint,
    deprecating: GROUP_LABELS.deprecatingHint
};
function groupHint(groupKey, i18n) {
    const desc = GROUP_HINT_DESCRIPTORS[groupKey];
    if (!desc) return;
    return i18n ? i18n._(desc) : desc.message;
}
function countLabel(n, i18n) {
    if (null == n || !i18n) return;
    return 1 === n ? i18n._({
        id: 'modelPicker.count.one',
        message: '{n} model',
        values: {
            n
        }
    }) : i18n._({
        id: 'modelPicker.count.many',
        message: '{n} models',
        values: {
            n
        }
    });
}
function optionDomId(listboxId, modelId) {
    const safe = modelId.replace(/[^A-Za-z0-9_-]/g, '-');
    return `${listboxId}-opt-${safe}`;
}
const GroupedOptionList = ({ id, options, activeIndex, setActiveIndex, selectedId, onSelect, tagContext, tagVariants, groupCounts, renderRowActions, renderRowMeta, dense, maxHeight = DEFAULT_LIST_MAX_HEIGHT, hideGroupHeaders, hideTagKinds, collapsedGroups, onGroupToggle, 'aria-label': ariaLabel = 'Models' })=>{
    let lastGroupKey;
    let headerCount = 0;
    const derivedCounts = useMemo(()=>{
        if (groupCounts) return groupCounts;
        const out = {};
        for (const o of options)out[o.groupKey] = (out[o.groupKey] ?? 0) + 1;
        return out;
    }, [
        groupCounts,
        options
    ]);
    return /*#__PURE__*/ jsx(Box, {
        role: "listbox",
        id: id,
        "aria-label": ariaLabel,
        sx: {
            maxHeight,
            overflowY: 'auto',
            py: 0.5
        },
        children: options.map((opt, i)=>{
            const showHeader = !hideGroupHeaders && opt.groupKey !== lastGroupKey;
            const isFirstHeader = showHeader && 0 === headerCount;
            if (showHeader) headerCount += 1;
            lastGroupKey = opt.groupKey;
            const isCollapsible = opt.groupKey === BYO_GROUP_KEY;
            const isCollapsed = isCollapsible && (collapsedGroups?.has(opt.groupKey) ?? false);
            return /*#__PURE__*/ jsxs(react.Fragment, {
                children: [
                    showHeader && /*#__PURE__*/ jsx(GroupHeader, {
                        label: opt.groupLabel,
                        hint: groupHint(opt.groupKey, tagContext?.i18n),
                        count: derivedCounts[opt.groupKey],
                        countLabel: countLabel(derivedCounts[opt.groupKey], tagContext?.i18n),
                        dense: dense,
                        isFirst: isFirstHeader,
                        leadingIcon: groupLeadingIcon(opt.groupKey),
                        collapsible: isCollapsible,
                        collapsed: isCollapsed,
                        onToggle: isCollapsible ? ()=>onGroupToggle?.(opt.groupKey) : void 0
                    }),
                    !isCollapsed && /*#__PURE__*/ jsx(ModelOptionRow, {
                        id: optionDomId(id, opt.modelId),
                        model: opt,
                        index: i,
                        active: i === activeIndex,
                        selected: opt.modelId === selectedId,
                        onSelect: onSelect,
                        onActivate: setActiveIndex,
                        tagContext: tagContext,
                        tagVariants: tagVariants,
                        hideTagKinds: hideTagKinds,
                        renderMeta: renderRowMeta,
                        renderActions: renderRowActions,
                        dense: dense
                    })
                ]
            }, opt.modelId);
        })
    });
};
const VirtualOptionList = ({ id, options, activeIndex, setActiveIndex, selectedId, onSelect, tagContext, tagVariants, groupCounts, renderRowActions, renderRowMeta, dense, maxHeight = DEFAULT_LIST_MAX_HEIGHT, hideGroupHeaders, hideTagKinds, collapsedGroups, onGroupToggle, 'aria-label': ariaLabel = 'Models' })=>{
    const rows = useMemo(()=>{
        const out = [];
        let lastGroupKey;
        let headerCount = 0;
        const counts = groupCounts ?? {};
        if (!groupCounts) for (const o of options)counts[o.groupKey] = (counts[o.groupKey] ?? 0) + 1;
        options.forEach((opt, i)=>{
            const collapsed = collapsedGroups?.has(opt.groupKey) ?? false;
            if (!hideGroupHeaders && opt.groupKey !== lastGroupKey) {
                out.push({
                    kind: 'header',
                    key: `h-${opt.groupKey}`,
                    groupKey: opt.groupKey,
                    label: opt.groupLabel,
                    isFirst: 0 === headerCount,
                    count: counts[opt.groupKey] ?? 0
                });
                headerCount += 1;
            }
            lastGroupKey = opt.groupKey;
            if (!collapsed) out.push({
                kind: 'option',
                key: opt.modelId,
                model: opt,
                index: i
            });
        });
        return out;
    }, [
        options,
        hideGroupHeaders,
        groupCounts,
        collapsedGroups
    ]);
    const headerHeight = dense ? 32 : 48;
    const optionHeight = dense ? DENSE_OPTION_HEIGHT : FULL_OPTION_HEIGHT;
    const parentRef = useRef(null);
    const virtualizer = useVirtualizer({
        count: rows.length,
        getScrollElement: ()=>parentRef.current,
        estimateSize: (i)=>rows[i]?.kind === 'header' ? headerHeight : optionHeight,
        overscan: 10
    });
    useEffect(()=>{
        const rowIdx = rows.findIndex((r)=>'option' === r.kind && r.index === activeIndex);
        if (rowIdx >= 0) virtualizer.scrollToIndex(rowIdx, {
            align: 'auto'
        });
    }, [
        activeIndex,
        rows,
        virtualizer
    ]);
    return /*#__PURE__*/ jsx(Box, {
        ref: parentRef,
        role: "listbox",
        id: id,
        "aria-label": ariaLabel,
        sx: {
            maxHeight,
            overflowY: 'auto',
            py: 0.5,
            position: 'relative'
        },
        children: /*#__PURE__*/ jsx(Box, {
            sx: {
                height: virtualizer.getTotalSize(),
                width: '100%',
                position: 'relative'
            },
            children: virtualizer.getVirtualItems().map((vi)=>{
                const row = rows[vi.index];
                if (!row) return null;
                const baseStyle = {
                    position: 'absolute',
                    top: 0,
                    left: 0,
                    width: '100%',
                    transform: `translateY(${vi.start}px)`
                };
                if ('header' === row.kind) {
                    const isCollapsible = row.groupKey === BYO_GROUP_KEY;
                    const isCollapsed = isCollapsible && (collapsedGroups?.has(row.groupKey) ?? false);
                    return /*#__PURE__*/ jsx("div", {
                        style: baseStyle,
                        children: /*#__PURE__*/ jsx(GroupHeader, {
                            label: row.label,
                            hint: groupHint(row.groupKey, tagContext?.i18n),
                            count: row.count,
                            countLabel: countLabel(row.count, tagContext?.i18n),
                            dense: dense,
                            isFirst: row.isFirst,
                            leadingIcon: groupLeadingIcon(row.groupKey),
                            collapsible: isCollapsible,
                            collapsed: isCollapsed,
                            onToggle: isCollapsible ? ()=>onGroupToggle?.(row.groupKey) : void 0
                        })
                    }, row.key);
                }
                return /*#__PURE__*/ jsx("div", {
                    style: baseStyle,
                    children: /*#__PURE__*/ jsx(ModelOptionRow, {
                        id: optionDomId(id, row.model.modelId),
                        model: row.model,
                        index: row.index,
                        active: row.index === activeIndex,
                        selected: row.model.modelId === selectedId,
                        onSelect: onSelect,
                        onActivate: setActiveIndex,
                        tagContext: tagContext,
                        tagVariants: tagVariants,
                        hideTagKinds: hideTagKinds,
                        renderMeta: renderRowMeta,
                        renderActions: renderRowActions,
                        dense: dense
                    })
                }, row.key);
            })
        })
    });
};
export { GroupedOptionList, VirtualOptionList, optionDomId };
