import { __awaiter } from "tslib";
import { loadCmdModule } from '../cmd-loader';
import * as Babel from '@babel/standalone';
import { runtime } from '../index';
let cancelPrevModLoader;
export function evalCodeCodules(modulesByScope, opts) {
    return __awaiter(this, void 0, void 0, function* () {
        // @ts-ignore
        const runtimeWindow = opts.runtimeWindow || runtime.previewWindow;
        if (!runtimeWindow) {
            return;
        }
        opts.onCodeError = opts.onCodeError || defaultCodeErrorHandler;
        const entries = [];
        const preload = {};
        const externalMap = opts.externals || {};
        for (const nodeModule in externalMap) {
            preload[nodeModule] = transformCode(`module.exports=${externalMap[nodeModule]}`);
        }
        for (const scope in modulesByScope) {
            // eslint-disable-line
            const modules = modulesByScope[scope];
            modules.forEach((m) => {
                const file = getModuleFilePath(scope, m.path);
                try {
                    preload[file] = transformCode(m.code);
                    entries.push(file);
                }
                catch (e) {
                    opts.onCodeError(e, file);
                    runtimeWindow.console.error(`${file}: ${e}`);
                }
            });
        }
        if (!opts.disableAutoCancelPrev && cancelPrevModLoader) {
            cancelPrevModLoader();
        }
        const { promise, cancel } = loadCmdModule(entries, {
            // const { promise, cancel } = loadEsModule(entries, {
            preload,
            dependencies: opts.dependencies,
            onDependencyMiss: opts.onDependencyMiss,
            runtime: runtimeWindow,
            onModuleError: (e) => {
                runtimeWindow.console.error(e.stack);
            },
            onError: (e) => {
                var _a, _b;
                (_b = (_a = runtimeWindow === null || runtimeWindow === void 0 ? void 0 : runtimeWindow.console) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.call(_a, e.stack);
            },
        });
        !opts.disableAutoCancelPrev && (cancelPrevModLoader = cancel);
        const loaded = yield promise;
        const result = {};
        for (const scope in modulesByScope) {
            // eslint-disable-line
            const modules = modulesByScope[scope];
            result[scope] = modules.map((m) => {
                const file = getModuleFilePath(scope, m.path);
                return Object.assign(Object.assign({}, m), { exports: loaded[file] });
            });
        }
        return result;
    });
}
function transformCode(srcCode) {
    // return srcCode;
    // eslint-disable-next-line no-undef
    return Babel.transform(srcCode, {
        presets: ['env', 'react'],
    }).code;
}
function getModuleFilePath(pageId, path) {
    const file = `/${path}`;
    if (pageId === 'global') {
        return file.replace('/global', '');
    }
    return file;
}
function defaultCodeErrorHandler(e, file) {
    console.error('Lowcode syntax error', file, e);
}
export function getDefaultModule(targetModule) {
    if (!targetModule) {
        return targetModule;
    }
    const keys = Object.keys(targetModule);
    if (keys.length === 1 && keys[0] === 'default') {
        return targetModule.default;
    }
    return targetModule;
}
