/**
 * Input tools: click, type, press_key, hover, drag, select_option, fill_form, file_upload.
 */
export function registerInputTools(ext, bs) {
    // ── browser_click ─────────────────────────────────────────────────
    const clickTool = {
        name: "browser_click",
        label: "Browser Click",
        description: "Click on an element identified by CSS selector or text match.",
        promptSnippet: "`browser_click { element }` — click an element",
        parameters: {
            type: "object",
            properties: {
                element: { type: "string", description: "CSS selector or text to click." },
                ref: { type: "string", description: "Snapshot reference (from browser_snapshot), ignored for CSS selectors." },
                button: { type: "string", enum: ["left", "right", "middle"], description: "Mouse button. Default: left." },
                modifiers: {
                    type: "array",
                    items: { type: "string" },
                    description: "Modifier keys: Alt, Control, Meta, Shift.",
                },
            },
            required: ["element"],
        },
        async execute(_toolCallId, params) {
            const p = params;
            try {
                const page = bs.getActivePage();
                await page.click(p.element, {
                    button: p.button ?? "left",
                    modifiers: p.modifiers,
                    timeout: 5000,
                });
                return { content: [{ type: "text", text: `✓ Clicked: ${p.element}` }], details: {} };
            }
            catch (err) {
                const msg = err instanceof Error ? err.message : String(err);
                return { content: [{ type: "text", text: `Click failed: ${msg}` }], details: { isError: true } };
            }
        },
    };
    // ── browser_type ──────────────────────────────────────────────────
    const typeTool = {
        name: "browser_type",
        label: "Browser Type",
        description: "Type text into an editable element.",
        promptSnippet: "`browser_type { element, text }` — type text into an element",
        parameters: {
            type: "object",
            properties: {
                element: { type: "string", description: "CSS selector of the input element." },
                text: { type: "string", description: "Text to type." },
                ref: { type: "string", description: "Snapshot reference (from browser_snapshot)." },
                slowly: { type: "boolean", description: "Type one character at a time (human-like). Default: false." },
            },
            required: ["element", "text"],
        },
        async execute(_toolCallId, params) {
            const p = params;
            try {
                const page = bs.getActivePage();
                await page.click(p.element);
                await page.fill(p.element, "", { timeout: 5000 });
                await page.type(p.element, p.text, { delay: p.slowly ? 50 : 0 });
                return { content: [{ type: "text", text: `✓ Typed into ${p.element}: "${p.text.slice(0, 100)}"` }], details: {} };
            }
            catch (err) {
                const msg = err instanceof Error ? err.message : String(err);
                return { content: [{ type: "text", text: `Type failed: ${msg}` }], details: { isError: true } };
            }
        },
    };
    // ── browser_press_key ─────────────────────────────────────────────
    const pressKeyTool = {
        name: "browser_press_key",
        label: "Browser Press Key",
        description: "Press a keyboard key. Use single keys like 'Enter', 'Escape', 'Tab', 'ArrowDown', etc.",
        promptSnippet: "`browser_press_key { key }` — press a keyboard key",
        parameters: {
            type: "object",
            properties: {
                key: { type: "string", description: "Key to press, e.g. Enter, Escape, Tab, ArrowDown, Backspace." },
            },
            required: ["key"],
        },
        async execute(_toolCallId, params) {
            const { key } = params;
            try {
                const page = bs.getActivePage();
                await page.keyboard.press(key);
                return { content: [{ type: "text", text: `✓ Pressed key: ${key}` }], details: {} };
            }
            catch (err) {
                const msg = err instanceof Error ? err.message : String(err);
                return { content: [{ type: "text", text: `Press key failed: ${msg}` }], details: { isError: true } };
            }
        },
    };
    // ── browser_hover ─────────────────────────────────────────────────
    const hoverTool = {
        name: "browser_hover",
        label: "Browser Hover",
        description: "Hover the mouse over an element.",
        promptSnippet: "`browser_hover { element }` — hover over an element",
        parameters: {
            type: "object",
            properties: {
                element: { type: "string", description: "CSS selector of the element to hover." },
                ref: { type: "string", description: "Snapshot reference (from browser_snapshot)." },
            },
            required: ["element"],
        },
        async execute(_toolCallId, params) {
            const { element } = params;
            try {
                const page = bs.getActivePage();
                await page.hover(element, { timeout: 5000 });
                return { content: [{ type: "text", text: `✓ Hovered: ${element}` }], details: {} };
            }
            catch (err) {
                const msg = err instanceof Error ? err.message : String(err);
                return { content: [{ type: "text", text: `Hover failed: ${msg}` }], details: { isError: true } };
            }
        },
    };
    // ── browser_drag ──────────────────────────────────────────────────
    const dragTool = {
        name: "browser_drag",
        label: "Browser Drag",
        description: "Drag an element from one location to another.",
        promptSnippet: "`browser_drag { startElement, endElement }` — drag and drop",
        parameters: {
            type: "object",
            properties: {
                startElement: { type: "string", description: "CSS selector of the element to drag." },
                endElement: { type: "string", description: "CSS selector of the drop target." },
            },
            required: ["startElement", "endElement"],
        },
        async execute(_toolCallId, params) {
            const { startElement, endElement } = params;
            try {
                const page = bs.getActivePage();
                await page.dragAndDrop(startElement, endElement, { timeout: 5000 });
                return { content: [{ type: "text", text: `✓ Dragged ${startElement} → ${endElement}` }], details: {} };
            }
            catch (err) {
                const msg = err instanceof Error ? err.message : String(err);
                return { content: [{ type: "text", text: `Drag failed: ${msg}` }], details: { isError: true } };
            }
        },
    };
    // ── browser_select_option ─────────────────────────────────────────
    const selectTool = {
        name: "browser_select_option",
        label: "Browser Select Option",
        description: "Select option(s) in a <select> dropdown element.",
        promptSnippet: "`browser_select_option { element, values }` — select dropdown options",
        parameters: {
            type: "object",
            properties: {
                element: { type: "string", description: "CSS selector of the <select> element." },
                values: {
                    type: "array",
                    items: { type: "string" },
                    description: "Option values or labels to select.",
                },
            },
            required: ["element", "values"],
        },
        async execute(_toolCallId, params) {
            const { element, values } = params;
            try {
                const page = bs.getActivePage();
                await page.selectOption(element, values, { timeout: 5000 });
                return { content: [{ type: "text", text: `✓ Selected [${values.join(", ")}] in ${element}` }], details: {} };
            }
            catch (err) {
                const msg = err instanceof Error ? err.message : String(err);
                return { content: [{ type: "text", text: `Select option failed: ${msg}` }], details: { isError: true } };
            }
        },
    };
    // ── browser_fill_form ─────────────────────────────────────────────
    const fillFormTool = {
        name: "browser_fill_form",
        label: "Browser Fill Form",
        description: "Fill multiple form fields at once.",
        promptSnippet: "`browser_fill_form { fields }` — fill multiple form fields",
        parameters: {
            type: "object",
            properties: {
                fields: {
                    type: "array",
                    items: {
                        type: "object",
                        properties: {
                            name: { type: "string", description: "CSS selector, name, or label of the form field." },
                            type: { type: "string", enum: ["text", "select", "checkbox", "radio"], description: "Input type." },
                            value: { type: "string", description: "Value to fill. For checkbox/radio use 'true' or 'false'." },
                        },
                        required: ["name", "type", "value"],
                    },
                    description: "Array of form fields to fill.",
                },
            },
            required: ["fields"],
        },
        async execute(_toolCallId, params) {
            const { fields } = params;
            try {
                const page = bs.getActivePage();
                const results = [];
                for (const f of fields) {
                    switch (f.type) {
                        case "select":
                            await page.selectOption(f.name, f.value, { timeout: 5000 });
                            results.push(`✓ [select] ${f.name} = ${f.value}`);
                            break;
                        case "checkbox":
                        case "radio":
                            if (f.value === "true") {
                                await page.check(f.name, { timeout: 5000 });
                            }
                            else {
                                await page.uncheck(f.name, { timeout: 5000 });
                            }
                            results.push(`✓ [${f.type}] ${f.name} = ${f.value}`);
                            break;
                        default:
                            await page.click(f.name, { timeout: 5000 });
                            await page.fill(f.name, "", { timeout: 5000 });
                            await page.type(f.name, f.value);
                            results.push(`✓ [text] ${f.name} = "${f.value}"`);
                    }
                }
                return { content: [{ type: "text", text: results.join("\n") }], details: {} };
            }
            catch (err) {
                const msg = err instanceof Error ? err.message : String(err);
                return { content: [{ type: "text", text: `Fill form failed: ${msg}` }], details: { isError: true } };
            }
        },
    };
    // ── browser_file_upload ───────────────────────────────────────────
    const fileUploadTool = {
        name: "browser_file_upload",
        label: "Browser File Upload",
        description: "Upload one or more files through a file input element.",
        promptSnippet: "`browser_file_upload { paths }` — upload files",
        parameters: {
            type: "object",
            properties: {
                element: { type: "string", description: "CSS selector of the file input element. Default: input[type=file]." },
                paths: {
                    type: "array",
                    items: { type: "string" },
                    description: "Absolute or relative paths to files to upload.",
                },
            },
            required: ["paths"],
        },
        async execute(_toolCallId, params) {
            const p = params;
            try {
                const page = bs.getActivePage();
                const selector = p.element ?? "input[type=file]";
                const fileChooserPromise = page.waitForEvent("filechooser");
                await page.click(selector, { timeout: 5000 });
                const fileChooser = await fileChooserPromise;
                await fileChooser.setFiles(p.paths);
                return { content: [{ type: "text", text: `✓ Uploaded: ${p.paths.join(", ")}` }], details: {} };
            }
            catch (err) {
                const msg = err instanceof Error ? err.message : String(err);
                return { content: [{ type: "text", text: `File upload failed: ${msg}` }], details: { isError: true } };
            }
        },
    };
    const tools = [clickTool, typeTool, pressKeyTool, hoverTool, dragTool, selectTool, fillFormTool, fileUploadTool];
    for (const tool of tools) {
        try {
            ext.registerTool(tool);
        }
        catch (err) {
            const msg = err instanceof Error ? err.message : String(err);
            process.stderr.write(`[browser] Failed to register ${tool.name}: ${msg}\n`);
        }
    }
}
