"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.initWebConfig = exports.usePageLifeCycle = exports.generatePageLifecycleHandlers = exports.removeAppLifeCycle = exports.initAppLifeCycle = void 0;
const tslib_1 = require("tslib");
/* eslint-disable @typescript-eslint/no-empty-function */
/**
 * 生命周期处理函数
 */
const React = tslib_1.__importStar(require("react"));
const lodash_es_1 = require("lodash-es");
const querystring = tslib_1.__importStar(require("query-string"));
const adapter_1 = require("./adapter");
const common_1 = require("./common");
const sso_1 = require("./sso");
// import { useHistory, useLocation } from 'react-router';
const error_handler_1 = require("./sso/error-handler");
const weda_client_1 = require("@cloudbase/weda-client");
const noops = () => { };
const APPLIFECYCLE = {
    onAppShow: noops,
    onAppHide: noops,
    onAppError: noops,
    onAppUnhandledRejection: noops,
    onAppLaunch: noops,
    beforeCustomLaunch: noops,
};
// 小程序 端使用lifeCycle
let alreadyInitAppLifeCycle = false;
let _HANDLER_MAP = {};
function initAppLifeCycle(app, appLifeCycle, force = false) {
    appLifeCycle = Object.assign(Object.assign({}, APPLIFECYCLE), appLifeCycle);
    function scheduleAppLifecycle() {
        var _a, _b, _c, _d, _e, _f;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const options = app.getLaunchOptionsSync();
            const { query = {} } = options;
            const { state, code } = query;
            if (common_1.ENABLE_WECOM && query.code && query.state) {
                try {
                    yield (0, sso_1.signInWidthProviderCode)(state, code);
                    yield weda_client_1.auth.getUserInfo(true);
                }
                catch (e) {
                    console.error(`企微登录失败: ${JSON.stringify({ state, code })}`, e);
                    app['showModal']({
                        content: `${(0, error_handler_1.parseProviderTokenError)(e)} [${JSON.stringify({
                            reqId: (e === null || e === void 0 ? void 0 : e.request_id) || '',
                            state,
                            code,
                        })}]`,
                        success(res) {
                            if (res.confirm) {
                                adapter_1.runtime.location.reload();
                            }
                        },
                    });
                    throw e;
                }
                finally {
                    delete query.state;
                    delete query.code;
                    delete query.appid;
                    const url = new URL(adapter_1.runtime.location.href);
                    (_b = (_a = url === null || url === void 0 ? void 0 : url.searchParams) === null || _a === void 0 ? void 0 : _a.delete) === null || _b === void 0 ? void 0 : _b.call(_a, 'code');
                    (_d = (_c = url === null || url === void 0 ? void 0 : url.searchParams) === null || _c === void 0 ? void 0 : _c.delete) === null || _d === void 0 ? void 0 : _d.call(_c, 'state');
                    (_f = (_e = url === null || url === void 0 ? void 0 : url.searchParams) === null || _e === void 0 ? void 0 : _e.delete) === null || _f === void 0 ? void 0 : _f.call(_e, 'appid');
                    adapter_1.runtime.history.replaceState({ _isLoginRoot: true }, '', url.toString());
                    // const popHandler = function (e) {
                    //   const { _isLoginRoot } = e.state;
                    //   console.log('pop state', e.state);
                    //   if (_isLoginRoot) {
                    //     runtime?.['WeixinJSBridge']?.call?.('closeWindow');
                    //   }
                    // };
                    // runtime.addEventListener('popstate', (e) => {
                    //   popHandler(e);
                    //   runtime.removeEventListener('popstate', popHandler);
                    // });
                }
            }
            yield (appLifeCycle === null || appLifeCycle === void 0 ? void 0 : appLifeCycle.beforeCustomLaunch(query));
            appLifeCycle === null || appLifeCycle === void 0 ? void 0 : appLifeCycle.onAppLaunch(options);
            appLifeCycle === null || appLifeCycle === void 0 ? void 0 : appLifeCycle.onAppShow(options);
        });
    }
    if (force) {
        removeAppLifeCycle();
    }
    // 应用级别事件监听
    if (!alreadyInitAppLifeCycle) {
        scheduleAppLifecycle();
        // 预留等客户端来触发
        _HANDLER_MAP = {
            appShow: (...args) => appLifeCycle.onAppShow(...args),
            appHide: (...args) => appLifeCycle.onAppHide(...args),
            error: (...args) => appLifeCycle.onAppError(...args),
            unhandledrejection: (event) => appLifeCycle.onAppUnhandledRejection(event === null || event === void 0 ? void 0 : event.reason),
        };
        for (const event in _HANDLER_MAP) {
            adapter_1.runtime.addEventListener(event, _HANDLER_MAP[event]);
        }
        alreadyInitAppLifeCycle = true;
    }
}
exports.initAppLifeCycle = initAppLifeCycle;
function removeAppLifeCycle() {
    for (const event in _HANDLER_MAP) {
        adapter_1.runtime.removeEventListener(event, _HANDLER_MAP[event]);
    }
    _HANDLER_MAP = {};
    alreadyInitAppLifeCycle = false;
}
exports.removeAppLifeCycle = removeAppLifeCycle;
let isReachBottom = false;
function generatePageLifecycleHandlers({ beforePageCustomLaunch = function (query) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () { });
}, onPageLoad = function (query) { }, onPageShow = function () { }, onPageReady = function () { }, onPageHide = function () { }, onPageUnload = function () { }, onReachBottom = function () { }, onShareAppMessage = function () { }, onPageScroll = function () { }, onResize = function () { }, }, events) {
    function ensureDelegater(fn, eventsKey = '') {
        return function (...args) {
            typeof fn === 'function' && fn.call(this, ...args);
            if (eventsKey) {
                events[eventsKey]();
            }
        };
    }
    return {
        beforePageCustomLaunch,
        onPageLoad(query) {
            let callHandlerResult = typeof onPageLoad === 'function' ? onPageLoad.call(this, query) : () => { };
            events.load({ query });
            return callHandlerResult;
        },
        onPageShow: ensureDelegater(onPageShow, 'show'),
        onPageReady: ensureDelegater(onPageReady, 'ready'),
        onPageHide: ensureDelegater(onPageHide, 'hide'),
        onPageUnload: ensureDelegater(onPageUnload, 'unload'),
        onReachBottom: ensureDelegater(onReachBottom),
        onShareAppMessage: ensureDelegater(onShareAppMessage),
        onPageScroll: ensureDelegater(onPageScroll),
        onResize: ensureDelegater(onResize),
    };
}
exports.generatePageLifecycleHandlers = generatePageLifecycleHandlers;
// web 端使用lifeCycle
function usePageLifeCycle({ beforePageCustomLaunch = function (query) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () { });
}, onPageLoad = function (query) { }, onPageShow = function () { }, onPageReady = function () { }, onPageHide = function () { }, onPageUnload = function () { }, onReachBottom = function () { }, onShareAppMessage = function () { }, onPageScroll = function () { }, onResize = function () { }, }, context, deps = []) {
    let reachBottomDistance = 50;
    try {
        const config = context.app.__internal__.getConfig().pages.find((page) => page.id === context.page.id);
        reachBottomDistance = config.reachBottomDistance;
        if (typeof reachBottomDistance !== 'number') {
            reachBottomDistance = 50;
        }
    }
    catch (e) { }
    React.useEffect(() => {
        function schedulePageLifecycle() {
            var _a, _b, _c, _d;
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                try {
                    const query = getCurrentPageQuery();
                    yield (beforePageCustomLaunch === null || beforePageCustomLaunch === void 0 ? void 0 : beforePageCustomLaunch(query));
                    (_a = onPageLoad === null || onPageLoad === void 0 ? void 0 : onPageLoad.call) === null || _a === void 0 ? void 0 : _a.call(onPageLoad, context.page, query);
                    (_b = onPageShow === null || onPageShow === void 0 ? void 0 : onPageShow.call) === null || _b === void 0 ? void 0 : _b.call(onPageShow, context.page);
                    (_c = onPageReady === null || onPageReady === void 0 ? void 0 : onPageReady.call) === null || _c === void 0 ? void 0 : _c.call(onPageReady, context.page);
                }
                catch (e) {
                    if (!((_d = context.options) === null || _d === void 0 ? void 0 : _d.looseError)) {
                        throw e;
                    }
                    else {
                        console.error('Catched error:', e);
                    }
                }
            });
        }
        schedulePageLifecycle();
        return () => {
            var _a, _b, _c;
            try {
                (_a = onPageHide === null || onPageHide === void 0 ? void 0 : onPageHide.call) === null || _a === void 0 ? void 0 : _a.call(onPageHide, context.page, {});
                (_b = onPageUnload === null || onPageUnload === void 0 ? void 0 : onPageUnload.call) === null || _b === void 0 ? void 0 : _b.call(onPageUnload, context.page, {});
            }
            catch (e) {
                if (!((_c = context.options) === null || _c === void 0 ? void 0 : _c.looseError)) {
                    throw e;
                }
                else {
                    console.error('Catched error:', e);
                }
            }
        };
    }, deps);
    React.useEffect(() => {
        var _a, _b;
        adapter_1.runtime.onscroll = (0, lodash_es_1.throttle)(() => {
            // 变量scrollTop是滚动条滚动时，滚动条上端距离顶部的距离
            let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
            // 变量windowHeight是可视区的高度
            let windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
            // 变量scrollHeight是滚动条的总高度（当前可滚动的页面的总高度）
            let scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
            onPageScroll.call(context.page, {
                scrollTop: adapter_1.runtime.pageYOffset,
            });
            // console.log(scrollTop, windowHeight, scrollTop + windowHeight, scrollHeight, isReachBottom)
            // 滚动条到底部
            if (scrollTop + windowHeight >= scrollHeight - reachBottomDistance) {
                // 要进行的操作
                if (!isReachBottom) {
                    isReachBottom = true;
                    onReachBottom.call(context.page);
                }
            }
            else {
                isReachBottom = false;
            }
        }, 300);
        // todo
        if (typeof onShareAppMessage === 'function') {
            adapter_1.runtime['onShareAppMessage'] = onShareAppMessage.bind(context.page);
        }
        adapter_1.runtime.onresize = (0, lodash_es_1.throttle)(() => {
            var _a;
            onResize.call(context.page, {
                size: {
                    windowWidth: adapter_1.runtime.innerWidth,
                    windowHeight: adapter_1.runtime.innerHeight,
                },
            });
            const device = (_a = context.page.__internal__.$w) === null || _a === void 0 ? void 0 : _a.device;
            if (device) {
                device.viewport = {
                    width: adapter_1.runtime.innerWidth,
                    height: adapter_1.runtime.innerHeight,
                };
            }
        }, 100);
        const navigator = (adapter_1.runtime === null || adapter_1.runtime === void 0 ? void 0 : adapter_1.runtime.navigator) || {};
        const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
        const isMobile = (_b = (_a = context.app) === null || _a === void 0 ? void 0 : _a.__internal__) === null || _b === void 0 ? void 0 : _b.isMobile;
        const connectionListener = () => {
            var _a;
            const device = (_a = context.page.__internal__.$w) === null || _a === void 0 ? void 0 : _a.device;
            if (isMobile === null || isMobile === void 0 ? void 0 : isMobile()) {
                device.networkType = (0, common_1.getNetworkType)(adapter_1.runtime);
            }
            else {
                device.networkType = '';
            }
        };
        connection === null || connection === void 0 ? void 0 : connection.addEventListener('change', connectionListener);
        return () => {
            adapter_1.runtime.onscroll = null;
            adapter_1.runtime.onresize = null;
            connection === null || connection === void 0 ? void 0 : connection.removeEventListener('change', connectionListener);
        };
    }, []);
}
exports.usePageLifeCycle = usePageLifeCycle;
function getCurrentPageQuery() {
    let queryObj = querystring.parse((location.search || '').split('?')[1] || '') || {};
    let hashQueryObj = querystring.parse((location.hash || '').split('?')[1] || '') || {};
    let query = Object.assign(Object.assign({}, hashQueryObj), queryObj);
    // query string parse decode succeess
    // Object.keys(query).forEach((key) => {
    //   query[key] = decodeURIComponent(query[key] as string);
    // });
    return query;
}
function initWebConfig(app, appConfig) {
    // miniprogram.config 配置截取
    app.setConfig(appConfig);
}
exports.initWebConfig = initWebConfig;
//# sourceMappingURL=lifecycle.js.map