import { __decorate } from "tslib";
import { throttle, Util } from '@ibizstudio/runtime';
import { PanelControlBase } from '../../../widgets';
import { Watch } from '../../../decorators';
/**
 * 面板部件基类
 *
 * @export
 * @class AppPanelBase
 * @extends {PanelControlBase}
 */
export class AppPanelBase extends PanelControlBase {
    constructor() {
        super(...arguments);
        /**
         * FLEX布局时类名映射
         *
         * @memberof AppPanelBase
         */
        this.classObj = {
            BUTTON: 'app-viewpanel-button',
            FIELD: 'app-viewpanel-field',
            RAWITEM: 'app-viewpanel-rowitem',
            TABPAGE: 'app-viewpanel-tabpage',
            TABPANEL: 'app-viewpanel-tabpanel',
        };
    }
    /**
     * 监听数据对象
     *
     * @memberof AppPanelBase
     */
    onDataChange(newVal, oldVal) {
        if (newVal) {
            this.computeButtonState(newVal);
            this.panelLogic({ name: '', newVal: null, oldVal: null });
            this.$forceUpdate();
        }
    }
    /**
     * 获取FLEX布局时类名
     * @param item
     */
    renderDetailClass(item) {
        var _a;
        // 映射类名
        let detailClass = this.classObj[item.itemType] || '';
        detailClass += ` viewpanel-${item.itemType.toLowerCase()}-${item.name.toLowerCase()}`;
        if ((_a = item === null || item === void 0 ? void 0 : item.getPSSysCss) === null || _a === void 0 ? void 0 : _a.call(item)) {
            detailClass += ` ${item.getPSSysCss().cssName}`;
        }
        return detailClass;
    }
    /**
     * 获取栅格布局的props
     *
     * @param {*} parent 父
     * @param {*} child 子
     * @returns {*}
     * @memberof AppPanelBase
     */
    getGridLayoutProps(parent, child) {
        let layout = parent === null || parent === void 0 ? void 0 : parent.getPSLayout().layout;
        let { colXS, colSM, colMD, colLG, colXSOffset, colSMOffset, colMDOffset, colLGOffset } = child.getPSLayoutPos();
        // 设置初始值
        colXS = !colXS || colXS == -1 ? 24 : colXS;
        colSM = !colSM || colSM == -1 ? 24 : colSM;
        colMD = !colMD || colMD == -1 ? 24 : colMD;
        colLG = !colLG || colLG == -1 ? 24 : colLG;
        colXSOffset = !colXSOffset || colXSOffset == -1 ? 0 : colXSOffset;
        colSMOffset = !colSMOffset || colSMOffset == -1 ? 0 : colSMOffset;
        colMDOffset = !colMDOffset || colMDOffset == -1 ? 0 : colMDOffset;
        colLGOffset = !colLGOffset || colLGOffset == -1 ? 0 : colLGOffset;
        if (layout == 'TABLE_12COL') {
            // 重新计算12列的栅格数值
            colXS = Math.min(colXS * 2, 24);
            colSM = Math.min(colSM * 2, 24);
            colMD = Math.min(colMD * 2, 24);
            colLG = Math.min(colXS * 2, 24);
            // 重新计算12列的栅格偏移
            let sign = (num) => (num == 0 ? 0 : num / Math.abs(num));
            colXSOffset = sign(colXSOffset) * Math.min(colXSOffset * 2, 24);
            colSMOffset = sign(colSMOffset) * Math.min(colSMOffset * 2, 24);
            colMDOffset = sign(colMDOffset) * Math.min(colMDOffset * 2, 24);
            colLGOffset = sign(colLGOffset) * Math.min(colLGOffset * 2, 24);
        }
        return {
            xs: { span: colXS, offset: colXSOffset },
            sm: { span: colSM, offset: colSMOffset },
            md: { span: colMD, offset: colMDOffset },
            lg: { span: colLG, offset: colLGOffset },
        };
    }
    /**
     * 绘制顶级面板成员集合
     *
     * @memberof AppPanelBase
     */
    renderRootPSPanelItems(controlInstance) {
        var _a;
        return (_a = controlInstance.getRootPSPanelItems()) === null || _a === void 0 ? void 0 : _a.map((container, index) => {
            return this.renderByDetailType(container);
        });
    }
    /**
     * 根据detailType绘制对应detail
     *
     * @param {*} modelJson
     * @memberof AppPanelBase
     */
    renderByDetailType(modelJson) {
        if (modelJson.getPSSysPFPlugin()) {
            const pluginInstance = this.PluginFactory.getPluginInstance('CONTROLITEM', modelJson.getPSSysPFPlugin().pluginCode);
            if (pluginInstance) {
                return pluginInstance.renderCtrlItem(this.$createElement, modelJson, this, this.data);
            }
        }
        else {
            switch (modelJson.itemType) {
                case 'CONTAINER':
                    return this.renderContainer(modelJson);
                case 'BUTTON':
                    return this.renderButton(modelJson);
                case 'FIELD':
                    return this.renderField(modelJson);
                case 'RAWITEM':
                    return this.renderRawitem(modelJson);
                case 'TABPANEL':
                    return this.renderTabPanel(modelJson);
                case 'TABPAGE':
                    return this.renderTabPage(modelJson);
                case 'CONTROL':
                    return this.renderControl(modelJson);
            }
        }
    }
    /**
     * 绘制面板Container
     *
     * @memberof AppPanelBase
     */
    renderContainer(container) {
        var _a, _b, _c, _d, _e, _f;
        const panelItems = container.getPSPanelItems() || [];
        let layout = container.getPSLayout();
        let layoutMode = (_a = container.getPSLayout()) === null || _a === void 0 ? void 0 : _a.layout;
        let css = container.getPSSysCss();
        let containerClass = {
            'app-viewpanel-container': true,
            [`viewpanel-container-${container.name.toLowerCase()}`]: true,
            'show-caption': container.showCaption,
        };
        if (css && css.cssName) {
            Object.assign(containerClass, { [css.cssName]: true });
        }
        let containerStyle = {};
        if (container.width) {
            Object.assign(containerStyle, { width: container.width + 'px' });
        }
        if (container.height) {
            Object.assign(containerStyle, { height: container.height + 'px' });
        }
        if (this.detailsModel[container.name] && !this.detailsModel[container.name].visible) {
            Object.assign(containerStyle, { display: 'none' });
        }
        // FLEX布局
        if (layout && layoutMode == 'FLEX') {
            const containerGrow = (_b = container.getPSLayoutPos()) === null || _b === void 0 ? void 0 : _b.grow;
            Object.assign(containerStyle, {
                overflow: 'auto',
                display: 'flex',
                'flex-grow': containerGrow && containerGrow != -1 ? containerGrow : 0,
            });
            const { dir, align, vAlign } = layout;
            if (dir) {
                Object.assign(containerStyle, { 'flex-direction': dir });
            }
            if (align) {
                Object.assign(containerStyle, { 'justify-content': align });
            }
            if (vAlign) {
                Object.assign(containerStyle, { 'align-items': vAlign });
            }
            return (<i-col style={containerStyle} class={containerClass}>
          {container.showCaption ? (<div class='viewpanel-container-header'>
              <span>{this.$tl((_d = (_c = container.getCapPSLanguageRes) === null || _c === void 0 ? void 0 : _c.call(container)) === null || _d === void 0 ? void 0 : _d.lanResTag, container.caption)}</span>
            </div>) : null}
          {panelItems.map((item, index) => {
                    var _a;
                    // 子样式
                    let { height, width, itemType } = item;
                    let detailStyle = {};
                    if (height) {
                        detailStyle.height = height + 'px';
                    }
                    if (this.detailsModel[item.name] && !this.detailsModel[item.name].visible) {
                        Object.assign(detailStyle, { display: 'none' });
                    }
                    switch (itemType) {
                        case 'CONTAINER':
                            return this.renderByDetailType(item);
                        case 'CTRLPOS':
                            detailStyle.width = width ? width + 'px' : '100%';
                            break;
                    }
                    if (item.getPSLayoutPos()) {
                        let grow = (_a = item.getPSLayoutPos()) === null || _a === void 0 ? void 0 : _a.grow;
                        detailStyle.flexGrow = grow != -1 ? grow : 0;
                    }
                    // 自定义类名
                    const controlClassName = this.renderDetailClass(item);
                    return (<div style={detailStyle} class={controlClassName}>
                {this.renderByDetailType(item)}
              </div>);
                })}
        </i-col>);
        }
        else {
            let attrs = this.getGridLayoutProps(null, container);
            // 栅格布局
            return (<i-col {...{ props: attrs }} style={containerStyle} class={containerClass}>
          {container.showCaption ? (<row class='viewpanel-container-header'>
              <span>{this.$tl((_f = (_e = container.getCapPSLanguageRes) === null || _e === void 0 ? void 0 : _e.call(container)) === null || _f === void 0 ? void 0 : _f.lanResTag, container.caption)}</span>
            </row>) : null}
          {panelItems.map((item, index) => {
                    let { height, width, itemType } = item;
                    let detailStyle = {};
                    if (this.detailsModel[item.name] && !this.detailsModel[item.name].visible) {
                        Object.assign(detailStyle, { display: 'none' });
                    }
                    if (height) {
                        detailStyle.height = height + 'px';
                    }
                    switch (itemType) {
                        case 'CONTAINER':
                            return this.renderByDetailType(item);
                        case 'CTRLPOS':
                            detailStyle.width = width ? width + 'px' : '100%';
                            break;
                    }
                    // 栅格布局
                    let attrs = this.getGridLayoutProps(container, item);
                    // 自定义类名
                    const controlClassName = this.renderDetailClass(item);
                    return (<i-col {...{ props: attrs }} style={detailStyle} class={controlClassName}>
                {this.renderByDetailType(item)}
              </i-col>);
                })}
        </i-col>);
        }
    }
    /**
     * 绘制面板Button
     *
     * @memberof AppPanelBase
     */
    renderButton(modelJson) {
        var _a, _b, _c, _d, _e;
        let { caption, showCaption, name, height, tooltip, width } = modelJson;
        const buttonStyle = {
            height: height && height > 0 ? height + 'px' : '',
            width: width && width > 0 ? width + 'px' : '',
        };
        const icon = modelJson.getPSSysImage();
        const uiAction = modelJson.getPSUIAction();
        return (<app-panel-button buttonStyle={buttonStyle} caption={this.$tl((_a = uiAction === null || uiAction === void 0 ? void 0 : uiAction.getCapPSLanguageRes()) === null || _a === void 0 ? void 0 : _a.lanResTag, caption)} tooltip={this.$tl((_b = uiAction === null || uiAction === void 0 ? void 0 : uiAction.getTooltipPSLanguageRes()) === null || _b === void 0 ? void 0 : _b.lanResTag, tooltip)} icon={(icon === null || icon === void 0 ? void 0 : icon.cssClass) ? icon.cssClass : ((_c = uiAction === null || uiAction === void 0 ? void 0 : uiAction.getPSSysImage()) === null || _c === void 0 ? void 0 : _c.cssClass) ? (_d = uiAction.getPSSysImage()) === null || _d === void 0 ? void 0 : _d.cssClass : null} imagePath={(icon === null || icon === void 0 ? void 0 : icon.imagePath) ? icon.imagePath : null} showCaption={showCaption} disabled={(_e = this.detailsModel[name]) === null || _e === void 0 ? void 0 : _e.disabled} on-onClick={($event) => {
                throttle(this.buttonClick, [this.controlInstance.name, { tag: name }, $event], this);
            }}></app-panel-button>);
    }
    /**
     * 绘制面板Field
     *
     * @memberof AppPanelBase
     */
    renderField(modelJson) {
        var _a, _b, _c, _d;
        let { name, caption, hidden, showCaption } = modelJson;
        const editor = modelJson.getPSEditor();
        let customCode = false;
        if (this.dataMap && this.dataMap.get(name)) {
            customCode = this.dataMap.get(name).customCode;
        }
        if (this.needFindDEField) {
            this.findDEFieldForPanelField(modelJson);
        }
        let labelPos = 'LEFT';
        return (!hidden && (<app-panel-field name={name} labelPos={labelPos} caption={this.$tl((_a = modelJson.getCapPSLanguageRes()) === null || _a === void 0 ? void 0 : _a.lanResTag, caption)} isEmptyCaption={!showCaption} error={(_b = this.rules[editor.name]) === null || _b === void 0 ? void 0 : _b.message} data={this.data} value={this.data[name]} itemRules={this.rules[editor.name]} required={(_c = this.detailsModel[modelJson.name]) === null || _c === void 0 ? void 0 : _c.required}>
          {editor && !customCode && (<app-default-editor value={this.data[editor.name]} editorInstance={editor} containerCtrl={this.controlInstance} parentItem={modelJson} contextData={this.data} valueFormat={modelJson.valueFormat} context={this.context} viewparams={this.viewparams} disabled={(_d = this.detailsModel[modelJson.name]) === null || _d === void 0 ? void 0 : _d.disabled} on-change={(value) => {
                    this.onPanelItemValueChange(this.data, value);
                }}/>)}
          {customCode &&
                this.$createElement('div', {
                    domProps: {
                        innerHTML: this.data[name],
                    },
                })}
        </app-panel-field>));
    }
    /**
     * 绘制面板Rawitem
     *
     * @memberof AppPanelBase
     */
    renderRawitem(modelJson) {
        var _a, _b, _c;
        const data = this.data;
        let { rawItemHeight, rawItemWidth, contentType, htmlContent, rawContent } = modelJson;
        let sysCssName = (_a = modelJson.getPSSysCss()) === null || _a === void 0 ? void 0 : _a.cssName;
        let sysImage = (_b = modelJson.getPSSysImage()) === null || _b === void 0 ? void 0 : _b.cssClass;
        let sysImgurl = (_c = modelJson.getPSSysImage()) === null || _c === void 0 ? void 0 : _c.imagePath;
        const style = {
            width: rawItemWidth > 0 ? `${rawItemWidth}px` : '100%',
            height: rawItemHeight > 0 ? `${rawItemHeight}px` : '',
        };
        let content;
        if (Object.is(contentType, 'RAW')) {
            content = rawContent;
        }
        else if (Object.is(contentType, 'HTML')) {
            content = htmlContent;
        }
        if (content) {
            const items = content.match(/\{{(.+?)\}}/g);
            if (items) {
                items.forEach((item) => {
                    content = content.replace(/\{{(.+?)\}}/, eval(item.substring(2, item.length - 2)));
                });
            }
            content = content.replaceAll('&lt;', '<');
            content = content.replaceAll('&gt;', '>');
            content = content.replaceAll('&amp;nbsp;', ' ');
            content = content.replaceAll('&nbsp;', ' ');
        }
        return (<app-rawitem class={sysCssName} style={style} viewparams={this.viewparams} context={this.context} contentType={contentType} imageClass={sysImage} imgUrl={sysImgurl} content={content}></app-rawitem>);
    }
    /**
     * 绘制面板TabPanel
     *
     * @memberof AppPanelBase
     */
    renderTabPanel(modelJson) {
        var _a;
        let activatedPage = (_a = this.detailsModel[modelJson.name]) === null || _a === void 0 ? void 0 : _a.activatedPage;
        const tabPages = modelJson.getPSPanelTabPages() || [];
        return (<i-col class={this.renderDetailClass(modelJson)}>
        <el-tabs v-model={activatedPage} on-tab-click={($event) => throttle(this.handleTabPanelClick, [modelJson.name, $event], this)} class={this.renderDetailClass(modelJson)}>
          {tabPages.length > 0
                ? tabPages.map((item, index) => {
                    return this.renderTabPage(item);
                })
                : null}
        </el-tabs>
      </i-col>);
    }
    /**
     * 绘制面板TabPage
     *
     * @memberof AppPanelBase
     */
    renderTabPage(modelJson) {
        var _a, _b;
        let label = this.$tl((_b = (_a = modelJson.getCapPSLanguageRes) === null || _a === void 0 ? void 0 : _a.call(modelJson)) === null || _b === void 0 ? void 0 : _b.lanResTag, modelJson.caption) || '分页';
        const panelItems = modelJson.getPSPanelItems() || [];
        return (<el-tab-pane label={label} name={modelJson.name} class={this.renderDetailClass(modelJson)} lazy>
        {panelItems.map((item, index) => {
                return this.renderByDetailType(item);
            })}
      </el-tab-pane>);
    }
    /**
     * 绘制面板Control
     *
     * @memberof AppPanelBase
     */
    renderControl(modelJson) {
        var _a, _b;
        const { showCaption, caption, height, width } = modelJson;
        const cssName = (_a = modelJson.getPSSysCss()) === null || _a === void 0 ? void 0 : _a.cssName;
        const controlStyle = {
            height: height ? height + 'px' : '',
            width: width ? width + 'px' : '100%',
        };
        const controlModelJson = modelJson.getPSControl();
        return (<div class={['control', cssName, (_b = controlModelJson === null || controlModelJson === void 0 ? void 0 : controlModelJson.controlType) === null || _b === void 0 ? void 0 : _b.toLocaleLowerCase()]} style={controlStyle}>
        {showCaption && caption ? (<div class='control-caption'>
            <p>{caption}</p>
            <el-divider></el-divider>
          </div>) : null}
        <div class={{ 'control-with-caption': showCaption, 'control-without-caption': !showCaption }}>{this.renderByControlType(controlModelJson)}</div>
      </div>);
    }
    /**
     * 根据controlType绘制对应control
     *
     * @param {*} modelJson
     * @memberof AppPanelBase
     */
    renderByControlType(modelJson) {
        switch (modelJson.controlType) {
            case 'VIEWPANEL':
                return this.renderViewPanel(modelJson);
        }
    }
    /**
     * 绘制ViewPanel
     *
     * @param {*} control
     * @memberof AppPanelBase
     */
    renderViewPanel(modelJson) {
        var _a, _b;
        let controlAppView = modelJson.getEmbeddedPSAppDEView();
        if (!controlAppView) {
            return;
        }
        const { modelFilePath, name } = controlAppView;
        let tempContext = Object.assign(Util.deepCopy(this.context), { viewpath: modelFilePath });
        const appDeKeyCodeName = (_b = (_a = this.controlInstance.getPSAppDataEntity()) === null || _a === void 0 ? void 0 : _a.codeName) === null || _b === void 0 ? void 0 : _b.toLowerCase();
        if (appDeKeyCodeName) {
            Object.assign(tempContext, { [appDeKeyCodeName]: this.data.srfkey });
        }
        return this.$createElement('app-view-shell', {
            props: {
                staticProps: {
                    portletState: this.viewState,
                    viewDefaultUsage: false,
                    viewModelData: controlAppView,
                },
                dynamicProps: {
                    viewdata: JSON.stringify(tempContext),
                    viewparam: JSON.stringify(this.viewparams),
                },
            },
            on: {
                viewIsMounted: () => {
                    this.setIsMounted(controlAppView === null || controlAppView === void 0 ? void 0 : controlAppView.name);
                },
            },
            ref: name,
        });
    }
    /**
     * 绘制面板
     *
     * @returns {*}
     * @memberof AppPanelBase
     */
    render() {
        if (!this.controlIsLoaded) {
            return null;
        }
        let controlClassNames = Object.assign({ 'app-viewpanel': true }, this.renderOptions.controlClassNames);
        let { width, height, layoutMode } = this.controlInstance;
        let controlStyle = {};
        controlStyle.width = width > 0 ? width + 'px' : 'auto';
        controlStyle.height = height > 0 ? height + 'px' : '100%';
        if (layoutMode == 'FLEX') {
            controlStyle.display = 'flex';
        }
        return (
        // height为100%，适配占满
        <div class='viewpanel-container' style={{ width: '100%', height: '100%' }}>
        <row class={controlClassNames} style={controlStyle}>
          {this.renderRootPSPanelItems(this.controlInstance)}
        </row>
      </div>);
    }
}
__decorate([
    Watch('data', { deep: true })
], AppPanelBase.prototype, "onDataChange", null);
