"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.registerCaptureTools = registerCaptureTools;
const path = __importStar(require("path"));
const logger_1 = require("../../../lib/logger");
const playwright_1 = require("../playwright");
const schemas_1 = require("./schemas");
const helpers_1 = require("./helpers");
function registerCaptureTools(srv) {
    // capture_page
    srv.registerTool('capture_page', {
        title: 'Capture Page',
        description: 'Navigate to a URL, capture a screenshot, and save it to persistent file storage in one call. ' +
            'The returned `path` is the storage reference — no separate write_file call is needed. ' +
            'Optionally waits for a CSS selector or a fixed delay to ensure content is loaded. ' +
            'Pass page_id from a prior login_and_capture to reuse the authenticated session.',
        inputSchema: schemas_1.capturePageSchema,
    }, async (args) => {
        try {
            let page;
            let pageId;
            if (args.page_id && playwright_1.pages.has(args.page_id)) {
                const existingPage = playwright_1.pages.get(args.page_id);
                try {
                    await existingPage.evaluate('1');
                    page = existingPage;
                    pageId = args.page_id;
                }
                catch {
                    playwright_1.pages.delete(args.page_id);
                    const b = await (0, playwright_1.ensureBrowser)();
                    page = await b.newPage();
                    pageId = (0, playwright_1.allocatePageId)();
                    playwright_1.pages.set(pageId, page);
                }
            }
            else {
                const b = await (0, playwright_1.ensureBrowser)();
                page = await b.newPage();
                pageId = (0, playwright_1.allocatePageId)();
                playwright_1.pages.set(pageId, page);
            }
            await page.goto(args.url, {
                waitUntil: args.wait_until || 'load',
                timeout: args.timeout ?? 30_000,
            });
            if (args.wait_for_selector) {
                await page.waitForSelector(args.wait_for_selector, { timeout: args.timeout ?? 10_000 });
            }
            else {
                await page.waitForTimeout(args.wait_ms ?? 2000);
            }
            // Auto-derive screenshot path from URL if not provided
            let screenshotPath = args.screenshot_path || (() => {
                try {
                    const urlPath = new URL(args.url).pathname;
                    const slug = urlPath === '/' ? 'home' : urlPath.replace(/^\/+|\/+$/g, '').replace(/\//g, '-');
                    return `screenshots/${slug || 'page'}.png`;
                }
                catch {
                    return `screenshots/capture-${Date.now()}.png`;
                }
            })();
            // Ensure file extension — storage backends require mime type
            if (!path.extname(screenshotPath)) {
                screenshotPath += '.png';
            }
            const screenshot = await (0, helpers_1.saveScreenshot)(page, screenshotPath, args.full_page ?? true);
            return {
                content: [{
                        type: 'text',
                        text: JSON.stringify({
                            page_id: pageId,
                            url: page.url(),
                            title: await page.title(),
                            ...screenshot,
                            storage_ref: screenshot.path,
                            _handle: (0, playwright_1.buildHandle)(pageId),
                        }),
                    }],
            };
        }
        catch (err) {
            return (0, helpers_1.errorResult)(err.message, err.name === 'TimeoutError' ? 'TIMEOUT' : 'CAPTURE_FAILED');
        }
    });
    // extract_content
    srv.registerTool('extract_content', {
        title: 'Extract Content',
        description: 'Navigate to a URL and extract structured content. ' +
            'Extracts page title and text by default. Optionally extracts links, metadata, ' +
            'text from a specific CSS selector, or runs custom JavaScript.',
        inputSchema: schemas_1.extractContentSchema,
    }, async (args) => {
        try {
            let page;
            let pageId;
            if (args.page_id && playwright_1.pages.has(args.page_id)) {
                // Reuse existing page (e.g., from login_and_capture)
                const existingPage = playwright_1.pages.get(args.page_id);
                // Verify page is still usable (not closed)
                try {
                    await existingPage.evaluate('1');
                    page = existingPage;
                    pageId = args.page_id;
                    if (args.url) {
                        await page.goto(args.url, { waitUntil: 'load', timeout: args.timeout ?? 30_000 });
                    }
                }
                catch {
                    // Page is stale/closed — clean it up and fall through to create new page
                    playwright_1.pages.delete(args.page_id);
                    logger_1.loggerRegistry.info(`[lt-mcp:playwright-cli] extract_content: page_id ${args.page_id} is stale, creating fresh page`);
                    if (!args.url) {
                        return (0, helpers_1.errorResult)('page_id is stale and no url provided as fallback', 'STALE_PAGE');
                    }
                    const b = await (0, playwright_1.ensureBrowser)();
                    page = await b.newPage();
                    pageId = (0, playwright_1.allocatePageId)();
                    playwright_1.pages.set(pageId, page);
                    await page.goto(args.url, { waitUntil: 'load', timeout: args.timeout ?? 30_000 });
                }
            }
            else {
                if (!args.url) {
                    return (0, helpers_1.errorResult)('Either url or a valid page_id is required', 'MISSING_PARAMS');
                }
                const b = await (0, playwright_1.ensureBrowser)();
                page = await b.newPage();
                pageId = (0, playwright_1.allocatePageId)();
                playwright_1.pages.set(pageId, page);
                await page.goto(args.url, { waitUntil: 'load', timeout: args.timeout ?? 30_000 });
            }
            if (args.wait_for_selector) {
                await page.waitForSelector(args.wait_for_selector, { timeout: args.timeout ?? 10_000 });
            }
            else {
                await page.waitForTimeout(args.wait_ms ?? 1000);
            }
            const result = {
                url: page.url(),
                title: await page.title(),
            };
            // Extract text from selector
            if (args.selector) {
                result.content = await page.$$eval(args.selector, (els) => els.map((el) => el.innerText).join('\n'));
            }
            else {
                result.content = await page.evaluate(() => document.body.innerText.slice(0, 5000));
            }
            // Custom script
            if (args.script) {
                result.script_result = await page.evaluate(args.script);
            }
            // Links
            if (args.extract_links) {
                result.links = await page.$$eval('a[href]', (els) => els.map((a) => ({ text: a.textContent?.trim(), href: a.href }))
                    .filter((l) => l.href && !l.href.startsWith('javascript:')));
            }
            // Metadata
            if (args.extract_metadata) {
                result.metadata = await page.evaluate(() => ({
                    title: document.title,
                    description: document.querySelector('meta[name="description"]')?.getAttribute('content'),
                    og_title: document.querySelector('meta[property="og:title"]')?.getAttribute('content'),
                    og_description: document.querySelector('meta[property="og:description"]')?.getAttribute('content'),
                    og_image: document.querySelector('meta[property="og:image"]')?.getAttribute('content'),
                }));
            }
            result.page_id = pageId;
            result._handle = (0, playwright_1.buildHandle)(pageId);
            return {
                content: [{ type: 'text', text: JSON.stringify(result) }],
            };
        }
        catch (err) {
            return (0, helpers_1.errorResult)(err.message, err.name === 'TimeoutError' ? 'TIMEOUT' : 'EXTRACT_FAILED');
        }
    });
    // submit_form
    srv.registerTool('submit_form', {
        title: 'Submit Form',
        description: 'Navigate to a form page, fill multiple fields, submit, and capture the result. ' +
            'Handles navigation, field filling, form submission, and post-submit waiting in one call.',
        inputSchema: schemas_1.submitFormSchema,
    }, async (args) => {
        try {
            const b = await (0, playwright_1.ensureBrowser)();
            const page = await b.newPage();
            const pageId = (0, playwright_1.allocatePageId)();
            playwright_1.pages.set(pageId, page);
            const timeout = args.timeout ?? 30_000;
            await page.goto(args.url, { waitUntil: 'load', timeout });
            // Fill all fields
            for (const field of args.fields) {
                await page.fill(field.selector, field.value, { timeout });
            }
            // Submit
            await page.click(args.submit_selector, { timeout });
            // Wait for result
            if (args.wait_after_submit) {
                const indicator = args.wait_after_submit;
                if (indicator.startsWith('/') || indicator.startsWith('http')) {
                    await page.waitForFunction((pattern) => window.location.href.includes(pattern), indicator, { timeout });
                }
                else {
                    await page.waitForSelector(indicator, { timeout });
                }
            }
            else {
                await page.waitForTimeout(2000);
            }
            // Optional screenshot — handle directory-only paths gracefully
            let screenshot;
            if (args.screenshot_path) {
                let screenshotPath = args.screenshot_path;
                if (!path.extname(screenshotPath)) {
                    screenshotPath = screenshotPath.replace(/\/$/, '') + '/result.png';
                }
                screenshot = await (0, helpers_1.saveScreenshot)(page, screenshotPath, args.full_page ?? true);
            }
            return {
                content: [{
                        type: 'text',
                        text: JSON.stringify({
                            page_id: pageId,
                            result_url: page.url(),
                            result_title: await page.title(),
                            screenshot,
                            _handle: (0, playwright_1.buildHandle)(pageId),
                        }),
                    }],
            };
        }
        catch (err) {
            logger_1.loggerRegistry.error(`[lt-mcp:playwright-cli] submit_form error: ${err.message}`);
            return (0, helpers_1.errorResult)(err.message, err.name === 'TimeoutError' ? 'TIMEOUT' : 'SUBMIT_FAILED');
        }
    });
}
