import { __assign, __read, __spreadArray, __values } from "tslib";
import * as React from 'react';
import { ForContext, getComponentRenderList } from './NodeRenderer';
import lodashSet from 'lodash.set';
import cloneDeep from 'lodash.clonedeep';
import { isScopeSlot, isSlot } from '../utils/common';
import { observer } from 'mobx-react-lite';
import { ComponentNotFound } from '../utils/error';
import { InjectContext } from '../router';
function checkDoNotRenderSlot(componentSchema, renderSlot, rootNode) {
    // 判断是否为 slot
    return isSlot(componentSchema) && !(renderSlot || rootNode);
}
export function getComponentChildren(component, context) {
    var _a = component.items, items = _a === void 0 ? [] : _a;
    if (!items.length) {
        return [];
    }
    var list = items.sort(function (a, b) { var _a, _b; return (((_a = a.extra) === null || _a === void 0 ? void 0 : _a.xIndex) || 0) - (((_b = b.extra) === null || _b === void 0 ? void 0 : _b.xIndex) || 0); });
    var virtualFields = context.virtualFields, codeContext = context.codeContext, scopeContext = context.scopeContext, forContext = context.forContext, injectContext = context.injectContext, dataContext = context.dataContext, updateContext = context.updateContext;
    return list.map(function (schema) {
        return getRenderList({
            key: schema.id,
            componentSchema: schema,
            rootNode: false,
            renderSlot: false,
            virtualFields: virtualFields,
            codeContext: codeContext,
            scopeContext: scopeContext,
            forContext: forContext,
            injectContext: injectContext,
            dataContext: dataContext,
            updateContext: updateContext,
        });
    });
}
export function generateSlotMetaMap(componentSchema, context, options) {
    var e_1, _a;
    var _b = componentSchema.items, items = _b === void 0 ? [] : _b;
    var scopeContext = context.scopeContext, codeContext = context.codeContext, virtualFields = context.virtualFields, dataContext = context.dataContext, updateContext = context.updateContext, injectContext = context.injectContext, forContext = context.forContext;
    var slots = {};
    var _loop_1 = function (child) {
        // TODO 做到不依赖组件 id
        var key = child.id;
        if (isSlot(child)) {
            var isHOC = isScopeSlot(componentSchema, key);
            slots[key] = {
                type: isHOC ? 'HOC' : 'ELEMENT',
                node: isHOC
                    ? function (props) {
                        var clonedScopeContext = cloneDeep(scopeContext);
                        lodashSet(clonedScopeContext, componentSchema.id + "." + key, props);
                        return (React.createElement(InjectContext.Provider, { value: injectContext },
                            React.createElement(AppRender, { key: key, componentSchema: child, renderSlot: options.renderSlot, virtualFields: virtualFields, codeContext: codeContext, scopeContext: clonedScopeContext, dataContext: dataContext, updateContext: updateContext })));
                    }
                    : function () {
                        return (React.createElement(InjectContext.Provider, { value: injectContext },
                            React.createElement(ForContext.Provider, { value: forContext },
                                React.createElement(AppRender, { key: key, componentSchema: child, renderSlot: options === null || options === void 0 ? void 0 : options.renderSlot, virtualFields: virtualFields, codeContext: codeContext, scopeContext: scopeContext, dataContext: dataContext, updateContext: updateContext }))));
                    },
            };
        }
    };
    try {
        // eslint-disable-next-line guard-for-in
        for (var items_1 = __values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) {
            var child = items_1_1.value;
            _loop_1(child);
        }
    }
    catch (e_1_1) { e_1 = { error: e_1_1 }; }
    finally {
        try {
            if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
        }
        finally { if (e_1) throw e_1.error; }
    }
    return slots;
}
function getRenderList(props) {
    var _a, _b;
    var key = props.key, className = props.className, virtualFields = props.virtualFields, componentSchema = props.componentSchema, renderSlot = props.renderSlot, _c = props.rootNode, rootNode = _c === void 0 ? true : _c, codeContext = props.codeContext, _d = props.scopeContext, scopeContext = _d === void 0 ? {} : _d, _e = props.forContext, forContext = _e === void 0 ? {} : _e, _f = props.injectContext, injectContext = _f === void 0 ? {} : _f, dataContext = props.dataContext, updateContext = props.updateContext;
    var _g = componentSchema.items, items = _g === void 0 ? [] : _g;
    var _h = (componentSchema.extra || {}).genericComp, genericComp = _h === void 0 ? {} : _h;
    // 判断是否为 slot
    if (checkDoNotRenderSlot(componentSchema, renderSlot, rootNode)) {
        return null;
    }
    // wrapperClass;
    // const preClassName = useRef<string>('');
    var containerEl = items[0];
    if ((containerEl === null || containerEl === void 0 ? void 0 : containerEl.attributes) && className) {
        var classNameList = (((_a = containerEl.attributes) === null || _a === void 0 ? void 0 : _a.class) || '')
            .split(/\s/)
            .filter(function (item) { return !!item; });
        // 先替换掉先前计算出来的className部分
        // if (preClassName.current) {
        //   if (preClassName.current !== className) {
        //     classNameList = classNameList.filter(
        //       (clsName) => clsName !== preClassName.current
        //     );
        //     preClassName.current = className;
        //   }
        // } else {
        //   preClassName.current = className;
        // }
        // containerEl.attributes.class = [className, ...classNameList].join(' ');
        containerEl.attributes.class = Array.from(new Set(__spreadArray([className], __read(classNameList), false))).join(' ');
    }
    if (componentSchema.module && componentSchema.component) {
        var sourceKey = componentSchema.module + ":" + componentSchema.component;
        var Field = virtualFields[sourceKey];
        if (!Field) {
            return (React.createElement(ComponentNotFound, { key: key, module: componentSchema.module, component: componentSchema.component }));
        }
    }
    var context = {
        virtualFields: virtualFields,
        codeContext: codeContext,
        scopeContext: scopeContext,
        forContext: forContext,
        dataContext: dataContext,
        updateContext: updateContext,
        injectContext: injectContext,
    };
    return getComponentRenderList({
        key: key,
        componentSchema: componentSchema,
        rootNode: rootNode,
        emitEvents: ((_b = componentSchema.extra) === null || _b === void 0 ? void 0 : _b.emitEvents) || [],
        renderSlot: renderSlot,
        virtualFields: virtualFields,
        codeContext: codeContext,
        scopeContext: scopeContext,
        forContext: forContext,
        dataContext: dataContext,
        updateContext: updateContext,
        injectContext: injectContext,
        genericComp: genericComp,
    });
}
export var AppRender = observer(function (props) {
    return getRenderList(__assign(__assign({}, props), { forContext: React.useContext(ForContext), injectContext: React.useContext(InjectContext) }));
});
//# sourceMappingURL=RenderWrapper.js.map