import { __assign, __read, __spreadArray, __values } from "tslib";
import { camelcase, isEmptyObj, isSlot } from '../common';
import { translateStyleToRem, translateStyleToRpx, _handleStyleNumValue, setStyleValue, setDistanceStyle, } from '../style';
import { deserializeAttributes, deserializeValue, PropBindType, ActionType, deserializeDynamicMap, EComponentType, } from '@cloudbase/cals';
import { uniq as _uniq, map as _map, get as lodashGet, } from 'lodash-es';
/**
 * utils start
 */
function getMetaInfoBySourceKey(sourceKey) {
    if (!sourceKey) {
        return {};
    }
    var _a = __read(sourceKey.split(':'), 2), materialName = _a[0], name = _a[1];
    return {
        materialName: materialName,
        name: name,
        variableName: camelcase(materialName + '_' + name),
    };
}
// Convert WeApps common style to css styles(React.CSSProperties)
export function toCssStyle(commonStyle, options) {
    if (commonStyle === void 0) { commonStyle = {}; }
    if (options === void 0) { options = { toRem: true, ignoreSelf: false, addPXUnit: false, toRpx: false }; }
    var size = commonStyle.size, 
    // transform,
    text = commonStyle.text, border = commonStyle.border, background = commonStyle.background, margin = commonStyle.margin, padding = commonStyle.padding, zIndex = commonStyle.zIndex, position = commonStyle.position, display = commonStyle.display, flexConfig = commonStyle.flexConfig, custom = commonStyle.custom, self = commonStyle.self;
    var style = {};
    if (size) {
        setStyleValue(style, 'width', _handleStyleNumValue(size.width, !!options.addPXUnit));
        setStyleValue(style, 'height', _handleStyleNumValue(size.height, !!options.addPXUnit));
    }
    // if (transform) {
    //   const { rotate, opacity, scale, radius } = transform
    //   if ((rotate && rotate !== 0) || (scale && scale !== 1)) {
    //     style.transform = `${rotate ? `rotate(${rotate}deg) ` : ''}${scale ? `scale(${scale})` : ''}`
    //   }
    //   setStyleValue(style, 'opacity', opacity)
    //   setStyleValue(style, 'borderRadius', radius)
    // }
    if (margin) {
        setDistanceStyle(style, margin, 'margin', !!options.addPXUnit);
    }
    if (padding) {
        setDistanceStyle(style, padding, 'padding', !!options.addPXUnit);
    }
    if (display) {
        setStyleValue(style, 'display', display);
    }
    if (display === 'flex' && flexConfig) {
        if (flexConfig.justifyContent)
            setStyleValue(style, 'justifyContent', flexConfig.justifyContent);
        if (flexConfig.alignItems)
            setStyleValue(style, 'alignItems', flexConfig.alignItems);
        if (flexConfig.flexWrap && flexConfig.flexDirection) {
            setStyleValue(style, 'flexFlow', flexConfig.flexDirection + " " + flexConfig.flexWrap);
        }
        else {
            if (flexConfig.flexWrap)
                setStyleValue(style, 'flexWrap', flexConfig.flexWrap);
            if (flexConfig.flexDirection)
                setStyleValue(style, 'flexDirection', flexConfig.flexDirection);
        }
    }
    if (typeof zIndex === 'number' || ("" + zIndex).search(/^\d+$/) === 0) {
        style.zIndex = zIndex;
    }
    if (text) {
        setStyleValue(style, 'color', text.color);
        setStyleValue(style, 'fontSize', _handleStyleNumValue(text.fontSize, !!options.addPXUnit));
        setStyleValue(style, 'lineHeight', text.lineHeight);
        setStyleValue(style, 'textAlign', text.textAlign);
        setStyleValue(style, 'fontWeight', text.weight);
        if (text.opacity) {
            setStyleValue(style, 'opacity', text.opacity / 100);
        }
    }
    if (border) {
        var type = border.type, color = border.color, width = border.width, radius = border.radius, radiusInfo = border.radiusInfo;
        if (width !== undefined) {
            if (type) {
                setStyleValue(style, 'border', _handleStyleNumValue(width, !!options.addPXUnit) + " " + type + " " + (color || ''));
            }
            else {
                setStyleValue(style, 'borderWidth', _handleStyleNumValue(width, !!options.addPXUnit));
                if (color)
                    setStyleValue(style, 'borderColor', color);
            }
        }
        if (radius !== undefined) {
            setStyleValue(style, 'borderRadius', _handleStyleNumValue(radius, !!options.addPXUnit));
        }
        if (radiusInfo && !isEmptyObj(radiusInfo)) {
            if (Object.keys(radiusInfo).length === 4) {
                if (_uniq(_map(radiusInfo, function (val) { return val; })).length === 1) {
                    // 4个值全相等的情况
                    setStyleValue(style, 'borderRadius', _handleStyleNumValue(radiusInfo.topLeft, !!options.addPXUnit));
                }
                else if (radiusInfo.topLeft === radiusInfo.bottomRight &&
                    radiusInfo.topRight === radiusInfo.bottomLeft) {
                    // 俩俩相等的情况
                    setStyleValue(style, 'borderRadius', _handleStyleNumValue(radiusInfo.topLeft, !!options.addPXUnit) + " " + _handleStyleNumValue(radiusInfo.topRight, !!options.addPXUnit));
                }
                else if (radiusInfo.topRight === radiusInfo.bottomLeft) {
                    setStyleValue(style, 'borderRadius', _handleStyleNumValue(radiusInfo.topLeft, !!options.addPXUnit) + " " + _handleStyleNumValue(radiusInfo.topRight, !!options.addPXUnit) + " " + _handleStyleNumValue(radiusInfo.bottomRight, !!options.addPXUnit));
                }
                else {
                    setStyleValue(style, 'borderRadius', _handleStyleNumValue(radiusInfo.topLeft, !!options.addPXUnit) + " " + _handleStyleNumValue(radiusInfo.topRight, !!options.addPXUnit) + " " + _handleStyleNumValue(radiusInfo.bottomRight, !!options.addPXUnit) + " " + _handleStyleNumValue(radiusInfo.bottomLeft, !!options.addPXUnit));
                }
            }
            else {
                setStyleValue(style, 'borderTopLeftRadius', _handleStyleNumValue(radiusInfo.topLeft, !!options.addPXUnit));
                setStyleValue(style, 'borderTopRightRadius', _handleStyleNumValue(radiusInfo.topRight, !!options.addPXUnit));
                setStyleValue(style, 'borderBottomRightRadius', _handleStyleNumValue(radiusInfo.bottomRight, !!options.addPXUnit));
                setStyleValue(style, 'borderBottomLeftRadius', _handleStyleNumValue(radiusInfo.bottomLeft, !!options.addPXUnit));
            }
        }
    }
    if (background) {
        var bgType = background.bgType, color = background.color, image = background.image, size_1 = background.size, repeat = background.repeat, position_1 = background.position, positionObj = background.positionObj;
        if (bgType === 'color') {
            setStyleValue(style, 'background', color);
        }
        else if (bgType === 'image') {
            // 如 radial-gradient(crimson, skyblue);
            if (image != null) {
                if (image.search(/[()]/) >= 0) {
                    style.background = image;
                }
                else {
                    style.background = "url(" + image + ")";
                }
            }
            if (repeat)
                style.background += " " + repeat;
            if (size_1) {
                setStyleValue(style, 'backgroundSize', _handleStyleNumValue(size_1, !!options.addPXUnit));
            }
            setStyleValue(style, 'backgroundPosition', position_1);
            if (positionObj && !isEmptyObj(positionObj)) {
                style.background += " " + _handleStyleNumValue(positionObj.left, !!options.addPXUnit) + " " + _handleStyleNumValue(positionObj.top, !!options.addPXUnit);
            }
        }
        // FIXME: 这里兼容原有应用的数据，后面应去掉
        if (bgType === undefined) {
            setStyleValue(style, 'backgroundColor', color);
            if (image != null) {
                style.backgroundImage = "url(" + image + ")";
                setStyleValue(style, 'backgroundRepeat', repeat);
                setStyleValue(style, 'backgroundSize', _handleStyleNumValue(size_1, !!options.addPXUnit));
                setStyleValue(style, 'backgroundPosition', position_1);
            }
        }
    }
    if (position) {
        setStyleValue(style, 'position', position.position);
        if (position.left !== undefined) {
            setStyleValue(style, 'left', _handleStyleNumValue(position.left, !!options.addPXUnit));
        }
        if (position.right !== undefined) {
            setStyleValue(style, 'right', _handleStyleNumValue(position.right, !!options.addPXUnit));
        }
        if (position.top !== undefined) {
            setStyleValue(style, 'top', _handleStyleNumValue(position.top, !!options.addPXUnit));
        }
        if (position.bottom !== undefined) {
            setStyleValue(style, 'bottom', _handleStyleNumValue(position.bottom, !!options.addPXUnit));
        }
    }
    if (custom && custom.length > 0) {
        custom.map(function (item) {
            setStyleValue(style, item.key, item.value);
        });
    }
    if (self && !options.ignoreSelf) {
        Object.assign(style, self);
    }
    if (options.toRpx) {
        return translateStyleToRpx(style);
    }
    return options.toRem ? translateStyleToRem(style) : style;
}
export function getComponentsInfo(dependencies) {
    var outputObj = {};
    dependencies.forEach(function (_a) {
        var materialName = _a.name, components = _a.components, isComposite = _a.isComposite;
        if (isComposite) {
            components.forEach(function (component) {
                var compItem = component;
                var sourceKey = materialName + ":" + compItem.name;
                outputObj[sourceKey] = __assign({ isComposite: isComposite }, compItem);
            });
        }
        else {
            components.forEach(function (_a) {
                var name = _a.name, meta = _a.meta, emitEvents = _a.emitEvents, _b = _a.events, events = _b === void 0 ? undefined : _b, isContainer = _a.isContainer, compConfig = _a.compConfig;
                outputObj[materialName + ':' + name] = __assign(__assign({ isComposite: isComposite }, meta), { events: events, emitEvents: emitEvents, isContainer: isContainer, compConfig: compConfig });
            });
        }
    });
    return outputObj;
}
function getInputProps(componentsMetaMap) {
    var outputObj = {};
    var _loop_1 = function (key) {
        var component = componentsMetaMap[key];
        var sourceKey = key;
        if (component.isComposite) {
            var compItem_1 = component;
            Object.keys(compItem_1.dataForm || {}).forEach(function (key) {
                var _a;
                var _b, _c;
                var inputProps = ((_b = compItem_1.dataForm[key]) === null || _b === void 0 ? void 0 : _b.inputProp) || ((_c = compItem_1.dataForm[key]) === null || _c === void 0 ? void 0 : _c.syncProp);
                if (inputProps) {
                    outputObj[sourceKey] = __assign((_a = {}, _a[key] = inputProps, _a), (outputObj[sourceKey] || {}));
                }
            });
        }
        else {
            var inputProps = (component === null || component === void 0 ? void 0 : component.inputProps) || (component === null || component === void 0 ? void 0 : component.syncProps);
            if (inputProps) {
                outputObj[sourceKey] = inputProps;
            }
        }
    };
    for (var key in componentsMetaMap) {
        _loop_1(key);
    }
    return outputObj;
}
/**
 * utils end
 */
function splitDynamicMap(data) {
    var staticData = {};
    var dataBinds = [];
    for (var key in data) {
        var meta = data[key];
        if (!meta.type || meta.type === PropBindType.static) {
            staticData[key] = meta.value;
        }
        else if (meta.type === PropBindType.slot) {
            continue;
        }
        else {
            dataBinds.push({
                type: meta.type,
                bindDataPath: meta.value,
                propertyPath: key,
            });
        }
    }
    return { staticData: staticData, dataBinds: dataBinds };
}
function walkThroughCals(cals, process) {
    var e_1, _a;
    var _b;
    var _c = cals.items, items = _c === void 0 ? [] : _c;
    cals.extra = cals.extra || {};
    if (((_b = cals === null || cals === void 0 ? void 0 : cals.directives) === null || _b === void 0 ? void 0 : _b[':if']) === false) {
        cals.items = [];
    }
    try {
        for (var items_1 = __values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) {
            var item = items_1_1.value;
            item.extra = item.extra || {};
            item.extra.__parent = cals;
            walkThroughCals(item, process);
        }
    }
    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; }
    }
    process(cals);
    return cals;
}
export function getComponentSchema(ctx, page, isComposite, componentsInfoMap, wrapperClass, options) {
    if (isComposite === void 0) { isComposite = false; }
    if (componentsInfoMap === void 0) { componentsInfoMap = {}; }
    var componentInputProps = getInputProps(componentsInfoMap) || {};
    var copyJson = JSON.parse(JSON.stringify(page));
    var compWidgets = {};
    var compDataBinds = {};
    var componentSchemaJson = walkThroughCals(copyJson, function (component) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
        if (isSlot(component)) {
            return;
        }
        var componentName = component.component, module = component.module, _s = component.attributes, attributes = _s === void 0 ? {} : _s;
        var _t = (component.extra || {}).commonStyle, commonStyle = _t === void 0 ? {} : _t;
        var processedCommonStyle = attributes.style
            ? attributes.style
            : toCssStyle(commonStyle);
        if (processedCommonStyle && !isEmptyObj(processedCommonStyle)) {
            component.extra.commonStyle = processedCommonStyle;
        }
        var sourceKey = module + ":" + componentName;
        var _u = attributes.class, className = _u === void 0 ? '' : _u;
        var deserializeCtx = { page: page };
        var dynamicStyle = component[':style']
            ? deserializeValue(deserializeCtx, ':style', component[':style']).value
            : undefined;
        var dynamicClassList = component[':class']
            ? deserializeValue(deserializeCtx, ':class', component[':class']).value
            : undefined;
        var dynamicIf = ((_a = component.directives) === null || _a === void 0 ? void 0 : _a[':if'])
            ? deserializeValue(deserializeCtx, ':if', (_b = component.directives) === null || _b === void 0 ? void 0 : _b[':if'])
                .value
            : undefined;
        var dynamicFor = ((_c = component.directives) === null || _c === void 0 ? void 0 : _c[':for'])
            ? deserializeValue(deserializeCtx, ':for', (_d = component.directives) === null || _d === void 0 ? void 0 : _d[':for'])
                .value
            : undefined;
        if (dynamicIf != undefined &&
            (dynamicIf.value == undefined ||
                dynamicIf.value === true ||
                dynamicIf.value === false)) {
            dynamicIf = undefined;
        }
        if (dynamicFor) {
            var type = dynamicFor.type, value = dynamicFor.value;
            if (type === PropBindType.expression) {
                dynamicFor.value = value.replace(/^(.*?in\s)/, '');
            }
        }
        var data = deserializeAttributes(deserializeCtx, attributes);
        var _v = splitDynamicMap(data), dataBinds = _v.dataBinds, staticData = _v.staticData;
        var componentInfo = componentsInfoMap[sourceKey];
        if ((_e = componentInfo) === null || _e === void 0 ? void 0 : _e.compConfig) {
            component.extra.compConfig = (_f = componentInfo) === null || _f === void 0 ? void 0 : _f.compConfig;
        }
        if ((_g = componentInfo) === null || _g === void 0 ? void 0 : _g.events) {
            component.extra.emitEvents = (_h = componentInfo) === null || _h === void 0 ? void 0 : _h.events.map(function (item) { return item.name; });
        }
        else if ((_j = componentInfo) === null || _j === void 0 ? void 0 : _j.emitEvents) {
            component.extra.emitEvents = componentInfo.emitEvents.map(function (item) { return item.eventName; });
        }
        // 生成 widgets/dataBinds
        if (!isSlot(component) && component.id) {
            var parentComponent = component.extra.__parent;
            var _visible = undefined;
            switch ((_k = component.directives) === null || _k === void 0 ? void 0 : _k[':if']) {
                case true:
                case false: {
                    _visible = (_l = component.directives) === null || _l === void 0 ? void 0 : _l[':if'];
                    break;
                }
                case undefined: {
                    _visible = true;
                    break;
                }
            }
            compWidgets[component.id] = __assign(__assign({}, Object.entries(staticData).reduce(function (data, _a) {
                var _b = __read(_a, 2), propsKey = _b[0], propsValue = _b[1];
                var value = propsValue;
                if (value && Array.isArray(value)) {
                    value = value.map(function (_, index) {
                        var _a, _b;
                        var block = (_a = attributes === null || attributes === void 0 ? void 0 : attributes[propsKey]) === null || _a === void 0 ? void 0 : _a[index];
                        var blockInstances = (_b = block === null || block === void 0 ? void 0 : block.selectableBlock) === null || _b === void 0 ? void 0 : _b.listeners;
                        if (blockInstances) {
                            block.selectableBlock['listenerInstances'] =
                                generateListnerInstances(ctx, blockInstances || [], {
                                    isComposite: isComposite,
                                    looseError: options === null || options === void 0 ? void 0 : options.looseError,
                                });
                        }
                        return block;
                    });
                }
                data[propsKey] = value;
                return data;
            }, {})), { _visible: _visible, style: __assign({}, processedCommonStyle), classList: className.split(/\s/).filter(function (item) { return !!item; }), widgetType: sourceKey, _parentId: parentComponent
                    ? isSlot(parentComponent)
                        ? (_o = (_m = parentComponent.extra) === null || _m === void 0 ? void 0 : _m.__parent) === null || _o === void 0 ? void 0 : _o.id
                        : parentComponent.id
                    : null, getConfig: function () {
                    var _a, _b;
                    return (_b = (_a = componentInfo) === null || _a === void 0 ? void 0 : _a.compConfig) !== null && _b !== void 0 ? _b : {};
                } });
            var processedDataBinds = __spreadArray([], __read(dataBinds), false);
            if (dynamicIf === null || dynamicIf === void 0 ? void 0 : dynamicIf.value) {
                processedDataBinds.push({
                    type: dynamicIf.type,
                    bindDataPath: dynamicIf.value,
                    propertyPath: '_visible',
                });
            }
            if (dynamicFor === null || dynamicFor === void 0 ? void 0 : dynamicFor.value) {
                processedDataBinds.push({
                    type: dynamicFor.type,
                    bindDataPath: dynamicFor.value,
                    propertyPath: '_waFor',
                });
            }
            if (dynamicStyle === null || dynamicStyle === void 0 ? void 0 : dynamicStyle.value) {
                processedDataBinds.push({
                    type: dynamicStyle.type,
                    bindDataPath: dynamicStyle.value,
                    propertyPath: 'style',
                });
            }
            if (dynamicClassList) {
                processedDataBinds.push({
                    type: dynamicClassList.type,
                    bindDataPath: dynamicClassList.value,
                    propertyPath: 'classList',
                });
            }
            if (processedDataBinds.length > 0) {
                compDataBinds[component.id] = generateDataBinds(ctx, processedDataBinds, { isComposite: isComposite, looseError: options === null || options === void 0 ? void 0 : options.looseError });
            }
        }
        component['listenerInstances'] = generateListnerInstances(ctx, component.listeners || [], { isComposite: isComposite, looseError: options === null || options === void 0 ? void 0 : options.looseError });
        delete component.listeners;
        if (!isEmptyObj(attributes)) {
            // 如果是复合组件的根节点，则补充 wrapperClass
            if (isComposite) {
                if (!((_r = (_q = (_p = component === null || component === void 0 ? void 0 : component.extra) === null || _p === void 0 ? void 0 : _p.__parent) === null || _q === void 0 ? void 0 : _q.extra) === null || _r === void 0 ? void 0 : _r.__parent)) {
                    component.attributes = {};
                    component.attributes.class = component.attributes.class + " " + wrapperClass;
                }
            }
            // 组件双向绑定
            var syncProps_1 = componentInputProps[sourceKey];
            if (syncProps_1) {
                Object.keys(syncProps_1).forEach(function (syncPropKey) {
                    var syncPropArr = [];
                    var syncProp = syncProps_1[syncPropKey];
                    // 统一转成数组处理
                    if (!Array.isArray(syncProp)) {
                        syncPropArr = [syncProp];
                    }
                    syncPropArr.forEach(function (_a) {
                        // 双向绑定需要优先第一个执行，否则会出现输入框的拼音被打断的问题
                        var changeEvent = _a.changeEvent, valueFromEvent = _a.valueFromEvent;
                        function withContext(context) {
                            var instance = new Function('context', "return ({ event, forItems }) => {\n                  const $for = forItems;\n                  const wid = " + (isComposite ? 'this.widgets' : '$page.widgets') + "." + component.id + ";\n                  const widgetData = $for.forIndexes && $for.forIndexes.length > 0 ? context.get(wid, forItems.forIndexes) : wid;\n                  widgetData." + syncPropKey + " = " + valueFromEvent + "\n                }")(context);
                            return ctx.this ? instance.bind(this) : instance;
                        }
                        component['listenerInstances'].unshift({
                            trigger: changeEvent,
                            instanceFunction: withContext({ get: lodashGet }),
                        });
                    });
                });
            }
        }
    });
    return {
        widgets: compWidgets,
        dataBinds: compDataBinds,
        componentSchema: componentSchemaJson,
    };
}
// convert data binds to functions for performance & simplicity
export function generateDataBinds(ctx, dataBinds, options) {
    var dataBindFuncs = {};
    dataBinds.forEach(function (bind) {
        var _a;
        if (!bind.bindDataPath) {
            return console.warn('无 bindDataPath', bind.propertyPath);
        }
        var funcCode = function () { };
        try {
            if (bind.type === PropBindType.forItem) {
                funcCode = new Function('context', "return (forItems) => forItems." + bind.bindDataPath)(ctx);
            }
            else if (bind.type === 'scope') {
                funcCode = new Function('context', "return () => ({__type: \"scopedValue\", getValue: ($scope)=>$scope." + bind.bindDataPath + "})}")(ctx);
            }
            else if (bind.type === PropBindType.expression) {
                if (options === null || options === void 0 ? void 0 : options.isComposite) {
                    funcCode = new Function('context', "const { $page, app, $app } = context || {};\n            return (forItems, $context) => {const $for = forItems; return (\n" + (bind.bindDataPath
                        .replace(/\$comp/g, 'this.$WEAPPS_COMP')
                        .replace(/;$/, '') || 'undefined') + "\n)}")(ctx);
                }
                else {
                    var code = bind.bindDataPath.replace(/;$/, '');
                    funcCode = new Function('context', "const { $page, app, $app } = context || {};\n\n            return " + (/\$scope\./.test(code)
                        ? "(forItems, event, $context) => ({__type: \"scopedValue\", getValue: ($scope) => { const $for = forItems; return (\n" + code + "\n)}})"
                        : "(forItems, event, $context) => { const $for = forItems; return (\n" + (code || 'undefined') + "\n)}"))(ctx);
                }
            }
            else if (bind.type === PropBindType.prop) {
                var bindDataPath = bind.bindDataPath;
                var isNegated = bindDataPath.startsWith('!');
                if (isNegated)
                    bindDataPath = bindDataPath.replace(/^!/, '');
                if (options === null || options === void 0 ? void 0 : options.isComposite) {
                    // 复合组件在预览时其实就是page，所以沿用page的变量即可
                    funcCode = new Function('context', "const { $page, app, $app } = context || {};\n            return () => " + (isNegated ? '!' : '') + 'this.$WEAPPS_COMP' + ".props.data." + bindDataPath)(ctx);
                }
                else {
                    // 复合组件在预览时其实就是page，所以沿用page的变量即可
                    funcCode = new Function('context', "const { $page, app, $app } = context || {};\n            return () => " + (isNegated ? '!' : '') + "$page.props.data." + bindDataPath)(ctx);
                }
            }
            else {
                var isGlobal = bind.bindDataPath.startsWith('global.');
                var returnValue = '';
                var PREFIX_MAP = (_a = {},
                    _a[PropBindType.state] = 'state',
                    _a[PropBindType.computed] = 'computed',
                    // [PropBindType.dataVar]: 'dataVar',
                    _a[PropBindType.stateData] = 'dataset.state',
                    _a[PropBindType.paramData] = 'dataset.params',
                    _a);
                switch (bind.type) {
                    case PropBindType.state:
                    case PropBindType.computed:
                    // case PropBindType.dataVar:
                    case PropBindType.stateData:
                    case PropBindType.paramData: {
                        if (isGlobal) {
                            returnValue = bind.bindDataPath.replace(/^global./, "app." + PREFIX_MAP[bind.type] + ".");
                        }
                        else {
                            if (options === null || options === void 0 ? void 0 : options.isComposite) {
                                returnValue = bind.bindDataPath
                                    .replace(/^comp-\w+./, "this.$WEAPPS_COMP." + PREFIX_MAP[bind.type] + ".")
                                    .replace(/^\$\w+_\d+./, "this.$WEAPPS_COMP." + PREFIX_MAP[bind.type] + ".");
                            }
                            else {
                                returnValue = bind.bindDataPath.replace(/^\w+./, "$page." + PREFIX_MAP[bind.type] + ".");
                            }
                        }
                        funcCode = new Function('context', "const { $page, app, $app } = context || {};\n              return () => " + returnValue)(ctx);
                        break;
                    }
                }
            }
        }
        catch (e) {
            if (options === null || options === void 0 ? void 0 : options.looseError) {
                console.error('generate dynamic data error:', e);
                funcCode = function () {
                    throw e;
                };
            }
            else {
                throw e;
            }
        }
        dataBindFuncs[bind.propertyPath] = funcCode;
    });
    return dataBindFuncs;
}
/**
 * dataset 特殊的绑定格式
 * 要求：入参分别为 app ， page
 * 绑定只有变量，参数，表达式的绑定
 */
export function generateDataBindForDataset(bind) {
    var _a;
    var expr = '';
    var type = bind.type, bindDataPath = bind.bindDataPath;
    if (type === PropBindType.static || !type) {
        expr =
            typeof bindDataPath === 'string'
                ? "'" + bindDataPath + "'"
                : JSON.stringify(bindDataPath);
    }
    else if (type === PropBindType.expression) {
        expr = bindDataPath;
    }
    else {
        var isGlobal = bindDataPath.startsWith('global.');
        var isCopositive = bindDataPath.startsWith('comp-') || bindDataPath.startsWith('$comp_');
        var PREFIX_MAP = (_a = {},
            _a[PropBindType.state] = 'state',
            _a[PropBindType.computed] = 'computed',
            _a[PropBindType.dataVar] = 'dataVar',
            _a[PropBindType.stateData] = 'dataset.state',
            _a[PropBindType.paramData] = 'dataset.params',
            _a);
        switch (type) {
            case PropBindType.state:
            case PropBindType.computed:
            case PropBindType.dataVar:
            case PropBindType.stateData:
            case PropBindType.paramData: {
                if (isCopositive) {
                    expr = bindDataPath
                        .replace(/^comp-\w+/, "$comp." + PREFIX_MAP[type])
                        .replace(/^\$comp_\w+/, "$comp." + PREFIX_MAP[type]);
                }
                else {
                    expr = bindDataPath
                        .replace(/^\w+./, (isGlobal ? 'app' : '$page') + "." + PREFIX_MAP[type] + ".")
                        .replace(/^comp-\w+/, "$comp." + PREFIX_MAP[type])
                        .replace(/^\$comp_\w+/, "$comp." + PREFIX_MAP[type]);
                }
            }
        }
    }
    return new Function('app, $page', "const $app = app; return (\n" + (expr || 'undefined') + "\n)");
}
function generateListnerInstances(ctx, listenerInstances, options) {
    var _this = this;
    if (options === void 0) { options = {
        isComposite: false,
    }; }
    var _a = options.isComposite, isComposite = _a === void 0 ? false : _a;
    return listenerInstances.map(function (listener) {
        var _a, _b, _c, _d, _e;
        var generatedListener = {
            key: listener.id,
            trigger: listener.eventName,
            isCapturePhase: !!listener.isCapturePhase,
            noPropagation: listener['noPropagation'],
            instanceFunction: function () { },
            data: {},
            dataBinds: {},
        };
        if (listener.type === ActionType.Material) {
            var _f = listener.handler || {}, name_1 = _f.name, module_1 = _f.module;
            generatedListener.instanceFunction = new Function('context', "const { $page, app, $app, actionsMap = {} } = context || {};\n        return (...args) => actionsMap[\"" + module_1 + ":" + name_1 + "\"]?.apply?.(null, args)")(ctx);
        }
        else if (listener.type === ActionType.PropEvent) {
            if (isComposite) {
                var instance = new Function('{ data, event, forItems }', "\n          event.detail.data = data;\n          this.props.emit('" + (
                // TODO: CHECK listener.handler.name 具体是什么
                listener.handler.name || listener['jsCode']) + "', event.detail);");
                generatedListener.instanceFunction = ctx.this
                    ? instance.bind(_this)
                    : instance;
            }
            else {
                generatedListener.instanceFunction = new Function('context', "return (...args) => context.$page.props.events." + (((_a = listener.handler) === null || _a === void 0 ? void 0 : _a.name) || listener['jsCode']) + ".apply(null, args)")(ctx);
            }
        }
        else if (listener.type === ActionType.Inline) {
            // 内联 handler
            var instance = new Function('{event, domEvent, customEventData, data, forItems}', "return " + listener['jsCode']);
            if (isComposite) {
                generatedListener.instanceFunction = ctx.this
                    ? instance.bind(_this)
                    : instance;
            }
            else {
                generatedListener.instanceFunction = instance.bind(ctx.$page);
            }
        }
        else if (listener.type === ActionType.Platform) {
            var name_2 = ((_b = listener.handler) === null || _b === void 0 ? void 0 : _b.name) || listener['jsCode'];
            generatedListener.instanceFunction = new Function('{data}', "return app." + name_2 + "(data)");
        }
        else if (listener.type === ActionType.DataSource) {
            generatedListener.instanceFunction = new Function('{data}', "return app.cloud.callDataSource(data)");
        }
        else {
            // Lowcode action(handler)
            if (isComposite) {
                generatedListener.instanceFunction = new Function('', "return this.handler." + (((_c = listener.handler) === null || _c === void 0 ? void 0 : _c.name) || listener['jsCode']) + ".bind(this)").bind(ctx.this)();
            }
            else {
                var name_3 = ((_d = listener.handler) === null || _d === void 0 ? void 0 : _d.name) || listener['jsCode'];
                generatedListener.instanceFunction = new Function('context', "return context.$page.handler." + name_3)(ctx);
            }
        }
        var processedParams = deserializeDynamicMap({
            page: { id: ctx.$page.id, type: EComponentType.PAGE },
        }, (_e = listener.handler) === null || _e === void 0 ? void 0 : _e.params);
        var _g = splitDynamicMap(processedParams), staticData = _g.staticData, dataBinds = _g.dataBinds;
        generatedListener.data = staticData;
        generatedListener.dataBinds = generateDataBinds(ctx, dataBinds, options);
        return generatedListener;
    });
}
//# sourceMappingURL=generate.js.map