import { callLepusMethodEndpoint, setNativePropsEndpoint, triggerComponentEventEndpoint, selectComponentEndpoint, reportErrorEndpoint, queryComponentEndpoint, updateBTSChunkEndpoint, } from '../../endpoints.js';
import { createInvokeUIMethod } from './crossThreadHandlers/createInvokeUIMethod.js';
import { registerPublicComponentEventHandler } from './crossThreadHandlers/registerPublicComponentEventHandler.js';
import { createNativeModules } from './createNativeModules.js';
import { registerUpdateDataHandler } from './crossThreadHandlers/registerUpdateDataHandler.js';
import { registerPublishEventHandler } from './crossThreadHandlers/registerPublishEventHandler.js';
import { createPerformanceApis } from './createPerformanceApis.js';
import { registerSendGlobalEventHandler } from './crossThreadHandlers/registerSendGlobalEvent.js';
import { createJSObjectDestructionObserver } from './crossThreadHandlers/createJSObjectDestructionObserver.js';
import { registerUpdateGlobalPropsHandler } from './crossThreadHandlers/registerUpdateGlobalPropsHandler.js';
import { registerUpdateI18nResource } from './crossThreadHandlers/registerUpdateI18nResource.js';
import { createGetPathInfo } from './crossThreadHandlers/createGetPathInfo.js';
import { createChunkLoading } from './createChunkLoading.js';
let nativeAppCount = 0;
const sharedData = {};
class I18nResource {
    data;
    constructor(data) {
        this.data = data;
    }
    setData(data) {
        this.data = data;
    }
}
export async function createNativeApp(mainThreadRpc, timingSystem, nativeModulesMap, entryTemplateUrl) {
    const performanceApis = createPerformanceApis(timingSystem);
    const callLepusMethod = mainThreadRpc.createCallbackify(callLepusMethodEndpoint, 2);
    const setNativeProps = mainThreadRpc.createCall(setNativePropsEndpoint);
    const triggerComponentEvent = mainThreadRpc.createCall(triggerComponentEventEndpoint);
    const selectComponent = mainThreadRpc.createCallbackify(selectComponentEndpoint, 3);
    const queryComponent = mainThreadRpc.createCall(queryComponentEndpoint);
    const reportError = mainThreadRpc.createCall(reportErrorEndpoint);
    const { templateCache, loadScript, loadScriptAsync, readScript } = createChunkLoading(entryTemplateUrl);
    mainThreadRpc.registerHandler(updateBTSChunkEndpoint, (url, btsChunkUrls) => {
        templateCache.set(url, btsChunkUrls);
    });
    const i18nResource = new I18nResource();
    let release = '';
    const nativeApp = {
        id: (nativeAppCount++).toString(),
        ...performanceApis,
        setTimeout: setTimeout,
        setInterval: setInterval,
        clearTimeout: clearTimeout,
        clearInterval: clearInterval,
        nativeModuleProxy: await createNativeModules(mainThreadRpc, mainThreadRpc, nativeModulesMap),
        readScript,
        loadScriptAsync,
        loadScript,
        requestAnimationFrame(cb) {
            return requestAnimationFrame(cb);
        },
        cancelAnimationFrame(handler) {
            return cancelAnimationFrame(handler);
        },
        callLepusMethod,
        setNativeProps,
        getPathInfo: createGetPathInfo(mainThreadRpc),
        invokeUIMethod: createInvokeUIMethod(mainThreadRpc),
        tt: null,
        setCard(tt) {
            registerPublicComponentEventHandler(mainThreadRpc, tt);
            registerPublishEventHandler(mainThreadRpc, tt);
            registerUpdateDataHandler(mainThreadRpc, tt);
            registerSendGlobalEventHandler(mainThreadRpc, tt);
            registerUpdateGlobalPropsHandler(mainThreadRpc, tt);
            registerUpdateI18nResource(mainThreadRpc, i18nResource, tt);
            timingSystem.registerGlobalEmitter(tt.GlobalEventEmitter);
            tt.lynx.getCoreContext().__start();
            nativeApp.tt = tt;
        },
        triggerComponentEvent,
        selectComponent,
        createJSObjectDestructionObserver: createJSObjectDestructionObserver(),
        setSharedData(dataKey, dataVal) {
            sharedData[dataKey] = dataVal;
        },
        getSharedData(dataKey) {
            return sharedData[dataKey];
        },
        i18nResource,
        reportException: (err, _) => reportError(err, _, release),
        __SetSourceMapRelease: (err) => release = err.message,
        __GetSourceMapRelease: (_url) => release,
        queryComponent: (source, callback) => {
            if (templateCache.has(source)) {
                callback({ __hasReady: true });
            }
            else {
                queryComponent(source).then(res => {
                    callback?.(res);
                });
            }
        },
    };
    return nativeApp;
}
//# sourceMappingURL=createNativeApp.js.map