import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Box, Text, useInput } from 'ink';
import SelectInput from 'ink-select-input';
import { useMemo, useState } from 'react';
import { StyledSelectInput } from '../../components/ui/styled-select-input.js';
import { TitledBoxWithPreferences } from '../../components/ui/titled-box.js';
import { useResponsiveTerminal } from '../../hooks/useTerminalWidth.js';
import { useTheme } from '../../hooks/useTheme.js';
import { TOOL_PROFILE_DESCRIPTIONS, TOOL_PROFILE_TOOLTIPS, } from '../../tools/tool-profiles.js';
import { getTuneToolMode, TUNE_DEFAULTS } from '../../types/config.js';
const AVAILABLE_PROFILES = ['auto', 'full', 'minimal', 'nano'];
const TOOL_MODE_CYCLE = ['native', 'xml', 'json'];
function nextToolMode(current) {
    const idx = TOOL_MODE_CYCLE.indexOf(current);
    return TOOL_MODE_CYCLE[(idx + 1) % TOOL_MODE_CYCLE.length];
}
function toolModeLabel(mode) {
    if (mode === 'native')
        return 'ON';
    if (mode === 'xml')
        return 'OFF (XML fallback)';
    return 'OFF (JSON fallback)';
}
const TUNE_PRESETS = [
    {
        name: 'Default',
        description: 'Reset all settings to defaults',
        config: { ...TUNE_DEFAULTS },
    },
    {
        name: 'Small Model',
        description: 'Optimised for 1B-8B models — minimal tools, slim prompt, single-tool, aggressive compact',
        config: {
            enabled: true,
            toolProfile: 'minimal',
            aggressiveCompact: true,
            modelParameters: { temperature: 0.7 },
        },
    },
    {
        name: 'Nano (low-end hardware)',
        description: 'Strictest budget — 5 tools, ultra-slim prompt, single-tool, aggressive compact, no AGENTS.md. Run bigger models on smaller machines.',
        config: {
            enabled: true,
            toolProfile: 'nano',
            aggressiveCompact: true,
            includeAgentsMd: false,
            modelParameters: { temperature: 0.4, maxTokens: 2048 },
        },
    },
];
// Main model mode menu
function TuneMainMenu({ config, onAction, onCancel, }) {
    const { colors } = useTheme();
    const { boxWidth, isNarrow } = useResponsiveTerminal();
    const items = useMemo(() => {
        const list = [
            {
                label: config.enabled ? 'Tune - Enabled' : 'Tune - Disabled',
                value: 'toggle',
            },
            {
                label: 'Load Preset',
                value: 'preset',
            },
        ];
        if (config.enabled) {
            // includeAgentsMd defaults to false for nano, true otherwise.
            const agentsMdOn = config.includeAgentsMd ?? config.toolProfile !== 'nano';
            list.push({
                label: `Tool Profile - ${config.toolProfile}`,
                value: 'toolProfile',
            }, {
                label: `Aggressive Compact - ${config.aggressiveCompact ? 'ON' : 'OFF'}`,
                value: 'aggressiveCompact',
            }, {
                label: `Native Tool Calling - ${toolModeLabel(getTuneToolMode(config))}`,
                value: 'toolMode',
            }, {
                label: `Include AGENTS.md - ${agentsMdOn ? 'ON' : 'OFF'}`,
                value: 'includeAgentsMd',
            }, {
                label: `Model Parameters - ${config.modelParameters ? 'configured' : 'defaults'}`,
                value: 'parameters',
            });
        }
        list.push({ label: 'Apply & Close', value: 'apply' });
        return list;
    }, [config]);
    useInput((_input, key) => {
        if (key.escape) {
            onCancel();
        }
    });
    // Narrow terminal: simplified layout
    if (isNarrow) {
        return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, borderStyle: "round", borderColor: colors.primary, paddingY: 1, paddingX: 2, width: "100%", children: [_jsx(Text, { color: colors.primary, bold: true, children: "Tune" }), _jsx(Text, { color: colors.text, children: " " }), _jsx(StyledSelectInput, { items: items, onSelect: item => onAction(item.value) }), _jsx(Box, { marginBottom: 1 }), _jsx(Text, { color: colors.secondary, children: "Enter/Esc" })] }));
    }
    return (_jsxs(TitledBoxWithPreferences, { title: "Tune", width: boxWidth, borderColor: colors.primary, paddingX: 2, paddingY: 1, flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: colors.secondary, children: "Configure runtime behavior for different model capabilities:" }) }), _jsx(StyledSelectInput, { items: items, onSelect: item => onAction(item.value) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.secondary, children: "Enter to select, Esc to cancel" }) })] }));
}
// Tool profile sub-panel
function ToolProfilePanel({ currentProfile, onSelect, onBack, onCancel, }) {
    const { colors } = useTheme();
    const { boxWidth, isNarrow } = useResponsiveTerminal();
    const [highlighted, setHighlighted] = useState(currentProfile);
    const items = useMemo(() => AVAILABLE_PROFILES.map(p => ({
        label: isNarrow
            ? p + (p === currentProfile ? ' *' : '')
            : `${p} - ${TOOL_PROFILE_DESCRIPTIONS[p]}${p === currentProfile ? ' (current)' : ''}`,
        value: p,
    })), [currentProfile, isNarrow]);
    const initialIndex = useMemo(() => {
        const index = AVAILABLE_PROFILES.indexOf(currentProfile);
        return index >= 0 ? index : 0;
    }, [currentProfile]);
    useInput((_, key) => {
        if (key.escape) {
            onCancel();
        }
        if (key.shift && key.tab) {
            onBack();
        }
    });
    // Narrow terminal: simplified layout
    if (isNarrow) {
        return (_jsxs(TitledBoxWithPreferences, { title: "Tool Profile", width: "100%", borderColor: colors.primary, paddingX: 2, paddingY: 1, flexDirection: "column", marginBottom: 1, children: [_jsx(SelectInput, { items: items, initialIndex: initialIndex, onSelect: item => onSelect(item.value), onHighlight: item => setHighlighted(item.value) }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(Text, { color: colors.secondary, children: TOOL_PROFILE_TOOLTIPS[highlighted] }) }), _jsx(Box, { marginBottom: 1 }), _jsx(Text, { color: colors.secondary, children: "Enter/Shift+Tab/Esc" })] }));
    }
    return (_jsxs(TitledBoxWithPreferences, { title: "Choose a tool profile", width: boxWidth, borderColor: colors.primary, paddingX: 2, paddingY: 1, flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: colors.secondary, children: "Enter to apply, Shift+Tab to go back, Esc to cancel" }) }), _jsx(StyledSelectInput, { items: items, initialIndex: initialIndex, onSelect: item => onSelect(item.value), onHighlight: item => setHighlighted(item.value) }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(Text, { color: colors.secondary, children: TOOL_PROFILE_TOOLTIPS[highlighted] }) })] }));
}
// Preset sub-panel
function PresetPanel({ onSelect, onBack, onCancel, }) {
    const { colors } = useTheme();
    const { boxWidth, isNarrow } = useResponsiveTerminal();
    const [highlighted, setHighlighted] = useState(0);
    const items = useMemo(() => TUNE_PRESETS.map((preset, i) => ({
        label: isNarrow
            ? preset.name
            : `${preset.name} - ${preset.description}`,
        value: String(i),
    })), [isNarrow]);
    useInput((_input, key) => {
        if (key.escape) {
            onCancel();
        }
        if (key.shift && key.tab) {
            onBack();
        }
    });
    const highlightedPreset = TUNE_PRESETS[highlighted];
    if (isNarrow) {
        return (_jsxs(TitledBoxWithPreferences, { title: "Presets", width: "100%", borderColor: colors.primary, paddingX: 2, paddingY: 1, flexDirection: "column", marginBottom: 1, children: [_jsx(SelectInput, { items: items, onSelect: item => onSelect(TUNE_PRESETS[Number(item.value)]?.config), onHighlight: item => setHighlighted(Number(item.value)) }), highlightedPreset && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.secondary, children: highlightedPreset.description }) })), _jsx(Box, { marginBottom: 1 }), _jsx(Text, { color: colors.secondary, children: "Enter/Shift+Tab/Esc" })] }));
    }
    return (_jsxs(TitledBoxWithPreferences, { title: "Load a preset", width: boxWidth, borderColor: colors.primary, paddingX: 2, paddingY: 1, flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: colors.secondary, children: "Enter to load preset, Shift+Tab to go back, Esc to cancel" }) }), _jsx(StyledSelectInput, { items: items, onSelect: item => onSelect(TUNE_PRESETS[Number(item.value)]?.config), onHighlight: item => setHighlighted(Number(item.value)) }), highlightedPreset && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.secondary, children: highlightedPreset.description }) }))] }));
}
const PARAM_DEFS = [
    {
        key: 'temperature',
        label: 'Temperature',
        tooltip: 'Controls randomness. Lower = more focused, higher = more creative.',
        min: 0.1,
        max: 2,
        step: 0.1,
    },
    {
        key: 'topP',
        label: 'Top P',
        tooltip: 'Nucleus sampling. Lower = fewer token choices considered.',
        min: 0,
        max: 1,
        step: 0.05,
    },
    {
        key: 'topK',
        label: 'Top K',
        tooltip: 'Limits token choices to top K candidates. Lower = more deterministic.',
        min: 1,
        max: 200,
        step: 1,
    },
    {
        key: 'maxTokens',
        label: 'Max Tokens',
        tooltip: 'Maximum response length. Useful for limiting verbose models or reducing costs.',
        min: 64,
        max: 32768,
        step: 256,
    },
    {
        key: 'frequencyPenalty',
        label: 'Frequency Penalty',
        tooltip: 'Penalises repeated tokens. Higher = less repetition.',
        min: -2,
        max: 2,
        step: 0.1,
    },
    {
        key: 'presencePenalty',
        label: 'Presence Penalty',
        tooltip: 'Penalises tokens already used. Higher = more topic diversity.',
        min: -2,
        max: 2,
        step: 0.1,
    },
];
// Model parameters sub-panel
function ParametersPanel({ currentParams, onApply, onBack, onCancel, }) {
    const { colors } = useTheme();
    const { boxWidth, isNarrow } = useResponsiveTerminal();
    // Local state so changes don't close the panel
    const [params, setParams] = useState(currentParams ? { ...currentParams } : undefined);
    const items = useMemo(() => {
        const fmtValue = (value) => {
            if (value === undefined)
                return 'default';
            if (Array.isArray(value))
                return value.join(', ');
            return String(value);
        };
        const list = PARAM_DEFS.map(def => ({
            label: `${def.label} - ${fmtValue(params?.[def.key])}`,
            value: def.key,
        }));
        list.push({ label: 'Reset All to Defaults', value: 'reset' }, { label: 'Done', value: 'done' });
        return list;
    }, [params]);
    const [highlighted, setHighlighted] = useState('temperature');
    const highlightedDef = PARAM_DEFS.find(d => d.key === highlighted);
    useInput((_input, key) => {
        if (key.escape) {
            onCancel();
        }
        if (key.shift && key.tab) {
            onApply(params);
            onBack();
        }
    });
    const handleSelect = (item) => {
        if (item.value === 'done') {
            onApply(params);
            onBack();
            return;
        }
        if (item.value === 'reset') {
            setParams(undefined);
            return;
        }
        // Cycle through values for the selected parameter
        const def = PARAM_DEFS.find(d => d.key === item.value);
        if (!def)
            return;
        const currentValue = params?.[def.key];
        let nextValue;
        if (currentValue === undefined) {
            // Start from a sensible default
            nextValue =
                def.key === 'temperature'
                    ? 0.7
                    : def.key === 'topP'
                        ? 0.9
                        : def.key === 'topK'
                            ? 40
                            : def.key === 'maxTokens'
                                ? 4096
                                : 0;
        }
        else {
            // Increment, wrap to undefined (default) after max
            const stepped = Math.round((currentValue + def.step) * 100) / 100;
            nextValue = stepped > def.max ? undefined : stepped;
        }
        setParams(prev => ({
            ...prev,
            [def.key]: nextValue,
        }));
    };
    if (isNarrow) {
        return (_jsxs(TitledBoxWithPreferences, { title: "Parameters", width: "100%", borderColor: colors.primary, paddingX: 2, paddingY: 1, flexDirection: "column", marginBottom: 1, children: [_jsx(SelectInput, { items: items, onSelect: handleSelect, onHighlight: item => setHighlighted(item.value) }), highlightedDef && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.secondary, children: highlightedDef.tooltip }) })), _jsx(Box, { marginBottom: 1 }), _jsx(Text, { color: colors.secondary, children: "Enter to cycle/Shift+Tab/Esc" })] }));
    }
    return (_jsxs(TitledBoxWithPreferences, { title: "Model Parameters", width: boxWidth, borderColor: colors.primary, paddingX: 2, paddingY: 1, flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: colors.secondary, children: "Enter to cycle values, Shift+Tab to go back, Esc to cancel" }) }), _jsx(StyledSelectInput, { items: items, onSelect: handleSelect, onHighlight: item => setHighlighted(item.value) }), highlightedDef && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.secondary, children: highlightedDef.tooltip }) }))] }));
}
// Main tune selector with step navigation
export function TuneSelector({ currentConfig, onSelect, onCancel, }) {
    const [step, setStep] = useState('main');
    const [config, setConfig] = useState({ ...currentConfig });
    const handleMainAction = (action) => {
        switch (action) {
            case 'toggle':
                setConfig(prev => ({
                    ...(prev.enabled ? TUNE_DEFAULTS : prev),
                    enabled: !prev.enabled,
                }));
                break;
            case 'preset':
                setStep('preset');
                break;
            case 'toolProfile':
                setStep('toolProfile');
                break;
            case 'aggressiveCompact':
                setConfig(prev => ({
                    ...prev,
                    aggressiveCompact: !prev.aggressiveCompact,
                }));
                break;
            case 'toolMode':
                setConfig(prev => {
                    const next = nextToolMode(getTuneToolMode(prev));
                    // Drop the legacy disableNativeTools field once the user has
                    // explicitly cycled — toolMode is now authoritative.
                    const { disableNativeTools: _legacy, ...rest } = prev;
                    return { ...rest, toolMode: next };
                });
                break;
            case 'includeAgentsMd':
                setConfig(prev => {
                    // Determine current effective value (defaults to false for nano, true otherwise).
                    const current = prev.includeAgentsMd ?? prev.toolProfile !== 'nano';
                    return { ...prev, includeAgentsMd: !current };
                });
                break;
            case 'parameters':
                setStep('parameters');
                break;
            case 'apply':
                onSelect(config);
                break;
        }
    };
    switch (step) {
        case 'main':
            return (_jsx(TuneMainMenu, { config: config, onAction: handleMainAction, onCancel: onCancel }));
        case 'toolProfile':
            return (_jsx(ToolProfilePanel, { currentProfile: config.toolProfile, onSelect: profile => {
                    setConfig(prev => ({ ...prev, toolProfile: profile }));
                    setStep('main');
                }, onBack: () => setStep('main'), onCancel: onCancel }));
        case 'parameters':
            return (_jsx(ParametersPanel, { currentParams: config.modelParameters, onApply: params => {
                    setConfig(prev => ({ ...prev, modelParameters: params }));
                    setStep('main');
                }, onBack: () => setStep('main'), onCancel: onCancel }));
        case 'preset':
            return (_jsx(PresetPanel, { onSelect: presetConfig => {
                    setConfig({ ...presetConfig });
                    setStep('main');
                }, onBack: () => setStep('main'), onCancel: onCancel }));
    }
}
//# sourceMappingURL=tune-selector.js.map