import { BrowserToolBase } from './base.js';
import { createSuccessResponse, createErrorResponse } from '../common/types.js';
import { setGlobalPage } from '../../toolHandler.js';
/**
 * Tool for clicking elements on the page
 */
export class ClickTool extends BrowserToolBase {
    /**
     * Execute the click tool
     */
    async execute(args, context) {
        return this.safeExecute(context, async (page) => {
            await page.click(args.selector);
            return createSuccessResponse(`Clicked element: ${args.selector}`);
        });
    }
}
/**
 * Tool for clicking a link and switching to the new tab
 */
export class ClickAndSwitchTabTool extends BrowserToolBase {
    /**
     * Execute the click and switch tab tool
     */
    async execute(args, context) {
        return this.safeExecute(context, async (page) => {
            // Listen for a new tab to open
            const [newPage] = await Promise.all([
                //context.browser.waitForEvent('page'), // Wait for a new page (tab) to open
                page.context().waitForEvent('page'), // Wait for a new page (tab) to open
                page.click(args.selector), // Click the link that opens the new tab
            ]);
            // Wait for the new page to load
            await newPage.waitForLoadState('domcontentloaded');
            // Switch control to the new tab
            setGlobalPage(newPage);
            //page= newPage; // Update the current page to the new tab
            //context.page = newPage;
            //context.page.bringToFront(); // Bring the new tab to the front
            return createSuccessResponse(`Clicked link and switched to new tab: ${newPage.url()}`);
            //return createSuccessResponse(`Clicked link and switched to new tab: ${context.page.url()}`);
        });
    }
}
/**
 * Tool for clicking elements inside iframes
 */
export class IframeClickTool extends BrowserToolBase {
    /**
     * Execute the iframe click tool
     */
    async execute(args, context) {
        return this.safeExecute(context, async (page) => {
            const frame = page.frameLocator(args.iframeSelector);
            if (!frame) {
                return createErrorResponse(`Iframe not found: ${args.iframeSelector}`);
            }
            await frame.locator(args.selector).click();
            return createSuccessResponse(`Clicked element ${args.selector} inside iframe ${args.iframeSelector}`);
        });
    }
}
/**
 * Tool for filling elements inside iframes
 */
export class IframeFillTool extends BrowserToolBase {
    /**
     * Execute the iframe fill tool
     */
    async execute(args, context) {
        return this.safeExecute(context, async (page) => {
            const frame = page.frameLocator(args.iframeSelector);
            if (!frame) {
                return createErrorResponse(`Iframe not found: ${args.iframeSelector}`);
            }
            await frame.locator(args.selector).fill(args.value);
            return createSuccessResponse(`Filled element ${args.selector} inside iframe ${args.iframeSelector} with: ${args.value}`);
        });
    }
}
/**
 * Tool for filling form fields
 */
export class FillTool extends BrowserToolBase {
    /**
     * Execute the fill tool
     */
    async execute(args, context) {
        return this.safeExecute(context, async (page) => {
            await page.waitForSelector(args.selector);
            await page.fill(args.selector, args.value);
            return createSuccessResponse(`Filled ${args.selector} with: ${args.value}`);
        });
    }
}
/**
 * Tool for selecting options from dropdown menus
 */
export class SelectTool extends BrowserToolBase {
    /**
     * Execute the select tool
     */
    async execute(args, context) {
        return this.safeExecute(context, async (page) => {
            await page.waitForSelector(args.selector);
            await page.selectOption(args.selector, args.value);
            return createSuccessResponse(`Selected ${args.selector} with: ${args.value}`);
        });
    }
}
/**
 * Tool for hovering over elements
 */
export class HoverTool extends BrowserToolBase {
    /**
     * Execute the hover tool
     */
    async execute(args, context) {
        return this.safeExecute(context, async (page) => {
            await page.waitForSelector(args.selector);
            await page.hover(args.selector);
            return createSuccessResponse(`Hovered ${args.selector}`);
        });
    }
}
/**
 * Tool for uploading files
 */
export class UploadFileTool extends BrowserToolBase {
    /**
     * Execute the upload file tool
     */
    async execute(args, context) {
        return this.safeExecute(context, async (page) => {
            await page.waitForSelector(args.selector);
            await page.setInputFiles(args.selector, args.filePath);
            return createSuccessResponse(`Uploaded file '${args.filePath}' to '${args.selector}'`);
        });
    }
}
/**
 * Tool for executing JavaScript in the browser
 */
export class EvaluateTool extends BrowserToolBase {
    /**
     * Execute the evaluate tool
     */
    async execute(args, context) {
        return this.safeExecute(context, async (page) => {
            const result = await page.evaluate(args.script);
            // Convert result to string for display
            let resultStr;
            try {
                resultStr = JSON.stringify(result, null, 2);
            }
            catch (error) {
                resultStr = String(result);
            }
            return createSuccessResponse([
                `Executed JavaScript:`,
                `${args.script}`,
                `Result:`,
                `${resultStr}`
            ]);
        });
    }
}
/**
 * Tool for dragging elements on the page
 */
export class DragTool extends BrowserToolBase {
    /**
     * Execute the drag tool
     */
    async execute(args, context) {
        return this.safeExecute(context, async (page) => {
            const sourceElement = await page.waitForSelector(args.sourceSelector);
            const targetElement = await page.waitForSelector(args.targetSelector);
            const sourceBound = await sourceElement.boundingBox();
            const targetBound = await targetElement.boundingBox();
            if (!sourceBound || !targetBound) {
                return createErrorResponse("Could not get element positions for drag operation");
            }
            await page.mouse.move(sourceBound.x + sourceBound.width / 2, sourceBound.y + sourceBound.height / 2);
            await page.mouse.down();
            await page.mouse.move(targetBound.x + targetBound.width / 2, targetBound.y + targetBound.height / 2);
            await page.mouse.up();
            return createSuccessResponse(`Dragged element from ${args.sourceSelector} to ${args.targetSelector}`);
        });
    }
}
/**
 * Tool for pressing keyboard keys
 */
export class PressKeyTool extends BrowserToolBase {
    /**
     * Execute the key press tool
     */
    async execute(args, context) {
        return this.safeExecute(context, async (page) => {
            if (args.selector) {
                await page.waitForSelector(args.selector);
                await page.focus(args.selector);
            }
            await page.keyboard.press(args.key);
            return createSuccessResponse(`Pressed key: ${args.key}`);
        });
    }
}
/**
 * Tool for switching browser tabs
 */
// export class SwitchTabTool extends BrowserToolBase {
//   /**
//    * Switch the tab to the specified index
//    */
//   async execute(args: any, context: ToolContext): Promise<ToolResponse> {
//     return this.safeExecute(context, async (page) => {
//       const tabs = await browser.page;      
//       // Validate the tab index
//       const tabIndex = Number(args.index);
//       if (isNaN(tabIndex)) {
//         return createErrorResponse(`Invalid tab index: ${args.index}. It must be a number.`);
//       }
//       if (tabIndex >= 0 && tabIndex < tabs.length) {
//         await tabs[tabIndex].bringToFront();
//         return createSuccessResponse(`Switched to tab with index ${tabIndex}`);
//       } else {
//         return createErrorResponse(
//           `Tab index out of range: ${tabIndex}. Available tabs: 0 to ${tabs.length - 1}.`
//         );
//       }
//     });
//   }
// }
