/**
 * Excel-specific approval component.
 *
 * Renders a diff table (Address | Before | After | Detail) with
 * an ApprovalButtonBar for Accept / Accept All / Reject.
 *
 * Display logic lives in GridTable (grid-table.ts) and the
 * DIFF_COLUMNS definitions below. ExcelApprovalComponent is pure composition.
 */
import { Container, getEditorKeybindings, Spacer, Text, truncateToWidth } from '../../tui/index.js';
import { parseMouseWheelDelta } from '../../tui/keys.js';
import { DEFAULT_GRID_VISIBLE_ROWS, GridTable } from '../components/primitives/grid-table.js';
import { ApprovalButtonBar, Border } from './approval.js';
// ---------------------------------------------------------------------------
// DiffCell column definitions
// ---------------------------------------------------------------------------
const DIFF_COLUMNS = [
    {
        header: 'Address',
        minWidth: 7,
        maxWidth: 24,
        width: (c) => String(c.address).length,
        render: (c, w, isCursor, theme) => theme.fg(isCursor ? 'accent' : 'text', truncateToWidth(String(c.address), w, '..', true))
    },
    {
        header: 'Before',
        minWidth: 6,
        maxWidth: 16,
        width: (c) => String(c.before).length,
        render: (c, w, _isCursor, theme) => theme.fg(c.before !== 'empty' ? 'error' : 'dim', truncateToWidth(String(c.before), w, '..', true))
    },
    {
        header: 'After',
        minWidth: 5,
        maxWidth: 16,
        width: (c) => String(c.after).length,
        render: (c, w, _isCursor, theme) => theme.fg('accent', truncateToWidth(String(c.after), w, '..', true))
    },
    {
        header: 'Detail',
        minWidth: 9,
        maxWidth: 30,
        width: (c) => (c.formula || c.oldFormula || '').length,
        render: (c, w, _isCursor, theme) => {
            if (c.formula)
                return truncateToWidth(c.formula, w, '..', true);
            if (c.oldFormula)
                return theme.fg('dim', truncateToWidth(c.oldFormula, w, '..', true));
            return theme.fg('dim', 'hardcoded');
        }
    }
];
// ---------------------------------------------------------------------------
// Excel approval component (pure composition)
// ---------------------------------------------------------------------------
export class ExcelApprovalComponent extends Container {
    grid;
    buttonBar;
    onDone;
    terminal;
    payload;
    theme;
    queueInfo;
    lastVisibleRows = DEFAULT_GRID_VISIBLE_ROWS;
    constructor(payload, theme, onDone, queueInfo, terminal) {
        super();
        this.onDone = onDone;
        this.payload = payload;
        this.theme = theme;
        this.queueInfo = queueInfo;
        this.terminal = terminal && 'terminal' in terminal ? terminal.terminal : terminal;
        this.rebuild();
    }
    getVisibleRows() {
        const rows = this.terminal?.rows;
        if (rows === undefined)
            return DEFAULT_GRID_VISIBLE_ROWS;
        if (!Number.isFinite(rows)) {
            return this.payload.kind === 'diff'
                ? Math.max(1, this.payload.diff.cells.length)
                : DEFAULT_GRID_VISIBLE_ROWS;
        }
        // Rendered height for a diff approval is:
        //   outer chrome + button bar = 7 lines, grid = 2 * visibleRows + 4 lines.
        // On very short terminals we drop blank spacers, so one row can still fit.
        if (rows <= 13)
            return 1;
        return Math.max(1, Math.min(DEFAULT_GRID_VISIBLE_ROWS, Math.floor((rows - 11) / 2)));
    }
    isCompactLayout() {
        const rows = this.terminal?.rows;
        return rows !== undefined && rows <= 13;
    }
    rebuild() {
        const payload = this.payload;
        const theme = this.theme;
        const queueInfo = this.queueInfo;
        this.clear();
        const borderColor = (s) => theme.fg('border', s);
        this.addChild(new Border(borderColor));
        const queueLabel = queueInfo
            ? theme.fg('accent', ` (${queueInfo.current}/${queueInfo.total})`)
            : '';
        if (payload.kind === 'diff') {
            const count = payload.diff.total;
            this.addChild(new Text(theme.bold(theme.fg('accent', ' Review Changes')) +
                queueLabel +
                theme.fg('dim', `  ${count} cell${count !== 1 ? 's' : ''} modified`), 0, 0));
            if (!this.isCompactLayout()) {
                this.addChild(new Spacer(1));
            }
            const visibleRows = this.getVisibleRows();
            if (this.grid) {
                this.grid.setMaxVisibleRows(visibleRows);
            }
            else {
                this.grid = new GridTable(DIFF_COLUMNS, payload.diff.cells, theme, {
                    maxVisibleRows: visibleRows
                });
            }
            this.lastVisibleRows = visibleRows;
            this.addChild(this.grid);
            if (payload.diff.total > payload.diff.cells.length) {
                const hidden = payload.diff.total - payload.diff.cells.length;
                this.addChild(new Text(theme.fg('dim', `  ... ${hidden} more cell${hidden !== 1 ? 's' : ''} not shown`), 0, 0));
            }
            if (!this.isCompactLayout()) {
                this.addChild(new Spacer(1));
            }
        }
        else {
            this.addChild(new Text(theme.fg('warning', ` ${payload.title}`) + queueLabel, 0, 0));
            this.addChild(new Spacer(1));
            this.addChild(new Text(`  ${payload.summary}`, 0, 0));
            this.addChild(new Spacer(1));
            for (const operation of payload.operations) {
                this.addChild(new Text(`  ${theme.bold(operation.label)}`, 0, 0));
                this.addChild(new Text(theme.fg('dim', `  ${operation.reason}`), 0, 0));
            }
            this.addChild(new Spacer(1));
        }
        this.buttonBar = new ApprovalButtonBar(theme, payload.kind === 'diff'
            ? '\u2191\u2193/scroll navigate  pgup pgdn page  \u2190\u2192 select  enter confirm  esc cancel'
            : '\u2190\u2192 select  enter confirm  esc cancel', payload.kind === 'dangerous');
        this.addChild(this.buttonBar.getContainer());
        this.addChild(new Border(borderColor));
    }
    render(width) {
        const visibleRows = this.getVisibleRows();
        if (visibleRows !== this.lastVisibleRows) {
            this.rebuild();
        }
        return super.render(width);
    }
    handleInput(keyData) {
        const kb = getEditorKeybindings();
        const wheelDelta = parseMouseWheelDelta(keyData);
        if (wheelDelta !== 0) {
            this.grid?.scrollBy(wheelDelta);
            return;
        }
        if (kb.matches(keyData, 'selectUp') || keyData === 'k') {
            this.grid?.moveCursor(-1);
            return;
        }
        if (kb.matches(keyData, 'selectDown') || keyData === 'j') {
            this.grid?.moveCursor(1);
            return;
        }
        if (kb.matches(keyData, 'selectPageUp')) {
            this.grid?.movePage(-1);
            return;
        }
        if (kb.matches(keyData, 'selectPageDown')) {
            this.grid?.movePage(1);
            return;
        }
        const choice = this.buttonBar?.handleInput(keyData);
        if (choice)
            this.onDone(choice);
    }
}
//# sourceMappingURL=excel-approval.js.map