import { useEffect, createContext, useContext } from './r.js';
import { instanceKeyPropNames } from './utils.js';
import { checkIfPlatformIsLoadCorrectly, } from './platform.js';
//@ts-expect-error
function generateEventHookName(eventName) {
    return "use".concat(eventName[0].toUpperCase()).concat(eventName.slice(1));
}
export var reactContext = createContext(null);
// --------------------------
function useAppxContext() {
    var appxInstanceContext = useContext(reactContext);
    if (!appxInstanceContext) {
        throw new Error('请不要在组件内调用 hooks');
    }
    return appxInstanceContext;
}
function useEventCall(name, handler, deps, disableMultiImpl) {
    if (!deps)
        console.warn("useEventCall ".concat(name, ": hooks \u7684 deps \u53C2\u6570\u4E3A\u7A7A\uFF0C\u53EF\u80FD\u4F1A\u5BFC\u81F4\u6027\u80FD\u95EE\u9898"));
    var appxInstanceContext = useAppxContext();
    if (appxInstanceContext.ifServerRender) {
        // 虚拟渲染时，注册空实现
        appxInstanceContext.handlersController.addHandler(name, {}, function () { }, false);
    }
    useEffect(function () {
        var off = appxInstanceContext.handlersController.addHandler(name, appxInstanceContext.instance, 
        //@ts-expect-error
        function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            return handler.apply(undefined, args);
        }, disableMultiImpl);
        return off;
    }, deps);
}
// 注册和更新 handler，注意只能更新第一次注册过的 handler 实现，不允许变更数量和 key
export function useEvent(name, handler, deps) {
    var appxInstanceContext = useAppxContext();
    var platformConfig = appxInstanceContext.platformConfig;
    var pageEvents = platformConfig.pageEvents, componentEvents = platformConfig.componentEvents, blockedProperty = platformConfig.blockedProperty;
    if (pageEvents.indexOf(name) >= 0 || componentEvents.indexOf(name) >= 0) {
        throw new Error("\u5C0F\u7A0B\u5E8F ".concat(name, " \u662F\u751F\u547D\u5468\u671F\u76F8\u5173\u7684\u4FDD\u7559\u65B9\u6CD5\uFF0C\u4E0D\u5141\u8BB8\u4F7F\u7528\u6B64\u79CD\u65B9\u6CD5\u6CE8\u518C\uFF0C\u8BF7\u4F7F\u7528\u5BF9\u5E94\u7684 hooks: ").concat(generateEventHookName(name)));
    }
    else if (blockedProperty.indexOf(name) >= 0) {
        throw new Error("\u4E0D\u5141\u8BB8\u6CE8\u518C\u540D\u4E3A ".concat(name, " \u7684\u4E8B\u4EF6\u5904\u7406\u51FD\u6570\uFF0C\u8FD9\u662F\u5C0F\u7A0B\u5E8F\u7684\u4FDD\u7559\u5C5E\u6027\uFF0C\u8BF7\u6362\u4E00\u4E2A\u540D\u79F0"));
    }
    useEventCall(name, handler, deps, true);
}
export function getLifeCycleHooks(eventName, disableMultiImpl, specifyPlatform) {
    if (disableMultiImpl === void 0) { disableMultiImpl = false; }
    return function (handler, deps) {
        var appxInstanceContext = useAppxContext();
        if (specifyPlatform) {
            var platformConfig = appxInstanceContext.platformConfig;
            checkIfPlatformIsLoadCorrectly(platformConfig, specifyPlatform);
        }
        useEventCall(eventName, handler, deps !== null && deps !== void 0 ? deps : [], disableMultiImpl);
    };
}
export function useSyncMiniData(data) {
    if (data === void 0) { data = {}; }
    var appxInstanceContext = useAppxContext();
    // const propKeys = appxInstanceContext
    if (!appxInstanceContext.instance) {
        throw new Error('cannot get appx instance, failed to set data');
    }
    if (appxInstanceContext.ifServerRender) {
        appxInstanceContext.instance.setData(data);
    }
    var debugLog = appxInstanceContext.debugLog || function () { };
    if (typeof data !== 'object')
        throw new Error("\u51FD\u6570\u8FD4\u56DE\u7684\u6570\u636E\u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61\uFF0C\u6536\u5230\u4E86 ".concat(typeof data));
    // 这里是一个每次都要跑的 passive effect
    useEffect(function () {
        var instance = appxInstanceContext.instance;
        var propNames = instance[instanceKeyPropNames] || []; // 微信的 data 里包含了 props，要手动踢掉
        var pendingData = {};
        var previousData = instance.data || {};
        // 比对一下，只 set 不同的部分
        for (var key in data) {
            if (!Object.prototype.hasOwnProperty.call(data, key))
                continue;
            //@ts-expect-error
            if (typeof data[key] === 'function')
                throw new Error("".concat(key, " - \u4E0D\u5141\u8BB8\u4F20\u5165\u51FD\u6570\u7C7B\u578B\u7684\u6570\u636E")); // 暂不支持，有需求再说
            //@ts-expect-error
            if (!previousData[key] || previousData[key] !== data[key]) {
                //@ts-expect-error
                pendingData[key] = data[key];
            }
        }
        // 缺少某些 key，就设置成 null
        for (var _i = 0, _a = Object.keys(previousData); _i < _a.length; _i++) {
            var key = _a[_i];
            if (propNames.indexOf(key) >= 0)
                continue;
            if (!Object.prototype.hasOwnProperty.call(data, key)) {
                //@ts-expect-error
                pendingData[key] = null;
            }
        }
        if (Object.keys(pendingData).length > 0) {
            debugLog('calling setData', pendingData);
            instance.setData(pendingData);
        }
    }, undefined);
}
function useMiniInstance() {
    var appxInstanceContext = useAppxContext();
    return appxInstanceContext.instance;
}
export var usePage = useMiniInstance;
export var useComponent = useMiniInstance;
