/**
 * Canvas Manager - Dynamic Terminal UI Components
 *
 * Provides A2UI-style dynamic rendering for terminal interfaces.
 */
import { EventEmitter } from 'events';
export const DEFAULT_CANVAS_CONFIG = {
    width: 80,
    height: 24,
    refreshRate: 60,
    clearOnRender: true,
};
// ============================================================================
// ANSI Helpers
// ============================================================================
const ANSI = {
    reset: '\x1b[0m',
    bold: '\x1b[1m',
    dim: '\x1b[2m',
    italic: '\x1b[3m',
    underline: '\x1b[4m',
    colors: {
        black: '\x1b[30m',
        red: '\x1b[31m',
        green: '\x1b[32m',
        yellow: '\x1b[33m',
        blue: '\x1b[34m',
        magenta: '\x1b[35m',
        cyan: '\x1b[36m',
        white: '\x1b[37m',
    },
    bgColors: {
        black: '\x1b[40m',
        red: '\x1b[41m',
        green: '\x1b[42m',
        yellow: '\x1b[43m',
        blue: '\x1b[44m',
        magenta: '\x1b[45m',
        cyan: '\x1b[46m',
        white: '\x1b[47m',
    },
    cursor: {
        hide: '\x1b[?25l',
        show: '\x1b[?25h',
        home: '\x1b[H',
        clear: '\x1b[2J',
        moveTo: (x, y) => `\x1b[${y};${x}H`,
    },
    box: {
        single: { tl: '┌', tr: '┐', bl: '└', br: '┘', h: '─', v: '│' },
        double: { tl: '╔', tr: '╗', bl: '╚', br: '╝', h: '═', v: '║' },
        rounded: { tl: '╭', tr: '╮', bl: '╰', br: '╯', h: '─', v: '│' },
    },
};
function applyStyle(text, style) {
    if (!style)
        return text;
    let result = '';
    if (style.bold)
        result += ANSI.bold;
    if (style.dim)
        result += ANSI.dim;
    if (style.italic)
        result += ANSI.italic;
    if (style.underline)
        result += ANSI.underline;
    if (style.color && ANSI.colors[style.color])
        result += ANSI.colors[style.color];
    if (style.bgColor && ANSI.bgColors[style.bgColor])
        result += ANSI.bgColors[style.bgColor];
    result += text + ANSI.reset;
    return result;
}
// ============================================================================
// Component Factory
// ============================================================================
let componentIdCounter = 0;
export function createComponent(type, content, style) {
    return {
        id: `comp-${++componentIdCounter}`,
        type,
        content,
        style,
        visible: true,
        zIndex: 0,
    };
}
export function createText(text, style) {
    return createComponent('text', text, style);
}
export function createBox(content, style) {
    return createComponent('box', Array.isArray(content) ? content : [createText(content)], {
        border: 'single',
        ...style,
    });
}
export function createPanel(title, content, style) {
    return createComponent('panel', [createText(title), ...content], {
        border: 'rounded',
        ...style,
    });
}
export function createProgress(percent, width = 20, style) {
    const filled = Math.round((percent / 100) * width);
    const empty = width - filled;
    const bar = '█'.repeat(filled) + '░'.repeat(empty);
    return createComponent('progress', `[${bar}] ${percent}%`, style);
}
export function createSpinner(frame = 0, style) {
    const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
    return createComponent('spinner', frames[frame % frames.length], style);
}
export function createTable(headers, rows, style) {
    const lines = [];
    const colWidths = headers.map((h, i) => {
        const maxRow = Math.max(...rows.map(r => (r[i] || '').length));
        return Math.max(h.length, maxRow);
    });
    // Header
    lines.push(headers.map((h, i) => h.padEnd(colWidths[i])).join(' │ '));
    lines.push(colWidths.map(w => '─'.repeat(w)).join('─┼─'));
    // Rows
    for (const row of rows) {
        lines.push(row.map((c, i) => (c || '').padEnd(colWidths[i])).join(' │ '));
    }
    return createComponent('table', lines, style);
}
export function createList(items, style) {
    return createComponent('list', items.map((item, i) => `${i + 1}. ${item}`), style);
}
// ============================================================================
// Canvas Renderer
// ============================================================================
export class CanvasRenderer {
    buffer = [];
    width;
    height;
    constructor(width, height) {
        this.width = width;
        this.height = height;
        this.clear();
    }
    clear() {
        this.buffer = Array(this.height).fill(null).map(() => Array(this.width).fill(' '));
    }
    drawText(text, x, y, style) {
        const styledText = applyStyle(text, style);
        const chars = [...text];
        for (let i = 0; i < chars.length && x + i < this.width; i++) {
            if (y >= 0 && y < this.height && x + i >= 0) {
                this.buffer[y][x + i] = chars[i];
            }
        }
    }
    drawBox(x, y, width, height, style) {
        const border = style?.border ?? 'single';
        if (border === 'none')
            return;
        const chars = ANSI.box[border] || ANSI.box.single;
        // Corners
        this.drawText(chars.tl, x, y, style);
        this.drawText(chars.tr, x + width - 1, y, style);
        this.drawText(chars.bl, x, y + height - 1, style);
        this.drawText(chars.br, x + width - 1, y + height - 1, style);
        // Horizontal lines
        for (let i = 1; i < width - 1; i++) {
            this.drawText(chars.h, x + i, y, style);
            this.drawText(chars.h, x + i, y + height - 1, style);
        }
        // Vertical lines
        for (let i = 1; i < height - 1; i++) {
            this.drawText(chars.v, x, y + i, style);
            this.drawText(chars.v, x + width - 1, y + i, style);
        }
    }
    render() {
        return this.buffer.map(row => row.join('')).join('\n');
    }
    toString() {
        return this.render();
    }
}
// ============================================================================
// Canvas Manager
// ============================================================================
export class CanvasManager extends EventEmitter {
    config;
    components = new Map();
    renderer;
    renderInterval = null;
    dirty = true;
    constructor(config = {}) {
        super();
        this.config = { ...DEFAULT_CANVAS_CONFIG, ...config };
        this.renderer = new CanvasRenderer(this.config.width, this.config.height);
    }
    add(component) {
        this.components.set(component.id, component);
        this.dirty = true;
        return component.id;
    }
    remove(id) {
        const removed = this.components.delete(id);
        if (removed)
            this.dirty = true;
        return removed;
    }
    get(id) {
        return this.components.get(id);
    }
    update(id, updates) {
        const component = this.components.get(id);
        if (!component)
            return false;
        Object.assign(component, updates);
        this.dirty = true;
        return true;
    }
    show(id) {
        this.update(id, { visible: true });
    }
    hide(id) {
        this.update(id, { visible: false });
    }
    clear() {
        this.components.clear();
        this.dirty = true;
    }
    render() {
        if (this.config.clearOnRender) {
            this.renderer.clear();
        }
        // Sort by zIndex
        const sorted = [...this.components.values()]
            .filter(c => c.visible)
            .sort((a, b) => a.zIndex - b.zIndex);
        let y = 0;
        for (const component of sorted) {
            const x = component.x ?? 0;
            const startY = component.y ?? y;
            this.renderComponent(component, x, startY);
            if (component.y === undefined) {
                y = startY + this.getComponentHeight(component);
            }
        }
        this.dirty = false;
        return this.renderer.render();
    }
    renderComponent(component, x, y) {
        switch (component.type) {
            case 'text':
                this.renderer.drawText(component.content, x, y, component.style);
                break;
            case 'progress':
            case 'spinner':
                this.renderer.drawText(component.content, x, y, component.style);
                break;
            case 'list':
            case 'table':
                const lines = component.content;
                for (let i = 0; i < lines.length; i++) {
                    this.renderer.drawText(lines[i], x, y + i, component.style);
                }
                break;
            case 'box':
            case 'panel':
                const width = typeof component.style?.width === 'number' ? component.style.width : 40;
                const height = typeof component.style?.height === 'number' ? component.style.height : 10;
                this.renderer.drawBox(x, y, width, height, component.style);
                // Render children
                const children = component.content;
                let childY = y + 1;
                for (const child of children) {
                    this.renderComponent(child, x + 2, childY);
                    childY += this.getComponentHeight(child);
                }
                break;
        }
    }
    getComponentHeight(component) {
        if (Array.isArray(component.content)) {
            if (component.type === 'list' || component.type === 'table') {
                return component.content.length;
            }
            return component.content.reduce((sum, c) => sum + this.getComponentHeight(c), 0);
        }
        return 1;
    }
    startAutoRender() {
        if (this.renderInterval)
            return;
        const interval = Math.floor(1000 / this.config.refreshRate);
        this.renderInterval = setInterval(() => {
            if (this.dirty) {
                const output = this.render();
                this.emit('render', output);
            }
        }, interval);
    }
    stopAutoRender() {
        if (this.renderInterval) {
            clearInterval(this.renderInterval);
            this.renderInterval = null;
        }
    }
    getStats() {
        return {
            componentCount: this.components.size,
            visibleCount: [...this.components.values()].filter(c => c.visible).length,
            dirty: this.dirty,
        };
    }
}
// Singleton
let canvasInstance = null;
export function getCanvasManager(config) {
    if (!canvasInstance) {
        canvasInstance = new CanvasManager(config);
    }
    return canvasInstance;
}
export function resetCanvasManager() {
    if (canvasInstance) {
        canvasInstance.stopAutoRender();
        canvasInstance.clear();
        canvasInstance = null;
    }
}
export { A2UI_VERSION, STANDARD_CATALOG_ID, DEFAULT_SURFACE_STYLES, } from './a2ui-types.js';
export { A2UIManager, getA2UIManager, resetA2UIManager, } from './a2ui-manager.js';
export { A2UIServer, getA2UIServer, resetA2UIServer, DEFAULT_A2UI_SERVER_CONFIG, } from './a2ui-server.js';
export { A2UITool, getA2UITool, resetA2UITool, } from './a2ui-tool.js';
export { DEFAULT_CANVAS_CONFIG as DEFAULT_VISUAL_CANVAS_CONFIG } from './types.js';
export { CanvasManager as VisualCanvasManager, getCanvasManager as getVisualCanvasManager, resetCanvasManager as resetVisualCanvasManager, } from './canvas-manager.js';
//# sourceMappingURL=index.js.map