/**
 * Vision overlay component for the TUI.
 * Shows screen capture state: selecting display, capturing, recording.
 */
import { Container, Spacer, Text } from "@dotkaio/avis-tui";
import { theme } from "../theme/theme.js";
import { DynamicBorder } from "./dynamic-border.js";
export class VisionOverlayComponent extends Container {
    constructor(config) {
        super();
        this.animFrame = 0;
        this.animInterval = null;
        this.recordStartTime = 0;
        this.recordTimer = null;
        this.config = config;
        this.addChild(new DynamicBorder());
        this.addChild(new Spacer(1));
        this.addChild(new Text(theme.bold(theme.fg("accent", "  Screen Capture")), 0, 0));
        this.addChild(new Spacer(1));
        this.stateText = new Text("", 0, 0);
        this.addChild(this.stateText);
        this.displayText = new Text("", 0, 0);
        this.addChild(this.displayText);
        this.detailText = new Text("", 0, 0);
        this.addChild(this.detailText);
        this.addChild(new Spacer(1));
        this.hintText = new Text("", 0, 0);
        this.addChild(this.hintText);
        this.addChild(new Spacer(1));
        this.addChild(new DynamicBorder());
        this.updateDisplay();
    }
    updateState(config) {
        Object.assign(this.config, config);
        this.updateDisplay();
    }
    startAnimation(requestRender) {
        if (this.animInterval)
            return;
        this.animInterval = setInterval(() => {
            this.animFrame = (this.animFrame + 1) % 4;
            this.updateDisplay();
            requestRender();
        }, 300);
    }
    stopAnimation() {
        if (this.animInterval) {
            clearInterval(this.animInterval);
            this.animInterval = null;
        }
        if (this.recordTimer) {
            clearInterval(this.recordTimer);
            this.recordTimer = null;
        }
    }
    startRecordTimer(requestRender) {
        this.recordStartTime = Date.now();
        this.recordTimer = setInterval(() => {
            const elapsed = Math.floor((Date.now() - this.recordStartTime) / 1000);
            this.config.recordingDuration = elapsed;
            this.updateDisplay();
            requestRender();
        }, 1000);
    }
    getDots() {
        return ".".repeat((this.animFrame % 3) + 1).padEnd(3);
    }
    getRecordIndicator() {
        const frames = ["[REC]", "[REC]", "[ . ]", "[REC]"];
        return frames[this.animFrame % frames.length];
    }
    formatDuration(secs) {
        const m = Math.floor(secs / 60);
        const s = secs % 60;
        return `${m}:${s.toString().padStart(2, "0")}`;
    }
    updateDisplay() {
        const { state, displays, selectedDisplay, mode, errorMessage, recordingDuration, frameCount } = this.config;
        switch (state) {
            case "selecting": {
                const modeLabel = mode === "screenshot" ? "Screenshot" : "Record";
                this.stateText.setText(theme.fg("accent", `  Mode: ${modeLabel}`));
                let displayList = "";
                for (const d of displays) {
                    const marker = d.id === (selectedDisplay ?? 1) ? theme.fg("accent", " > ") : "   ";
                    const main = d.isMain ? " (main)" : "";
                    displayList += `${marker}${d.id}. ${d.name} - ${d.resolution}${main}\n`;
                }
                this.displayText.setText(displayList.trimEnd());
                const lines = [
                    theme.fg("dim", "  1-9  select display"),
                    theme.fg("dim", "  Tab  toggle screenshot/record"),
                    theme.fg("dim", "  Enter  capture"),
                    theme.fg("dim", "  Esc  cancel"),
                ];
                this.detailText.setText("");
                this.hintText.setText(lines.join("\n"));
                break;
            }
            case "screenshot":
                this.stateText.setText(theme.fg("warning", `  Taking screenshot${this.getDots()}`));
                this.displayText.setText("");
                this.detailText.setText(theme.fg("muted", `  Display ${selectedDisplay ?? 1}`));
                this.hintText.setText("");
                break;
            case "recording": {
                const dur = this.formatDuration(recordingDuration ?? 0);
                this.stateText.setText(theme.fg("error", `  ${this.getRecordIndicator()} Recording  ${dur}`));
                this.displayText.setText("");
                this.detailText.setText(theme.fg("muted", `  Display ${selectedDisplay ?? 1} - recording your screen`));
                this.hintText.setText(theme.fg("dim", "  Esc  stop recording and send to Avis"));
                break;
            }
            case "processing":
                this.stateText.setText(theme.fg("warning", `  Processing capture${this.getDots()}`));
                this.displayText.setText("");
                this.detailText.setText(frameCount
                    ? theme.fg("muted", `  Extracted ${frameCount} frame(s)`)
                    : theme.fg("muted", "  Preparing image..."));
                this.hintText.setText("");
                break;
            case "ready":
                this.stateText.setText(theme.fg("success", "  Capture ready"));
                this.displayText.setText("");
                this.detailText.setText(theme.fg("muted", "  Sending to Avis..."));
                this.hintText.setText("");
                break;
            case "error":
                this.stateText.setText(theme.fg("error", "  Error"));
                this.displayText.setText("");
                this.detailText.setText(theme.fg("error", `  ${errorMessage ?? "Unknown error"}`));
                this.hintText.setText(theme.fg("dim", "  Esc  close"));
                break;
        }
    }
    handleInput(data) {
        const { state } = this.config;
        // Esc to cancel or stop recording
        if (data === "\x1b" || data === "\x1b\x1b") {
            this.stopAnimation();
            this.onCancel?.();
            return;
        }
        // Ctrl+C
        if (data === "\x03") {
            this.stopAnimation();
            this.onCancel?.();
            return;
        }
        if (state === "selecting") {
            // Number keys 1-9 to select display
            if (data >= "1" && data <= "9") {
                const id = parseInt(data, 10);
                if (id <= this.config.displays.length) {
                    this.config.selectedDisplay = id;
                    this.onSelectDisplay?.(id);
                    this.updateDisplay();
                }
                return;
            }
            // Tab to toggle mode
            if (data === "\t") {
                this.onToggleMode?.();
                return;
            }
            // Enter to capture
            if (data === "\r" || data === "\n") {
                this.onCapture?.();
                return;
            }
        }
    }
    dispose() {
        this.stopAnimation();
    }
}
//# sourceMappingURL=vision-overlay.js.map