import { Editor, visibleWidth } from "@earendil-works/pi-tui";
const ANSI_ESCAPE_PATTERN = /\x1b\[[0-?]*[ -/]*[@-~]|\x1b\][^\x07]*(?:\x07|\x1b\\)|\x1b[PX_][\s\S]*?\x1b\\/g;
const BORDER_LINE_PATTERN = /^[─ ↑↓0-9more]+$/;
/**
 * Custom editor that handles app-level keybindings for coding-agent.
 */
export class CustomEditor extends Editor {
    constructor(tui, theme, keybindings, options) {
        super(tui, theme, options);
        this.actionHandlers = new Map();
        this.keybindings = keybindings;
        this.promptPrefix = options?.promptPrefix ?? "❯ ";
    }
    render(width) {
        const promptWidth = visibleWidth(this.promptPrefix);
        if (promptWidth <= 0 || width <= promptWidth + 1) {
            return super.render(width);
        }
        const editorWidth = Math.max(1, width - promptWidth);
        const lines = super.render(editorWidth);
        let borderCount = 0;
        let inPromptBox = false;
        let promptShown = false;
        return lines.map((line) => {
            if (this.isEditorBorderLine(line)) {
                borderCount += 1;
                if (borderCount === 1) {
                    inPromptBox = true;
                    promptShown = false;
                }
                else if (borderCount === 2) {
                    inPromptBox = false;
                }
                return this.extendBorderLine(line, width);
            }
            const prefix = inPromptBox && !promptShown ? this.promptPrefix : " ".repeat(promptWidth);
            if (inPromptBox) {
                promptShown = true;
            }
            return this.padLine(`${prefix}${line}`, width);
        });
    }
    isEditorBorderLine(line) {
        const plain = line.replace(ANSI_ESCAPE_PATTERN, "").trim();
        return plain.includes("─") && BORDER_LINE_PATTERN.test(plain);
    }
    extendBorderLine(line, width) {
        const remainingWidth = width - visibleWidth(line);
        if (remainingWidth <= 0) {
            return line;
        }
        return `${line}${this.borderColor("─".repeat(remainingWidth))}`;
    }
    padLine(line, width) {
        const remainingWidth = width - visibleWidth(line);
        if (remainingWidth <= 0) {
            return line;
        }
        return `${line}${" ".repeat(remainingWidth)}`;
    }
    /**
     * Register a handler for an app action.
     */
    onAction(action, handler) {
        this.actionHandlers.set(action, handler);
    }
    handleInput(data) {
        // Check extension-registered shortcuts first
        if (this.onExtensionShortcut?.(data)) {
            return;
        }
        // Check for paste image keybinding
        if (this.keybindings.matches(data, "app.clipboard.pasteImage")) {
            this.onPasteImage?.();
            return;
        }
        // Check app keybindings first
        // Escape/interrupt - only if autocomplete is NOT active
        if (this.keybindings.matches(data, "app.interrupt")) {
            if (!this.isShowingAutocomplete()) {
                // Use dynamic onEscape if set, otherwise registered handler
                const handler = this.onEscape ?? this.actionHandlers.get("app.interrupt");
                if (handler) {
                    handler();
                    return;
                }
            }
            // Let parent handle escape for autocomplete cancellation
            super.handleInput(data);
            return;
        }
        // Exit (Ctrl+D) - only when editor is empty
        if (this.keybindings.matches(data, "app.exit")) {
            if (this.getText().length === 0) {
                const handler = this.onCtrlD ?? this.actionHandlers.get("app.exit");
                if (handler)
                    handler();
                return;
            }
            // Fall through to editor handling for delete-char-forward when not empty
        }
        // Check all other app actions
        for (const [action, handler] of this.actionHandlers) {
            if (action !== "app.interrupt" && action !== "app.exit" && this.keybindings.matches(data, action)) {
                handler();
                return;
            }
        }
        // Pass to parent for editor handling
        super.handleInput(data);
    }
}
//# sourceMappingURL=custom-editor.js.map