import node_os from "node:os";
import node_path from "node:path";
import { ComputerDevice, agentFromComputer, checkAccessibilityPermission, checkScreenRecordingPermission, getConnectedDisplays } from "@midscene/computer";
import { createScreenshotPreviewDescriptor, definePlaygroundPlatform, launchPreparedPlaygroundPlatform } from "@midscene/playground";
import puppeteer from "puppeteer";
import { PLAYGROUND_SERVER_PORT } from "@midscene/shared/constants";
import { findAvailablePort } from "@midscene/shared/node";
function _define_property(obj, key, value) {
    if (key in obj) Object.defineProperty(obj, key, {
        value: value,
        enumerable: true,
        configurable: true,
        writable: true
    });
    else obj[key] = value;
    return obj;
}
class BrowserWindowController {
    async minimize() {
        try {
            await this.session.send('Browser.setWindowBounds', {
                windowId: this.windowId,
                bounds: {
                    windowState: 'minimized'
                }
            });
            console.log('🔽 Window minimized, starting task execution...');
        } catch (error) {
            console.warn('⚠️  Failed to minimize window:', error);
        }
    }
    async restore() {
        try {
            await Promise.all([
                this.session.send('Browser.setWindowBounds', {
                    windowId: this.windowId,
                    bounds: {
                        windowState: 'normal'
                    }
                }),
                this.page.bringToFront()
            ]);
            console.log('🔼 Window restored');
        } catch (error) {
            console.warn('⚠️  Failed to restore window:', error);
        }
    }
    constructor(session, page, windowId){
        _define_property(this, "session", void 0);
        _define_property(this, "page", void 0);
        _define_property(this, "windowId", void 0);
        this.session = session;
        this.page = page;
        this.windowId = windowId;
    }
}
const computerPlaygroundPlatform = definePlaygroundPlatform({
    id: 'computer',
    title: 'Midscene Computer Playground',
    description: "Computer playground platform descriptor",
    async prepare (options) {
        const initialAccessibility = checkAccessibilityPermission(true);
        const initialScreenRecording = checkScreenRecordingPermission(true);
        const evaluatePermissions = ()=>{
            const accessibilityCheck = checkAccessibilityPermission(false);
            const screenRecordingCheck = checkScreenRecordingPermission(false);
            const permissionError = !accessibilityCheck.hasPermission && accessibilityCheck.error || !screenRecordingCheck.hasPermission && screenRecordingCheck.error || void 0;
            return {
                accessibilityCheck,
                screenRecordingCheck,
                permissionError,
                allPermissionsGranted: accessibilityCheck.hasPermission && screenRecordingCheck.hasPermission
            };
        };
        const staticDir = options?.staticDir || node_path.join(__dirname, '../../static');
        const availablePort = await findAvailablePort(PLAYGROUND_SERVER_PORT);
        if (availablePort !== PLAYGROUND_SERVER_PORT) console.log(`⚠️  Port ${PLAYGROUND_SERVER_PORT} is busy, using port ${availablePort} instead`);
        const sessionManager = {
            async getSetupSchema () {
                const { allPermissionsGranted, permissionError } = evaluatePermissions();
                const displays = await getConnectedDisplays();
                const defaultDisplay = displays.find((display)=>display.primary) || displays[0];
                return {
                    title: 'Connect Computer Agent',
                    description: allPermissionsGranted ? 'Create a Computer Agent for the selected display.' : permissionError,
                    primaryActionLabel: 'Create Agent',
                    fields: [
                        {
                            key: 'displayId',
                            label: 'Display',
                            type: 'select',
                            required: true,
                            options: displays.map((display)=>({
                                    label: display.name,
                                    value: String(display.id),
                                    description: display.primary ? 'Primary display' : void 0
                                })),
                            defaultValue: defaultDisplay ? String(defaultDisplay.id) : '',
                            placeholder: 'Select a display'
                        }
                    ],
                    targets: displays.map((display)=>({
                            id: String(display.id),
                            label: display.name,
                            description: display.primary ? 'Primary display' : void 0,
                            isDefault: display.primary
                        }))
                };
            },
            async listTargets () {
                const displays = await getConnectedDisplays();
                return displays.map((display)=>({
                        id: String(display.id),
                        label: display.name,
                        description: display.primary ? 'Primary display' : void 0,
                        isDefault: display.primary
                    }));
            },
            async createSession (input) {
                const { allPermissionsGranted, permissionError } = evaluatePermissions();
                if (!allPermissionsGranted) throw new Error(permissionError || 'Accessibility and Screen Recording permissions are required');
                const displayId = input?.displayId === void 0 || null === input.displayId ? void 0 : String(input.displayId);
                const agent = await agentFromComputer(displayId ? {
                    displayId
                } : void 0);
                const displays = await getConnectedDisplays();
                const selectedDisplay = displays.find((display)=>display.id === displayId) || displays.find((display)=>display.primary) || displays[0];
                return {
                    agent,
                    agentFactory: ()=>agentFromComputer(selectedDisplay ? {
                            displayId: selectedDisplay.id
                        } : void 0),
                    preview: createScreenshotPreviewDescriptor({
                        title: 'Desktop preview'
                    }),
                    displayName: selectedDisplay?.name || 'Desktop',
                    metadata: {
                        displayId: selectedDisplay?.id,
                        executionUx: 'countdown-before-run'
                    }
                };
            }
        };
        return {
            platformId: 'computer',
            title: 'Midscene Computer Playground',
            sessionManager,
            launchOptions: {
                port: availablePort,
                openBrowser: false,
                verbose: false,
                staticPath: staticDir
            },
            executionHooks: {
                async beforeExecute () {
                    const windowController = options?.getWindowController?.();
                    if (!windowController) return void console.warn('⚠️  Window controller not initialized yet, skipping window control');
                    await new Promise((resolve)=>setTimeout(resolve, 1500));
                    await windowController.minimize();
                },
                async afterExecute () {
                    const windowController = options?.getWindowController?.();
                    if (!windowController) return;
                    await windowController.restore();
                }
            },
            preview: createScreenshotPreviewDescriptor({
                title: 'Desktop preview'
            }),
            metadata: {
                executionUx: 'countdown-before-run',
                sessionConnected: false,
                setupState: initialAccessibility.hasPermission && initialScreenRecording.hasPermission ? 'required' : 'blocked',
                setupBlockingReason: !initialAccessibility.hasPermission && initialAccessibility.error || !initialScreenRecording.hasPermission && initialScreenRecording.error || void 0
            }
        };
    }
});
const bin_staticDir = node_path.join(__dirname, '../../static');
const main = async ()=>{
    try {
        const displays = await ComputerDevice.listDisplays();
        if (displays.length > 0) {
            console.log('🖥️  Available displays:');
            for (const display of displays)console.log(`  ${display.primary ? '✅' : '  '} ${display.name} (${display.id})${display.primary ? ' [Primary]' : ''}`);
        }
        let windowController = null;
        console.log('🚀 Starting server...');
        const prepared = await computerPlaygroundPlatform.prepare({
            staticDir: bin_staticDir,
            getWindowController: ()=>windowController
        });
        const { server: playgroundServer } = await launchPreparedPlaygroundPlatform(prepared);
        console.log('');
        console.log('✨ Midscene Computer Playground is ready!');
        console.log(`🎮 Playground: http://localhost:${playgroundServer.port}`);
        console.log(`🔑 Server ID: ${playgroundServer.id}`);
        console.log('');
        const url = `http://localhost:${playgroundServer.port}`;
        console.log('🌐 Launching browser in standalone window mode...');
        const device = new ComputerDevice();
        await device.connect();
        const screenSize = await device.size();
        await device.destroy();
        const windowWidth = 500;
        const maxWindowHeight = 1200;
        const windowHeight = Math.min(screenSize.height, maxWindowHeight);
        console.log(`📐 Screen size: ${screenSize.width}x${screenSize.height}, window size: ${windowWidth}x${windowHeight}`);
        const userDataDir = node_path.join(node_os.homedir(), '.midscene', 'computer-playground');
        console.log(`💾 User data directory: ${userDataDir}`);
        const browser = await puppeteer.launch({
            headless: false,
            defaultViewport: null,
            userDataDir,
            args: [
                `--app=${url}`,
                `--window-size=${windowWidth},${windowHeight}`,
                '--no-first-run',
                '--no-default-browser-check'
            ]
        });
        console.log('✅ Browser launched successfully');
        const pages = await browser.pages();
        const page = pages[0];
        const session = await page.createCDPSession();
        const windowInfo = await session.send('Browser.getWindowForTarget');
        console.log(`🪟 Window ID: ${windowInfo.windowId}`);
        windowController = new BrowserWindowController(session, page, windowInfo.windowId);
        console.log('✅ Window controller initialized');
        process.on('SIGINT', async ()=>{
            console.log('\n👋 Shutting down...');
            await browser.close();
            process.exit(0);
        });
    } catch (error) {
        console.error('❌ Failed to start server:', error);
        process.exit(1);
    }
};
main();
