import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Box, Text } from "ink";
import { padRightCells, truncateCells } from "./textLayout.js";
import { toneColor } from "./terminalTheme.js";
export function clampSelectIndex(options, selectedIndex) {
    if (options.length === 0)
        return -1;
    const requested = selectedIndex ?? options.findIndex((option) => option.selected);
    const fallback = options.findIndex((option) => !option.disabled);
    const clamped = requested < 0 ? fallback : Math.min(options.length - 1, requested);
    if (clamped < 0)
        return 0;
    if (!options[clamped]?.disabled)
        return clamped;
    return fallback >= 0 ? fallback : clamped;
}
export function selectListWindow(input) {
    const count = Math.max(0, input.count);
    const visible = Math.max(1, input.visibleCount);
    if (count <= visible)
        return { start: 0, end: count };
    const half = Math.floor(visible / 2);
    const start = Math.max(0, Math.min(input.selectedIndex - half, count - visible));
    return { start, end: start + visible };
}
export function buildSelectListRows(input) {
    const selectedIndex = clampSelectIndex(input.options, input.selectedIndex);
    const window = selectListWindow({
        count: input.options.length,
        selectedIndex,
        visibleCount: input.visibleCount ?? 6,
    });
    const maxIndexWidth = String(input.options.length).length;
    return input.options.slice(window.start, window.end).map((option, offset) => {
        const absoluteIndex = window.start + offset;
        const focused = absoluteIndex === selectedIndex;
        const selected = option.selected ?? focused;
        const hasMoreAbove = window.start > 0 && offset === 0;
        const hasMoreBelow = window.end < input.options.length && offset === window.end - window.start - 1;
        return {
            id: option.id,
            label: option.label,
            detail: option.detail ?? "",
            description: option.description ?? "",
            indexLabel: input.hideIndexes ? "" : `${absoluteIndex + 1}.`.padEnd(maxIndexWidth + 1),
            indicator: focused ? ">" : hasMoreAbove ? "^" : hasMoreBelow ? "v" : " ",
            marker: selected ? "[x]" : "   ",
            focused,
            disabled: option.disabled ?? false,
            tone: option.disabled ? "muted" : option.tone ?? (focused ? "brand" : "default"),
        };
    });
}
export function SelectList(props) {
    const rows = buildSelectListRows(props);
    const width = props.width ?? 96;
    const labelWidth = Math.max(12, Math.min(28, Math.floor(width * 0.28)));
    const detailWidth = Math.max(18, width - labelWidth - 12);
    if (rows.length === 0) {
        return _jsx(Text, { color: "gray", children: "No options" });
    }
    return (_jsx(Box, { flexDirection: "column", children: rows.map((row) => (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: toneColor(row.tone), inverse: row.focused, dimColor: row.disabled, children: row.indicator }), _jsxs(Text, { color: "gray", children: [" ", row.indexLabel] }), _jsx(Text, { color: toneColor(row.tone), dimColor: row.disabled, children: padRightCells(row.label, labelWidth) }), _jsx(Text, { color: toneColor(row.focused ? "success" : "muted"), dimColor: row.disabled, children: ` ${row.marker} ` }), _jsx(Text, { color: "gray", children: truncateCells(row.detail, detailWidth) })] }), row.description ? (_jsx(Box, { paddingLeft: 4, children: _jsx(Text, { color: "gray", children: truncateCells(row.description, Math.max(18, width - 6)) }) })) : null] }, row.id))) }));
}
