import { matchesKey } from "@earendil-works/pi-tui";
import { IsolatedInteractiveRuntime } from "./isolated-runtime.js";
import { RemoteComponentController } from "./remote-component.js";
import { InputFormHostController } from "./input-form-host.js";
import { SessionPickerHostController } from "./session-picker-host.js";
async function handleRequest(ui, request) {
    switch (request.method) {
        case "select": {
            const value = await ui.select(request.title, request.options, { timeout: request.timeout });
            return value === undefined
                ? { type: "extension_ui_response", id: request.id, cancelled: true }
                : { type: "extension_ui_response", id: request.id, value };
        }
        case "confirm": {
            const confirmed = await ui.confirm(request.title, request.message, { timeout: request.timeout });
            return { type: "extension_ui_response", id: request.id, confirmed };
        }
        case "input": {
            const value = await ui.input(request.title, request.placeholder, { timeout: request.timeout });
            return value === undefined
                ? { type: "extension_ui_response", id: request.id, cancelled: true }
                : { type: "extension_ui_response", id: request.id, value };
        }
        case "editor": {
            const value = await ui.editor(request.title, request.prefill);
            return value === undefined
                ? { type: "extension_ui_response", id: request.id, cancelled: true }
                : { type: "extension_ui_response", id: request.id, value };
        }
        case "notify":
            ui.notify(request.message, request.notifyType);
            return undefined;
        case "setStatus":
            ui.setStatus(request.statusKey, request.statusText);
            return undefined;
        case "setWidget":
            ui.setWidget(request.widgetKey, request.widgetLines, { placement: request.widgetPlacement });
            return undefined;
        case "setTitle":
            ui.setTitle(request.title);
            return undefined;
        case "set_editor_text":
            ui.setEditorText(request.text);
            return undefined;
    }
}
export function attachInteractiveEngineKeybindingSync(runtime, keybindings, onState) {
    const applyState = (state) => {
        keybindings.setUserBindings(state.userBindings);
        onState?.(state);
    };
    if (runtime.onKeybindingState)
        return runtime.onKeybindingState(applyState);
    return runtime.onEngineMessage((message) => {
        if (message.type === "engine_keybindings_reloaded")
            applyState(message.state);
    });
}
export function attachInteractiveEngineHost(runtime, ui, onDiagnostic, setShortcutHandler, keybindings) {
    if (!(runtime instanceof IsolatedInteractiveRuntime))
        return () => { };
    const disposeDiagnostic = runtime.onDiagnostic(onDiagnostic);
    const disposeExtensionUi = runtime.setExtensionUIHandler((request) => handleRequest(ui, request));
    let shortcuts = [];
    const dispatchShortcut = (data) => {
        const shortcut = shortcuts.find(({ key }) => matchesKey(data, key));
        if (!shortcut)
            return false;
        void runtime.invokeRemoteShortcut(shortcut.key).catch((error) => onDiagnostic({ activity: undefined, elapsedMs: 0, level: "unresponsive", message: error.message }));
        return true;
    };
    let disposeShortcutHandler;
    const installShortcutHandler = () => {
        disposeShortcutHandler?.();
        const dispose = setShortcutHandler?.(dispatchShortcut);
        disposeShortcutHandler = typeof dispose === "function" ? dispose : undefined;
    };
    const applyState = (state) => {
        shortcuts = [...state.shortcuts];
        installShortcutHandler();
    };
    installShortcutHandler();
    const disposeKeybindings = keybindings
        ? attachInteractiveEngineKeybindingSync(runtime, keybindings, applyState)
        : runtime.onEngineMessage((message) => {
            if (message.type === "engine_keybindings_reloaded")
                applyState(message.state);
        });
    const remoteComponents = new RemoteComponentController(runtime, ui);
    const sessionPicker = new SessionPickerHostController(runtime, ui);
    const inputForm = new InputFormHostController(runtime, ui);
    let disposed = false;
    return () => {
        if (disposed)
            return;
        disposed = true;
        disposeShortcutHandler?.();
        disposeKeybindings();
        remoteComponents.dispose();
        sessionPicker.dispose();
        inputForm.dispose();
        disposeExtensionUi();
        disposeDiagnostic();
    };
}
export async function waitForInteractiveEngineBound(runtime) {
    if (!(runtime instanceof IsolatedInteractiveRuntime))
        return;
    await runtime.waitUntilBound();
    await runtime.initializeFromEngine();
}
export function interruptBlockedInteractiveEngine(runtime) {
    return runtime instanceof IsolatedInteractiveRuntime && runtime.interruptBlockedCallback();
}
/**
 * Command catalog the engine child exposes to the isolated host. Returns an
 * empty list for non-isolated runtimes so callers can merge unconditionally.
 */
export function getInteractiveEngineRemoteCommands(runtime) {
    return runtime instanceof IsolatedInteractiveRuntime ? runtime.getRemoteCommands() : [];
}
/** Subscribe to engine-child command catalog changes. No-op when not isolated. */
export function onInteractiveEngineRemoteCommandsChanged(runtime, listener) {
    return runtime instanceof IsolatedInteractiveRuntime ? runtime.onRemoteCommandsChanged(listener) : () => { };
}
//# sourceMappingURL=extension-ui-bridge.js.map