"use strict";
// src/test_provider_selector_render.ts
// Regression test for the config TUI corruption bug: selectOne's in-place
// redraw (\x1b[{lineCount}A) desyncs when a rendered line exceeds terminal
// width and wraps. Root-cause invariant: NO rendered line may exceed the
// given width, so logical line count == visual line count and cursor-up is exact.
Object.defineProperty(exports, "__esModule", { value: true });
const ProviderSelector_1 = require("./cli/ProviderSelector");
let passed = 0;
let failed = 0;
function check(label, ok, detail) {
    if (ok) {
        console.log(`  ✓ ${label}`);
        passed++;
    }
    else {
        console.error(`  ✗ ${label}${detail ? ` — ${detail}` : ''}`);
        failed++;
    }
}
// Count visible columns, excluding ANSI escape sequences (zero width).
// eslint-disable-next-line no-control-regex
function visibleWidth(s) {
    return s.replace(/\x1b\[[0-9;]*[A-Za-z]/g, '').length;
}
async function main() {
    console.log('test_provider_selector_render: starting\n');
    // The exact shape that broke production: the main config menu, with a long
    // model-name hint that wraps on an 80-col terminal.
    const options = [
        { value: '1', label: 'Provider & Model', hint: 'gemini-api/gemini-3.1-flash-lite-preview' },
        { value: '2', label: 'API Keys', hint: 'openai · anthropic · gemini · openrouter · together · mistral' },
        { value: '3', label: 'Telegram Bot', hint: '·' },
        { value: '4', label: 'Voice / TTS', hint: '' },
        { value: '5', label: 'Daemon', hint: '' },
        { value: '6', label: 'Exit', hint: '' },
    ];
    console.log('[1] no rendered line exceeds the terminal width');
    for (const width of [40, 60, 80, 120]) {
        const block = (0, ProviderSelector_1.renderMenu)('OpenLife Configuration', options, 0, '1', width);
        const lines = block.split('\n');
        const overflow = lines.filter(l => visibleWidth(l) > width);
        check(`width=${width}: every line ≤ ${width} cols`, overflow.length === 0, overflow.length ? `${overflow.length} line(s) overflow; first visible width=${visibleWidth(overflow[0])}` : '');
    }
    console.log('\n[2] logical line count is stable regardless of hint length');
    const narrow = (0, ProviderSelector_1.renderMenu)('OpenLife Configuration', options, 0, '1', 40).split('\n').length;
    const wide = (0, ProviderSelector_1.renderMenu)('OpenLife Configuration', options, 0, '1', 200).split('\n').length;
    check('line count identical across widths', narrow === wide, `narrow=${narrow} wide=${wide}`);
    check('line count = header(3) + items(6) + trailing(1) = 10', narrow === 10, `got ${narrow}`);
    console.log('\n[3] content is preserved (labels still present after clamping)');
    const block = (0, ProviderSelector_1.renderMenu)('OpenLife Configuration', options, 0, '1', 80);
    check('label "Provider & Model" present', block.includes('Provider & Model'));
    check('label "Exit" present', block.includes('Exit'));
    check('title present', block.includes('OpenLife Configuration'));
    console.log('\n[4] cursor arrow renders on the selected row only');
    const b2 = (0, ProviderSelector_1.renderMenu)('t', options, 2, '1', 80);
    const arrowLines = b2.split('\n').filter(l => l.includes('▶'));
    check('exactly one cursor arrow', arrowLines.length === 1, `got ${arrowLines.length}`);
    console.log('');
    console.log(`Results: ${passed} passed, ${failed} failed`);
    if (failed > 0) {
        console.error('TEST_PROVIDER_SELECTOR_RENDER_FAIL');
        process.exit(1);
    }
    console.log('✅ test_provider_selector_render: all checks passed');
}
main().catch(err => { console.error(err); process.exit(1); });
