import { parseStructuredParams } from "../common.mjs";
import { BasePlaygroundAdapter } from "./base.mjs";
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 ElectronExecutionAdapter extends BasePlaygroundAdapter {
    onDumpUpdate(callback) {
        this.dumpUpdateCallback = void 0;
        this.dumpUpdateCallback = callback;
        window.electron?.ipcRenderer.removeAllListeners('progress-chunk');
        window.electron?.ipcRenderer.on('progress-chunk', (e, executionDump)=>{
            try {
                if (executionDump) {
                    if (this.dumpUpdateCallback) this.dumpUpdateCallback('', executionDump);
                }
            } catch (error) {
                console.error('Error polling task progress:', error);
            }
        });
    }
    get id() {
        return this._id;
    }
    validateParams(value, action) {
        if (!action?.paramSchema) return {
            valid: true
        };
        const needsStructuredParams = this.actionNeedsStructuredParams(action);
        if (!needsStructuredParams) return {
            valid: true
        };
        if (!value.params) return {
            valid: false,
            errorMessage: 'Parameters are required'
        };
        if (action.paramSchema && 'object' == typeof action.paramSchema) {
            const schema = action.paramSchema;
            if (schema.shape || 'ZodObject' === schema.type) {
                const shape = schema.shape || {};
                const missingFields = Object.keys(shape).filter((key)=>{
                    const fieldDef = shape[key];
                    const isOptional = fieldDef?.isOptional || fieldDef?._def?.innerType || fieldDef?._def?.typeName === 'ZodOptional';
                    return !isOptional && (void 0 === value.params[key] || '' === value.params[key]);
                });
                if (missingFields.length > 0) return {
                    valid: false,
                    errorMessage: `Missing required parameters: ${missingFields.join(', ')}`
                };
            }
        }
        return {
            valid: true
        };
    }
    async parseStructuredParams(action, params, options) {
        return await parseStructuredParams(action, params, options);
    }
    formatErrorMessage(error) {
        const message = error?.message || '';
        const androidErrors = [
            {
                keyword: 'adb',
                message: 'ADB connection error. Please ensure device is connected and USB debugging is enabled.'
            },
            {
                keyword: 'UIAutomator',
                message: 'UIAutomator error. Please ensure the UIAutomator server is running on the device.'
            }
        ];
        const androidError = androidErrors.find(({ keyword })=>message.includes(keyword));
        if (androidError) return androidError.message;
        return this.formatBasicErrorMessage(error);
    }
    async executeAction(actionType, value, options) {
        return this.executeViaServer(actionType, value, options);
    }
    async executeViaServer(actionType, value, options) {
        const payload = {
            type: actionType,
            prompt: value.prompt,
            ...this.buildOptionalPayloadParams(options, value)
        };
        if (options.context) payload.context = options.context;
        options.requestId && this.dumpUpdateCallback;
        try {
            return await window.electron?.ipcRenderer.invoke('playground:execute', payload);
        } catch (error) {
            console.error('Execute via server failed:', error);
            throw error;
        } finally{
            this.stopProgressPolling();
        }
    }
    buildOptionalPayloadParams(options, value) {
        const optionalParams = {};
        const optionalFields = [
            {
                key: 'requestId',
                value: options.requestId
            },
            {
                key: 'deepLocate',
                value: options.deepLocate
            },
            {
                key: 'deepThink',
                value: options.deepThink
            },
            {
                key: 'screenshotIncluded',
                value: options.screenshotIncluded
            },
            {
                key: 'domIncluded',
                value: options.domIncluded
            },
            {
                key: 'deviceOptions',
                value: options.deviceOptions
            },
            {
                key: 'params',
                value: value.params
            }
        ];
        optionalFields.forEach(({ key, value })=>{
            if (null != value && '' !== value) optionalParams[key] = value;
        });
        return optionalParams;
    }
    async getActionSpace(context) {
        try {
            const result = await window.electron?.ipcRenderer.invoke('playground:action-space', {
                context
            });
            return Array.isArray(result) ? result : [];
        } catch (error) {
            console.error('Failed to get action space from server:', error);
            return [];
        }
    }
    async checkStatus() {
        try {
            return await window.electron?.ipcRenderer.invoke('playground:status');
        } catch (error) {
            console.warn('Server status check failed:', error);
            return false;
        }
    }
    async overrideConfig(aiConfig) {
        try {
            await window.electron?.ipcRenderer.invoke('playground:config', {
                aiConfig
            });
        } catch (error) {
            console.error('Failed to override server config:', error);
            throw error;
        }
    }
    async runConnectivityTest() {
        return await window.electron?.ipcRenderer.invoke('playground:connectivity-test');
    }
    async getTaskProgress(requestId) {
        if (!requestId?.trim()) {
            console.warn('Invalid requestId provided for task progress');
            return {};
        }
        try {
            return await window.electron?.ipcRenderer.invoke('playground:task-progress', encodeURIComponent(requestId));
        } catch (error) {
            console.error('Failed to poll task progress:', error);
            return {};
        }
    }
    startProgressPolling(requestId) {
        this.stopProgressPolling();
        this.pollingIntervalId = setInterval(async ()=>{
            try {
                const progressData = await this.getTaskProgress(requestId);
                if (progressData.executionDump) {
                    if (this.dumpUpdateCallback) this.dumpUpdateCallback('', progressData.executionDump);
                }
            } catch (error) {
                console.error('Error polling task progress:', error);
            }
        }, 500);
    }
    stopProgressPolling() {
        if (this.pollingIntervalId) {
            clearInterval(this.pollingIntervalId);
            this.pollingIntervalId = void 0;
        }
    }
    async cancelTask(requestId) {
        if (!requestId?.trim()) return {
            error: 'Invalid request ID'
        };
        try {
            const result = await window.electron?.ipcRenderer.invoke('playground:cancel', encodeURIComponent(requestId));
            return {
                success: true,
                ...result
            };
        } catch (error) {
            console.error('Failed to cancel task:', error);
            return {
                error: 'Failed to cancel task'
            };
        }
    }
    async getScreenshot() {
        try {
            return await window.electron?.ipcRenderer.invoke('playground:screenshot');
        } catch (error) {
            console.error('Failed to get screenshot:', error);
            return null;
        }
    }
    async getInterfaceInfo() {
        try {
            return await window.electron?.ipcRenderer.invoke('playground:interface-info');
        } catch (error) {
            console.error('Failed to get interface info:', error);
            return null;
        }
    }
    async getRuntimeInfo() {
        try {
            return await window.electron?.ipcRenderer.invoke('playground:runtime-info');
        } catch (error) {
            console.error('Failed to get runtime info:', error);
            return null;
        }
    }
    async getSessionInfo() {
        try {
            return await window.electron?.ipcRenderer.invoke('playground:session');
        } catch (error) {
            console.error('Failed to get session info:', error);
            return null;
        }
    }
    async getSessionSetup(input) {
        try {
            const searchParams = {};
            Object.entries(input || {}).forEach(([key, value])=>{
                if ('string' == typeof value || 'number' == typeof value || 'boolean' == typeof value) searchParams[key] = String(value);
            });
            return await window.electron?.ipcRenderer.invoke('playground:session-setup', searchParams);
        } catch (error) {
            console.error('Failed to get session setup:', error);
            throw error;
        }
    }
    async listSessionTargets() {
        try {
            const result = await window.electron?.ipcRenderer.invoke('playground:session-targets');
            return Array.isArray(result) ? result : [];
        } catch (error) {
            console.error('Failed to get session targets:', error);
            throw error;
        }
    }
    async createSession(input) {
        return await window.electron?.ipcRenderer.invoke('playground:session-create', input || {});
    }
    async destroySession() {
        return await window.electron?.ipcRenderer.invoke('playground:session-delete');
    }
    constructor(...args){
        super(...args), _define_property(this, "_id", void 0), _define_property(this, "dumpUpdateCallback", void 0), _define_property(this, "pollingIntervalId", void 0);
    }
}
export { ElectronExecutionAdapter };
