"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
// Import Libs and Handlers
var React = (0, tslib_1.__importStar)(require("react"));
var mobx_1 = require("mobx");
var lodash_es_1 = require("lodash-es");
var global_api_1 = require("../app/global-api"); // 取对应子包app
var RenderWrapper_1 = require("../handlers/RenderWrapper");
var weda_client_1 = require("@cloudbase/weda-client");
var index_1 = require("../utils/index");
var generate_1 = require("../utils/adapter/generate");
var lifecycle_1 = require("../utils/lifecycle");
var hooks_1 = require("../utils/hooks");
var global_api_2 = require("../app/global-api"); // 取主包app
var index_2 = require("../utils/adapter/index");
var qiankun_1 = require("qiankun");
var createDataset = weda_client_1._WEDA_CLOUD_SDK.createDataset, createStateDataSourceVar = weda_client_1._WEDA_CLOUD_SDK.createStateDataSourceVar, generateParamsParser = weda_client_1._WEDA_CLOUD_SDK.generateParamsParser, EXTRA_API = weda_client_1._WEDA_CLOUD_SDK.EXTRA_API;
// Import Actions
// Init
function App(_a) {
    var page = _a.page, generateComponentsMap = _a.generateComponentsMap, generateActionsMap = _a.generateActionsMap, generateLowcodeModule = _a.generateLowcodeModule, generateWidgetsContext = _a.generateWidgetsContext, generateDataBinds = _a.generateDataBinds, generateComponentSchema = _a.generateComponentSchema, generateContext = _a.generateContext, onRender = _a.onRender, onMounted = _a.onMounted, _b = _a.injectContext, injectContext = _b === void 0 ? {} : _b, _c = _a.initDataContext, initDataContext = _c === void 0 ? {} : _c, _d = _a.options, options = _d === void 0 ? { looseError: false, disabledCheckAuth: false } : _d;
    var _e = (0, tslib_1.__read)(React.useState(false), 2), pageContextInited = _e[0], setPageContextInited = _e[1];
    var _f = (0, tslib_1.__read)(React.useState(Date.now()), 2), _ = _f[0], setFourceUpdate = _f[1];
    // 数据容器的上下文数据
    var dataContextRef = React.useRef((0, mobx_1.observable)((injectContext === null || injectContext === void 0 ? void 0 : injectContext.dataContext) || initDataContext));
    var dataContext = dataContextRef.current;
    React.useEffect(function () {
        if (injectContext === null || injectContext === void 0 ? void 0 : injectContext.dataContext) {
            dataContextRef.current = (0, mobx_1.observable)(injectContext === null || injectContext === void 0 ? void 0 : injectContext.dataContext);
            setFourceUpdate(Date.now());
        }
    }, [injectContext === null || injectContext === void 0 ? void 0 : injectContext.dataContext]);
    // 兼容 this.state / $page.state 两种模式
    var pageCodeContextRef = React.useRef((injectContext === null || injectContext === void 0 ? void 0 : injectContext.$page) || (0, global_api_2.createPageApi)());
    var $page = pageCodeContextRef.current;
    var lowcode = generateLowcodeModule();
    var componentSchema, widgetsContext, databinds;
    React.useEffect(function () {
        if (!(injectContext === null || injectContext === void 0 ? void 0 : injectContext.$page)) {
            var dataset = createDataset(page.id);
            var state = (0, mobx_1.observable)(lowcode.state || {});
            state.dataset = dataset;
            Object.assign($page, {
                id: page.id,
                state: state,
                computed: (0, index_1.createComputed)(lowcode.computed || {}, pageCodeContextRef.current),
                handler: (0, index_1.bindFuncObj)(lowcode.handler || {}, pageCodeContextRef.current),
                dataset: dataset,
            });
        }
        setPageContextInited(true);
    }, []);
    if (pageContextInited) {
        var globalCtx = {
            $page: $page,
            app: global_api_1.app,
            $app: global_api_1.app,
            actionsMap: (generateActionsMap === null || generateActionsMap === void 0 ? void 0 : generateActionsMap()) || {},
        };
        if (generateContext) {
            var context = generateContext(globalCtx, { items: page.items });
            widgetsContext = context.widgetContext;
            databinds = context.dataBinds;
            componentSchema = context.componentSchema;
            // componentSchema = generateComponentSchema(globalCtx, page);
        }
        else {
            widgetsContext = generateWidgetsContext(page);
            databinds = generateDataBinds(globalCtx, page);
            componentSchema = generateComponentSchema(globalCtx, page);
        }
        // widgets 内的 dataBinds 可能需要关联 widgets，需要重新执行 dataBinds
        $page._dataBinds = databinds;
        $page.widgets = (0, index_1.createWidgets)(widgetsContext, $page._dataBinds || {}, dataContext);
        (0, index_1.retryDataBinds)();
    }
    return (pageContextInited && (React.createElement(AppContent, { page: page, lowcode: lowcode, componentSchema: componentSchema, pageCodeContext: pageCodeContextRef.current, virtualFields: generateComponentsMap(), onMounted: onMounted, onRender: onRender, dataContext: dataContext, 
        /**
         * 更新数据容器的上下文的方法
         * 会传递到事件emit的地方，将从组件获取到的数据data赋值给上下文
         * 当组件卸载时，传过来的data为undefined即可
         * {
         *   id1: [{...}],
         *   id2: {...},
         *   id3: undefined,
         *   id4: null,
         *   ...
         * }
         * @param id
         * @param data
         */
        updateContext: function (id, data) {
            var _a;
            if (id && !(injectContext === null || injectContext === void 0 ? void 0 : injectContext.dataContext)) {
                dataContext[id] = { data: data };
            }
            (_a = injectContext === null || injectContext === void 0 ? void 0 : injectContext.onDataContextChange) === null || _a === void 0 ? void 0 : _a.call(injectContext, id, data);
        }, options: options })));
}
exports.default = App;
function AppContent(_a) {
    var _this = this;
    var _b, _c, _d;
    var page = _a.page, lowcode = _a.lowcode, componentSchema = _a.componentSchema, pageCodeContext = _a.pageCodeContext, virtualFields = _a.virtualFields, _e = _a.onMounted, onMounted = _e === void 0 ? function (props) {
        var _a;
        (_a = props === null || props === void 0 ? void 0 : props.default) === null || _a === void 0 ? void 0 : _a.call(props);
    } : _e, _f = _a.onRender, onRender = _f === void 0 ? function () { } : _f, dataContext = _a.dataContext, updateContext = _a.updateContext, options = _a.options;
    // 检查权限
    var _g = (0, tslib_1.__read)(React.useState(false), 2), weDaHasLogin = _g[0], setWeDaHasLogin = _g[1];
    var containerRef = React.useRef(null);
    var microApp = React.useRef(null);
    var pureSrc = (_b = page.attributes) === null || _b === void 0 ? void 0 : _b.src;
    var isPure = !!pureSrc;
    // Web 环境页面级别生命周期
    (0, lifecycle_1.usePageLifeCycle)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, lowcode === null || lowcode === void 0 ? void 0 : lowcode.lifecycle), { beforePageCustomLaunch: function (query) { return (0, tslib_1.__awaiter)(_this, void 0, void 0, function () {
            var checkAuthResult, _a;
            return (0, tslib_1.__generator)(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        onMounted({
                            page: page,
                            default: function () {
                                var _a;
                                var document = (index_2.runtime === null || index_2.runtime === void 0 ? void 0 : index_2.runtime.document) || window.document;
                                document.title = ((_a = page.attributes) === null || _a === void 0 ? void 0 : _a.title) || page.id;
                            },
                        });
                        EXTRA_API.setParams(page.id, query || {});
                        initWatchMethods(pageCodeContext);
                        _a = (options === null || options === void 0 ? void 0 : options.disabledCheckAuth);
                        if (_a) return [3 /*break*/, 2];
                        return [4 /*yield*/, (0, index_1.checkAuth)(global_api_1.app, global_api_1.app.id, pageCodeContext)];
                    case 1:
                        _a = (_b.sent());
                        _b.label = 2;
                    case 2:
                        checkAuthResult = _a;
                        setWeDaHasLogin(checkAuthResult);
                        createStateDataSourceVar(page.id, generateParamsParser({ app: global_api_1.app, $page: pageCodeContext }));
                        onRender === null || onRender === void 0 ? void 0 : onRender();
                        return [2 /*return*/];
                }
            });
        }); } }), { app: global_api_1.app, page: pageCodeContext, options: { looseError: options === null || options === void 0 ? void 0 : options.looseError } });
    // 切换页面滚动到顶部
    (0, hooks_1.useScrollTop)();
    React.useEffect(function () {
        var _a, _b;
        if (isPure) {
            if (weDaHasLogin) {
                if (!microApp.current) {
                    microApp.current = (0, qiankun_1.loadMicroApp)({
                        name: page.id,
                        entry: pureSrc,
                        container: containerRef.current,
                    });
                }
                else {
                    (_b = (_a = microApp.current).mount) === null || _b === void 0 ? void 0 : _b.call(_a);
                }
            }
            else if (microApp.current) {
                microApp.current.unmount();
            }
        }
    }, [weDaHasLogin]);
    React.useEffect(function () {
        return function () {
            if (microApp.current) {
                microApp.current.unmount();
            }
        };
    }, []);
    return (React.createElement("div", { ref: containerRef, className: "weapps-page weapps-page-" + page.id },
        React.createElement("style", { type: "text/css", dangerouslySetInnerHTML: {
                __html: "" + (0, index_1.toCssText)(((_c = page.attributes) === null || _c === void 0 ? void 0 : _c.style) ||
                    (0, generate_1.toCssStyle)(((_d = page === null || page === void 0 ? void 0 : page.extra) === null || _d === void 0 ? void 0 : _d.commonStyle) || {}), 'body') + (lowcode.style || []).map(function (item) { return item.code; }).join('\n'),
            } }),
        weDaHasLogin && !isPure && (React.createElement(RenderWrapper_1.AppRender, { virtualFields: virtualFields, componentSchema: componentSchema, codeContext: pageCodeContext, dataContext: dataContext, updateContext: updateContext }))));
}
function initWatchMethods(pageContext) {
    // const { watch = {}, watchState = {}, watchWidget = {}, watchEffects = {}} = pageAPI
    var _a = {}, _b = _a.watch, watch = _b === void 0 ? {} : _b, _c = _a.watchState, watchState = _c === void 0 ? {} : _c, _d = _a.watchWidget, watchWidget = _d === void 0 ? {} : _d, _e = _a.watchEffects, watchEffects = _e === void 0 ? {} : _e;
    // # watch effect
    var watchEffectDisposers = Object.keys(watchEffects).map(function (fnName) {
        return (0, mobx_1.autorun)(watchEffects[fnName].bind(pageContext));
    });
    var disposers = watchEffectDisposers;
    // # watch state
    Object.keys(watchState).map(function (key) {
        return runWatcher(parseWatcher(watchState[key]), pageContext.state, key, 'watchState');
    });
    // # watch widgets
    Object.keys(watchWidget).map(function (key) {
        return runWatcher(parseWatcher(watchWidget[key]), pageContext.widgets, key, 'watchWidgets');
    });
    function runWatcher(_a, target, key, label) {
        var _b = _a === void 0 ? {} : _a, handler = _b.handler, immediate = _b.immediate;
        if (!handler) {
            console.error("Invalid " + label + "(" + key + ") of " + pageContext.node.widgetType + ", watch must a function or {handler: function}");
            return;
        }
        var disposer = (0, mobx_1.reaction)(function () { return (0, lodash_es_1.get)(target, key); }, handler.bind(pageContext), { fireImmediately: immediate });
        disposers.push(disposer);
    }
}
function parseWatcher(watcher) {
    if (!watcher)
        return;
    if (watcher instanceof Function) {
        return { handler: watcher, immediate: false };
    }
    var handler = watcher.handler, _a = watcher.immediate, immediate = _a === void 0 ? false : _a;
    if (!(handler instanceof Function))
        return;
    return { handler: handler, immediate: immediate };
}
//# sourceMappingURL=index.js.map