"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateSystemPackNpmRelationList = exports.mergePackNpmRelationList = exports.mergeSubPackages = exports.generateMpConfig = void 0;
const path = __importStar(require("path"));
const lodash_1 = require("lodash");
const mp_1 = require("@cloudbase/lowcode-generator/lib/generator/config/mp");
const weapps_core_1 = require("@cloudbase/lowcode-generator/lib/weapps-core");
const config_1 = require("../config");
const net_1 = require("../util/net");
const chalk_1 = __importDefault(require("chalk"));
const util_1 = require("../util");
/**
 * generate app.json & page.json for mp
 *
 * @param kboneConfig https://wechat-miniprogram.github.io/kbone/docs/config/
 * @param appConfigs app config from prop edit panel
 */
async function generateMpConfig(ctx, weapps, calses, options) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _j;
    const appConfig = {
        useExtendedLib: { weui: true },
    };
    const { miniprogramPlugins = [] } = ctx;
    const projConfig = (0, lodash_1.merge)({}, mp_1.defaultProjConfig, {
        projectname: (ctx.mainAppData && ctx.mainAppData.label) || `WeDa-${ctx.appId}`,
        appid: (options === null || options === void 0 ? void 0 : options.mpAppId) || mp_1.defaultProjConfig.appid,
    });
    const pageConfigs = weapps.map((app) => {
        var _a;
        const pageConfig = {};
        // #1 Get page config from mp config
        const kbConfig = (_a = app.lowCodes) === null || _a === void 0 ? void 0 : _a.find((m) => m.name === config_1.MP_CONFIG_MODULE_NAME);
        if (kbConfig) {
            const { pagesConfigJson = {} } = eval(`(${kbConfig.code.replace(/export\s+default/, '')})`);
            (0, lodash_1.merge)(pageConfig, pagesConfigJson);
        }
        // #2 Get page config from page page.data editor UI
        (0, lodash_1.merge)(pageConfig, getAppPagesConfig((app === null || app === void 0 ? void 0 : app.pageInstanceList) || []));
        return pageConfig;
    });
    const kbConfig = (_a = weapps[0].lowCodes) === null || _a === void 0 ? void 0 : _a.find((m) => m.name === config_1.MP_CONFIG_MODULE_NAME);
    const { tradingCapability, ...mainAppConfig } = weapps[0].appConfig || {};
    // keep main app config only, ignore subapp config
    const configs = (kbConfig ? [eval(`(${kbConfig.code.replace(/export\s+default/, '')})`)] : []).concat([
        { appJson: mainAppConfig },
        {
            ...options.mpConfig,
            appJson: ((_b = options.mpConfig) === null || _b === void 0 ? void 0 : _b.appJson)
                ? {
                    ...(_c = options.mpConfig) === null || _c === void 0 ? void 0 : _c.appJson,
                    sitemapLocation: undefined,
                }
                : {},
        },
    ]);
    configs.forEach((config) => {
        if (config) {
            const { projectConfigJson = {}, appJson = {} } = config;
            // # project.config.json, https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html
            (0, lodash_1.merge)(projConfig, projectConfigJson);
            (0, lodash_1.merge)(appConfig, appJson);
        }
    });
    // 若存在 wedaRoot，则正规化
    if (projConfig.wedaRoot) {
        projConfig.wedaRoot = (0, util_1.normalizeWedaRoot)(projConfig.wedaRoot);
    }
    // # app.json, https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html
    if (appConfig.tabBar) {
        await parseTabConfig(appConfig.tabBar, path.posix.join(ctx.projDir, projConfig.miniprogramRoot || ''), path.posix.join('./', projConfig.wedaRoot || ''));
    }
    /**
     * 基础配置合并完成
     * 开启特殊合并合并/覆盖逻辑
     */
    projConfig.packOptions.ignore.push(...ctx.materialLibs
        .filter((lib) => !lib.isComposite)
        .reduce((arr, lib) => {
        arr.push({
            type: 'file',
            value: path.posix.join(projConfig.wedaRoot || '', `${config_1.materialsDirName}/${lib.name}/meta.json`),
        });
        return arr;
    }, []));
    /**
     * 合并追加系统页面子包
     */
    const { subpackages, pages = [] } = extractPages(weapps, pageConfigs, { wedaRoot: projConfig.wedaRoot });
    appConfig.pages = Array.from(new Set([...(appConfig.pages || []), ...pages]));
    appConfig.subpackages = mergeSubPackages(((_e = (_d = appConfig.subpackages) === null || _d === void 0 ? void 0 : _d.filter) === null || _e === void 0 ? void 0 : _e.call(_d, (item) => item.name !== 'wd-sys-module' && item.name !== 'wd-sys-materials')) || [], [
        {
            root: path.posix.join(projConfig.wedaRoot || '', 'packages/$wd_system'),
            name: 'wd-sys-module',
            pages: ((_g = (_f = calses === null || calses === void 0 ? void 0 : calses[0]) === null || _f === void 0 ? void 0 : _f.extra) === null || _g === void 0 ? void 0 : _g.loginConfigVersion) ? ['pages/login/index'] : [],
        },
    ]
        .concat(ctx.enableAsyncMaterials
        ? [
            {
                root: path.posix.join(projConfig.wedaRoot || '', config_1.materialsDirName),
                name: 'wd-sys-materials',
                pages: [],
            },
        ]
        : [])
        .concat(subpackages));
    /**
     * 补全交易插件
     */
    if (tradingCapability) {
        const tradePluginKey = `weda-mini-shop-plugin`;
        const pluginMeta = {
            version: 'latest',
            provider: 'wx34345ae5855f892d',
        };
        let { plugins = {} } = appConfig;
        let find = false;
        for (let key in plugins) {
            let value = plugins[key];
            if (key === tradePluginKey || value.provider === pluginMeta.provider) {
                find = true;
                break;
            }
        }
        if (!find) {
            plugins[tradePluginKey] = pluginMeta;
        }
        appConfig.plugins = plugins;
    }
    miniprogramPlugins.forEach((plugin) => {
        var _a;
        if (!((_a = appConfig === null || appConfig === void 0 ? void 0 : appConfig.plugins) === null || _a === void 0 ? void 0 : _a[plugin.name])) {
            (0, lodash_1.set)(appConfig, `plugins.${plugin.name}`, {
                version: plugin.version,
                provider: plugin.pluginAppId,
            });
        }
    });
    if (!projConfig.setting) {
        projConfig.setting = {};
    }
    // projConfig.setting.compileHotReLoad = false;
    projConfig.setting.bigPackageSizeSupport = true;
    projConfig.setting.packNpmManually = true;
    if (!projConfig.setting.packNpmRelationList) {
        projConfig.setting.packNpmRelationList = [];
    }
    projConfig.setting.packNpmRelationList = mergePackNpmRelationList(generateSystemPackNpmRelationList(path.posix.join('./', projConfig.miniprogramRoot || '/', projConfig.wedaRoot || '')), ((_j = (_h = projConfig.setting.packNpmRelationList) === null || _h === void 0 ? void 0 : _h.filter) === null || _j === void 0 ? void 0 : _j.call(_h, (item) => {
        return !/\/packages\/\$wd_system\/package.json/.test(item.packageJsonPath);
    })) || []);
    if (process.env.IS_WEB_WORKER) {
        projConfig.setting.ignoreUploadUnusedFiles = true;
    }
    if (options.mpAppId) {
        projConfig.appId = options.mpAppId;
    }
    // merge(pageConfigs, extractAllPagesConfig())
    return { appConfig, projConfig, pageConfigs };
}
exports.generateMpConfig = generateMpConfig;
function extractPages(weapps, pageConfigs, options) {
    const pages = [];
    const subpackages = [];
    let homePage = '';
    const { wedaRoot } = options || {};
    weapps.forEach((weapp, index) => {
        const { rootPath } = weapp;
        const subPackage = { root: rootPath ? path.posix.join('./', wedaRoot || '', `packages/${rootPath}`) : '', pages: [] };
        if (rootPath) {
            subpackages.push(subPackage);
        }
        (0, weapps_core_1.loopDealWithFn)(weapp.pageInstanceList || [], (page) => {
            const pageConfig = pageConfigs[index];
            const pageFileName = (0, lodash_1.get)(pageConfig, `${page.id}.pageFileName`, 'index');
            if (rootPath) {
                subPackage.pages.push(`pages/${page.id}/${pageFileName}`);
            }
            else if (!page.isHome) {
                pages.push(path.posix.join('./', wedaRoot || '', `pages/${page.id}/${pageFileName}`));
            }
            else {
                homePage = path.posix.join('./', wedaRoot || '', `pages/${page.id}/${pageFileName}`);
            }
        });
    });
    if (homePage) {
        pages.unshift(homePage);
    }
    return { pages, subpackages };
}
function getAppPagesConfig(pages = []) {
    const pagesConfig = {};
    pages.map((page) => {
        const pageConfig = transformDynamicData(page.data);
        delete pageConfig['title'];
        pagesConfig[page.id] = pageConfig;
    });
    return pagesConfig;
}
function transformDynamicData(originData) {
    const temp = {};
    for (const key in originData) {
        const target = originData[key];
        if ((target === null || target === void 0 ? void 0 : target.value) && ((target === null || target === void 0 ? void 0 : target.type) === 'static' || !(target === null || target === void 0 ? void 0 : target.type))) {
            temp[key] = target.value;
        }
    }
    return temp;
}
function parseTabConfig(tabBar, miniprogramRoot, wedaRoot) {
    var _a, _b;
    async function parseTabIcon(iconUrl, index, filename) {
        if (typeof iconUrl !== 'string') {
            console.error(chalk_1.default.red('App.json invalid tabbar icon path'), iconUrl);
            return;
        }
        const iconPath = path.posix.join('./', wedaRoot || '/', `assets/tab${index}/${filename}${path.extname(iconUrl)}`);
        await (0, net_1.downloadFile)(iconUrl, `${miniprogramRoot}/${iconPath}`).catch((e) => {
            console.error(chalk_1.default.red(`Fail to download tabBar icon from ${iconUrl}`), e);
            throw e;
        });
        return iconPath;
    }
    return Promise.all(((_b = (_a = tabBar.list) === null || _a === void 0 ? void 0 : _a.map) === null || _b === void 0 ? void 0 : _b.call(_a, async (tab, index) => {
        const { iconPath, selectedIconPath } = tab;
        if (iconPath && /^http(s):\/\//.test(iconPath)) {
            try {
                tab.iconPath = await parseTabIcon(iconPath, index, 'icon');
            }
            catch (e) { }
        }
        if (selectedIconPath && /^http(s):\/\//.test(selectedIconPath)) {
            try {
                tab.selectedIconPath = await parseTabIcon(selectedIconPath, index, 'selectedIcon');
            }
            catch (e) { }
        }
    })) || []);
}
function mergeSubPackages(base = [], extra = []) {
    const baseMap = base.reduce((map, item) => {
        map[item.root] = item;
        return map;
    }, {});
    for (const subpackage of extra) {
        if (!baseMap[subpackage.root]) {
            base.push(subpackage);
            continue;
        }
        const current = baseMap[subpackage.root];
        current.pages = Array.from(new Set([...(current.pages || []), ...(subpackage.pages || [])]));
        if (current.plugins || subpackage.plugins) {
            current.plugins = (0, lodash_1.merge)(current.plugins, subpackage.plugins);
        }
    }
    return base;
}
exports.mergeSubPackages = mergeSubPackages;
function mergePackNpmRelationList(base = [], extra = []) {
    const baseMap = base.reduce((map, item) => {
        map[path.posix.join('./', item.packageJsonPath, 'fake')] = true;
        return map;
    }, {});
    const res = [...base];
    extra.forEach((item) => {
        const key = path.posix.join('./', item.packageJsonPath, 'fake');
        if (!baseMap[key]) {
            res.push(item);
        }
    });
    return res;
}
exports.mergePackNpmRelationList = mergePackNpmRelationList;
function generateSystemPackNpmRelationList(wedaRootProjectPath) {
    return [
        {
            packageJsonPath: path.posix.join(wedaRootProjectPath || './', 'package.json'),
            miniprogramNpmDistDir: wedaRootProjectPath || './',
        },
        {
            packageJsonPath: path.posix.join(wedaRootProjectPath || './', 'packages', '$wd_system', 'package.json'),
            miniprogramNpmDistDir: path.posix.join(wedaRootProjectPath || './', 'packages', '$wd_system'),
        },
    ];
}
exports.generateSystemPackNpmRelationList = generateSystemPackNpmRelationList;
