/**
 * Main thread Worker host — thin shim that keeps UI responsive.
 *
 * Responsibilities:
 *   1. Create Worker and proxy mailxapi calls to it
 *   2. Proxy TCP calls from Worker to msgapi.tcp (C# native bridge)
 *   3. Proxy native bridge calls (OAuth, device info)
 *   4. Forward events from Worker to UI event handlers
 *   5. Set up visibilitychange/periodic sync triggers
 *
 * The UI code (api-client.ts) calls window.mailxapi.* exactly as before —
 * this host just routes those calls to the Worker instead of running them inline.
 */
const eventHandlers = [];
let worker;
let rpcCounter = 0;
const pendingRpc = new Map();
// ── Worker communication ──
function sendRpc(action, params = {}) {
    const id = ++rpcCounter;
    return new Promise((resolve, reject) => {
        pendingRpc.set(id, { resolve, reject });
        worker.postMessage({ type: "rpc", id, action, params });
        // 5-minute timeout for long operations like syncAll
        setTimeout(() => {
            if (pendingRpc.has(id)) {
                pendingRpc.delete(id);
                reject(new Error(`RPC ${action} timeout`));
            }
        }, 300000);
    });
}
// ── TCP proxy: relay Worker TCP requests to msgapi.tcp ──
function handleTcpRequest(msg) {
    const msgapi = window.msgapi;
    if (!msgapi?.tcp) {
        worker.postMessage({ type: "tcp-response", reqId: msg.reqId, error: "TCP bridge not available" });
        return;
    }
    switch (msg.op) {
        case "connect": {
            msgapi.tcp.connect(msg.host, msg.port, msg.tls)
                .then((streamId) => {
                const sid = Number(streamId);
                // Register event forwarding for this stream
                msgapi.tcp.onData(sid, (data) => {
                    worker.postMessage({ type: "tcp-data", streamId: sid, data });
                });
                msgapi.tcp.onClose(sid, (hadError) => {
                    worker.postMessage({ type: "tcp-close", streamId: sid, hadError });
                });
                msgapi.tcp.onError(sid, (message) => {
                    worker.postMessage({ type: "tcp-error", streamId: sid, message });
                });
                worker.postMessage({ type: "tcp-response", reqId: msg.reqId, result: String(sid) });
            })
                .catch((e) => {
                worker.postMessage({ type: "tcp-response", reqId: msg.reqId, error: e.message });
            });
            break;
        }
        case "write": {
            const data = msg.data;
            // btoa for the bridge (C# expects base64)
            msgapi.tcp.write(msg.streamId, data)
                .then(() => {
                worker.postMessage({ type: "tcp-response", reqId: msg.reqId, result: "ok" });
            })
                .catch((e) => {
                worker.postMessage({ type: "tcp-response", reqId: msg.reqId, error: e.message });
            });
            break;
        }
        case "upgradeTLS": {
            msgapi.tcp.upgradeTLS(msg.streamId, msg.servername)
                .then(() => {
                worker.postMessage({ type: "tcp-response", reqId: msg.reqId, result: "ok" });
            })
                .catch((e) => {
                worker.postMessage({ type: "tcp-response", reqId: msg.reqId, error: e.message });
            });
            break;
        }
        case "close": {
            try {
                msgapi.tcp.close(msg.streamId);
            }
            catch { /* ignore */ }
            break;
        }
    }
}
// ── Native bridge proxy: relay Worker native requests ──
function handleNativeRequest(msg) {
    const bridge = window._nativeBridge;
    switch (msg.op) {
        case "refreshToken": {
            const email = msg.args?.[0];
            if (bridge?.app?.startOAuth) {
                // Use the existing OAuth flow
                // For now, use the cached token or refresh
                bridge.app.refreshToken?.(email)
                    .then((token) => {
                    worker.postMessage({ type: "native-response", reqId: msg.reqId, result: token });
                })
                    .catch((e) => {
                    worker.postMessage({ type: "native-response", reqId: msg.reqId, error: e.message });
                });
            }
            else {
                worker.postMessage({ type: "native-response", reqId: msg.reqId, error: "No OAuth bridge" });
            }
            break;
        }
        case "vlog": {
            // Verbose logging via logit
            const text = msg.args?.[0] || "";
            fetch(`https://rmf39.aaz.lt/logit/${encodeURIComponent("V/" + text)}?log=mailx-android`).catch(() => { });
            break;
        }
        case "getAndroidId": {
            bridge?.app?.getAndroidId?.()
                .then((id) => {
                worker.postMessage({ type: "native-response", reqId: msg.reqId, result: id });
            })
                .catch((e) => {
                worker.postMessage({ type: "native-response", reqId: msg.reqId, error: e.message });
            });
            break;
        }
        case "getDeviceAccounts": {
            bridge?.app?.getDeviceAccounts?.()
                .then((accounts) => {
                worker.postMessage({ type: "native-response", reqId: msg.reqId, result: accounts });
            })
                .catch((e) => {
                worker.postMessage({ type: "native-response", reqId: msg.reqId, error: e.message });
            });
            break;
        }
        case "localStorageGet": {
            const key = msg.args?.[0];
            worker.postMessage({ type: "native-response", reqId: msg.reqId, result: localStorage.getItem(key) });
            break;
        }
        case "localStorageSet": {
            const [key, value] = msg.args || [];
            localStorage.setItem(key, value);
            worker.postMessage({ type: "native-response", reqId: msg.reqId, result: "ok" });
            break;
        }
        default: {
            worker.postMessage({ type: "native-response", reqId: msg.reqId, error: `Unknown native op: ${msg.op}` });
        }
    }
}
// ── Event handling ──
function handleWorkerEvent(event) {
    for (const handler of eventHandlers) {
        try {
            handler(event);
        }
        catch { /* ignore */ }
    }
    // Also dispatch to the global host service-channel event callback
    const cb = window._msgapiServiceEvent;
    if (cb)
        try {
            cb(event);
        }
        catch { /* ignore */ }
}
// ── Worker message router ──
function onWorkerMessage(e) {
    const msg = e.data;
    if (msg.type === "rpc-response") {
        const pending = pendingRpc.get(msg.id);
        if (pending) {
            pendingRpc.delete(msg.id);
            if (msg.error)
                pending.reject(new Error(msg.error));
            else
                pending.resolve(msg.result);
        }
        return;
    }
    if (msg.type === "event") {
        handleWorkerEvent(msg.event);
        return;
    }
    if (msg.type === "tcp") {
        handleTcpRequest(msg);
        return;
    }
    if (msg.type === "native") {
        handleNativeRequest(msg);
        return;
    }
    if (msg.type === "init-complete") {
        console.log("[host] Worker initialization complete");
        return;
    }
    if (msg.type === "init-error") {
        console.error(`[host] Worker init failed: ${msg.error}`);
        return;
    }
}
// ── Install mailxapi bridge (same interface as before, routes to Worker) ──
function installBridge() {
    window.mailxapi = {
        isApp: true,
        platform: "android",
        // All service methods proxy to the Worker
        getAccounts: () => sendRpc("getAccounts"),
        getFolders: (accountId) => sendRpc("getFolders", { accountId }),
        getMessages: (accountId, folderId, page, pageSize) => sendRpc("getMessages", { accountId, folderId, page, pageSize }),
        getUnifiedInbox: (page, pageSize) => sendRpc("getUnifiedInbox", { page, pageSize }),
        getMessage: (accountId, uid, allowRemote, folderId) => sendRpc("getMessage", { accountId, uid, allowRemote, folderId }),
        getAttachment: (accountId, uid, index, folderId) => sendRpc("getAttachment", { accountId, uid, index, folderId }),
        updateFlags: (accountId, uid, flags) => sendRpc("updateFlags", { accountId, uid, flags }),
        deleteMessage: (accountId, uid) => sendRpc("deleteMessage", { accountId, uid }),
        deleteMessages: (accountId, uids) => sendRpc("deleteMessages", { accountId, uids }),
        undeleteMessage: (accountId, uid, folderId) => sendRpc("undeleteMessage", { accountId, uid, folderId }),
        moveMessage: (accountId, uid, targetFolderId, targetAccountId) => sendRpc("moveMessage", { accountId, uid, targetFolderId, targetAccountId }),
        moveMessages: (accountId, uids, targetFolderId) => sendRpc("moveMessages", { accountId, uids, targetFolderId }),
        markFolderRead: (folderId) => sendRpc("markFolderRead", { folderId }),
        sendMessage: async (msg) => { await sendRpc("sendMessage", msg); return { ok: true }; },
        saveDraft: (p) => sendRpc("saveDraft", p),
        deleteDraft: (accountId, draftUid) => sendRpc("deleteDraft", { accountId, draftUid }),
        syncAll: () => sendRpc("syncAll"),
        syncAccount: (accountId) => sendRpc("syncAccount", { accountId }),
        triggerSync: () => sendRpc("syncAll"),
        getSyncPending: () => sendRpc("getSyncPending"),
        reauthenticate: (accountId) => sendRpc("reauthenticate", { accountId }),
        searchMessages: (query, page, pageSize) => sendRpc("searchMessages", { query, page, pageSize }),
        searchContacts: (query) => sendRpc("searchContacts", { query }),
        listContacts: (query, page = 1, pageSize = 100) => sendRpc("listContacts", { query, page, pageSize }),
        upsertContact: (name, email) => sendRpc("upsertContact", { name, email }),
        deleteContact: (email) => sendRpc("deleteContact", { email }),
        addContact: (name, email) => sendRpc("addContact", { name, email }),
        getSettings: () => sendRpc("getSettings"),
        saveSettings: (data) => sendRpc("saveSettingsData", data),
        allowRemoteContent: (type, value) => sendRpc("allowRemoteContent", { type, value }),
        getVersion: () => sendRpc("getVersion"),
        getAutocompleteSettings: () => sendRpc("getAutocompleteSettings"),
        saveAutocompleteSettings: (data) => sendRpc("saveAutocompleteSettings", data),
        emptyFolder: (accountId, folderId) => sendRpc("emptyFolder", { accountId, folderId }),
        resetAll: () => sendRpc("resetStore"),
        // Event registration
        onEvent: (handler) => { eventHandlers.push(handler); },
    };
}
export {};
// ── Public entry point ──
//# sourceMappingURL=main-thread-host.js.map