import { throttle, LayoutTool, Util } from '@ibizstudio/runtime';
import { EditFormControlBase } from '../../../widgets';
/**
 * 编辑表单部件基类
 *
 * @export
 * @class AppFormBase
 * @extends {EditFormControlBase}
 */
export class AppFormBase extends EditFormControlBase {
    /**
     * 绘制子表单成员,布局控制
     *
     * @param {*} modelJson
     * @returns
     * @memberof AppFormBase
     */
    renderDetails(modelJson) {
        let formDetails = modelJson.getPSDEFormDetails();
        let layout = modelJson.getPSLayout();
        // 没有子表单成员
        if (!formDetails || formDetails.length == 0) {
            return null;
        }
        // 无布局
        if (!layout) {
            return formDetails.map((item, index) => {
                return this.renderByDetailType(item, index);
            });
        }
        // 栅格布局
        if (layout.layout == 'TABLE_24COL' || layout.layout == 'TABLE_12COL' || layout.layout == 'TABLE') {
            return (<row>
          {formDetails.map((item, index) => {
                    if (item.hidden) {
                        return;
                    }
                    let attrs = LayoutTool.getGridOptions(item.getPSLayoutPos());
                    let style = this.getGridLayoutStyle(item);
                    return (<i-col class='form-layout-container' {...{ props: attrs }} style={style}>
                {this.renderByDetailType(item, index)}
              </i-col>);
                })}
        </row>);
        }
        // FLEX布局
        if (layout.layout == 'FLEX') {
            const flexStyle = LayoutTool.getFlexStyle(layout);
            return (<div style={flexStyle}>
          {formDetails.map((item, index) => {
                    if (item.hidden) {
                        return;
                    }
                    let detailStyle = LayoutTool.getFlexStyle2(item === null || item === void 0 ? void 0 : item.getPSLayoutPos());
                    detailStyle += this.detailsModel[item.name].visible ? '' : 'display: none;';
                    return (<div style={detailStyle} class='form-layout-container'>
                {this.renderByDetailType(item, index)}
              </div>);
                })}
        </div>);
        }
        throw new Error(`${layout.layout}${this.$t('app.nosupport.layout')}`);
    }
    /**
     * 获取栅格布局样式
     *
     * @param {*} item
     * @memberof AppFormBase
     */
    getGridLayoutStyle(item) {
        var _a;
        const { name, width, height } = item;
        let style = {};
        if (!((_a = this.detailsModel[name]) === null || _a === void 0 ? void 0 : _a.visible)) {
            Object.assign(style, { display: 'none' });
        }
        if (width && width > 0) {
            Object.assign(style, { width: `${width}px` });
        }
        if (height && height > 0) {
            Object.assign(style, { height: `${height}px` });
        }
        return style;
    }
    /**
     * 根据detailType绘制对应detail
     *
     * @param {*} modelJson
     * @param {number} index
     * @memberof AppFormBase
     */
    renderByDetailType(modelJson, index) {
        var _a;
        if (modelJson.getPSSysPFPlugin()) {
            const pluginInstance = this.PluginFactory.getPluginInstance('CONTROLITEM', ((_a = modelJson.getPSSysPFPlugin()) === null || _a === void 0 ? void 0 : _a.pluginCode) || '');
            if (pluginInstance) {
                return pluginInstance.renderCtrlItem(this.$createElement, modelJson, this, null);
            }
        }
        else {
            switch (modelJson.detailType) {
                case 'FORMPAGE':
                    return this.renderFormPage(modelJson, index);
                case 'GROUPPANEL':
                    return this.renderGroupPanel(modelJson, index);
                case 'TABPAGE':
                    return this.renderTabPage(modelJson, index);
                case 'TABPANEL':
                    return this.renderTabPanel(modelJson, index);
                case 'FORMITEM':
                    return this.renderFormItem(modelJson, index);
                case 'BUTTON':
                    return this.renderButton(modelJson, index);
                case 'DRUIPART':
                    return this.renderDruipart(modelJson, index);
                case 'RAWITEM':
                    return this.renderRawitem(modelJson, index);
                case 'IFRAME':
                    return this.renderIframe(modelJson, index);
                case 'FORMPART':
                    return this.renderFormPart(modelJson, index);
            }
        }
    }
    /**
     * 绘制表单部件
     *
     * @returns
     * @memberof AppFormBase
     */
    renderFormPart(modelJson, index) {
        let { formPartType, name, codeName } = modelJson;
        // 后续补
        let systemCodeName = '', appCodeName = '', deCodeName = '', formCodeName = '';
        if (formPartType && formPartType == 'DYNASYS') {
            return (<app-form-part name={name} context={this.context} viewparams={this.viewparams} systemCodeName={systemCodeName} appCodeName={appCodeName} deCodeName={deCodeName} formCodeName={formCodeName} formDetailCodeName={codeName} on-change={(e) => this.onFormItemValueChange(e)}></app-form-part>);
        }
    }
    /**
     * 绘制iframe
     *
     * @returns
     * @memberof AppFormBase
     */
    renderIframe(modelJson, index) {
        let { contentHeight, iFrameUrl, contentWidth } = modelJson;
        let iframeStyle = {
            height: contentHeight ? contentHeight + 'px' : false,
            width: contentWidth ? contentWidth + 'px' : false,
        };
        return (<div style={iframeStyle}>
        <iframe src={iFrameUrl} style='height: 100%;width: 100%;border: 0'></iframe>
      </div>);
    }
    /**
     * 绘制直接内容
     *
     * @returns
     * @memberof AppDefaultFormBase
     */
    renderRawitem(modelJson, index) {
        var _a, _b, _c;
        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` : false,
            height: rawItemHeight > 0 ? `${rawItemHeight}px` : false,
        };
        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>);
    }
    /**
     * 关系界面保存事件
     *
     * @param {*} e
     * @memberof AppFormBase
     */
    onDrDataSaved(e) {
        this.ctrlEvent({
            controlname: this.controlInstance.name,
            action: 'drdatasaved',
            data: e,
        });
    }
    /**
     * 绘制关系界面
     *
     * @returns
     * @memberof AppFormBase
     */
    renderDruipart(modelJson, index) {
        var _a, _b, _c;
        const { refreshItems, height, parentDataJO } = modelJson;
        const layoutPos = modelJson.getPSLayoutPos();
        const appView = modelJson.getPSAppView();
        const appDERSPaths = appView === null || appView === void 0 ? void 0 : appView.getPSAppDERSPaths();
        const appDataEntity = this.controlInstance.getPSAppDataEntity();
        let tempContext = Util.deepCopy(this.context);
        // druipart样式
        let druipartHeight;
        if ((layoutPos === null || layoutPos === void 0 ? void 0 : layoutPos.layout) == 'FlEX') {
            druipartHeight = '100%';
        }
        else if (!height && (appView === null || appView === void 0 ? void 0 : appView.height) > 0) {
            druipartHeight = appView.height;
        }
        else {
            druipartHeight = Util.isNumber(height) && height > 0 ? `${height}px` : '100%';
        }
        let druipartStyle = { height: druipartHeight, overflow: 'auto' };
        return (<app-form-druipart class={(_a = modelJson.getPSSysCss()) === null || _a === void 0 ? void 0 : _a.cssName} isForbidLoad={this.data.srfuf === '0'} userTag={modelJson.userTag ? modelJson.userTag : ''} paramItem={modelJson.paramItem ? modelJson.paramItem : (_b = appDataEntity === null || appDataEntity === void 0 ? void 0 : appDataEntity.codeName) === null || _b === void 0 ? void 0 : _b.toLowerCase()} parentdata={parentDataJO || undefined} parameters={Util.formatAppDERSPath(this.context, appDERSPaths)} context={tempContext} viewModelData={appView} viewparams={this.viewparams} parameterName={(_c = appDataEntity === null || appDataEntity === void 0 ? void 0 : appDataEntity.codeName) === null || _c === void 0 ? void 0 : _c.toLowerCase()} parentName={appDataEntity === null || appDataEntity === void 0 ? void 0 : appDataEntity.codeName} appViewtype={appView === null || appView === void 0 ? void 0 : appView.viewType} refreshitems={refreshItems || undefined} ignorefieldvaluechange={this.ignorefieldvaluechange} viewname={appView === null || appView === void 0 ? void 0 : appView.codeName} localContext={Util.formatNavParam(modelJson.getPSNavigateContexts())} localParam={Util.formatNavParam(modelJson.getPSNavigateParams())} tempMode={(appView === null || appView === void 0 ? void 0 : appView.tempMode) ? appView === null || appView === void 0 ? void 0 : appView.tempMode : 0} data={JSON.stringify(this.data)} on-drdatasaved={($event) => this.drdatasaved($event)} style={druipartStyle}></app-form-druipart>);
    }
    /**
     * 绘制按钮
     *
     * @returns
     * @memberof AppFormBase
     */
    renderButton(modelJson, index) {
        var _a, _b, _c;
        const { width, height, showCaption, caption } = modelJson;
        const uiAction = modelJson.getPSUIAction();
        const sysCss = modelJson.getPSSysCss();
        let btnClass = width > 0 && height > 0 ? { width: `${width}px`, height: `${height}px` } : '';
        let badge = null;
        // TODO计数器徽章
        // if (uiAction) {
        //     let { appCounter, counterId } = uiAction;
        //     let { codeName } = appCounter;
        //     let count = codeName + 'counterservice.counterData.' + counterId;
        //     badge = <badge type='primary' count={count}></badge>;
        // }
        // 自定义类名
        const controlClassNames = { 'app-form-button': true };
        if (sysCss === null || sysCss === void 0 ? void 0 : sysCss.cssName) {
            Object.assign(controlClassNames, { [sysCss.cssName]: true });
        }
        let labelCaption = this.$tl((_a = modelJson.getCapPSLanguageRes()) === null || _a === void 0 ? void 0 : _a.lanResTag, caption);
        // 计算图标绘制参数
        const sysImage = modelJson.getPSSysImage();
        const actionImage = uiAction === null || uiAction === void 0 ? void 0 : uiAction.getPSSysImage();
        let iconItem = {
            iconcls: (sysImage === null || sysImage === void 0 ? void 0 : sysImage.cssClass) || (actionImage === null || actionImage === void 0 ? void 0 : actionImage.cssClass),
            icon: (sysImage === null || sysImage === void 0 ? void 0 : sysImage.imagePath) || (actionImage === null || actionImage === void 0 ? void 0 : actionImage.imagePath),
        };
        // 由detailsModel控制按钮显示与否
        if (!((_b = this.detailsModel[modelJson.name]) === null || _b === void 0 ? void 0 : _b.visible)) {
            return null;
        }
        return (<div class='form-button-container'>
        {badge}
        <i-button type='primary' class={controlClassNames} style={btnClass} on-click={($event) => throttle(this.onFormItemActionClick, [{ formdetail: modelJson, event: $event }], this)} disabled={(_c = this.detailsModel[modelJson.name]) === null || _c === void 0 ? void 0 : _c.disabled}>
          <menu-icon item={iconItem}/>
          {showCaption && <span>{labelCaption}</span>}
        </i-button>
      </div>);
    }
    /**
     * 绘制表单项
     *
     * @returns
     * @memberof AppFormBase
     */
    renderFormItem(modelJson, index) {
        var _a;
        const { compositeItem, contentWidth, contentHeight } = modelJson;
        let editor = modelJson.getPSEditor();
        const refFormItem = [];
        const style = {
            width: contentWidth ? `${contentWidth}px` : false,
            height: contentHeight ? `${contentHeight}px` : false,
        };
        if (compositeItem) {
            let formItems = modelJson.getPSDEFormItems();
            formItems === null || formItems === void 0 ? void 0 : formItems.forEach((formItem) => {
                refFormItem.push(formItem === null || formItem === void 0 ? void 0 : formItem.id);
            });
        }
        const isDebounce = !Object.is(this.controlInstance.controlType, 'FORM');
        // 代码编辑器动态控制切换时重绘
        let isEditorRender = true;
        if ((editor === null || editor === void 0 ? void 0 : editor.editorType) == "CODE") {
            isEditorRender = this.detailsModel[modelJson.name].visible;
        }
        return (<app-default-form-item detailsInstance={modelJson} index={index} data={this.data} modelService={this.modelService} rules={this.rules[modelJson.name]} runtimeModel={this.detailsModel[modelJson.name]} context={Util.deepCopy(this.context)} viewparams={Util.deepCopy(this.viewparams)} service={this.service} ignorefieldvaluechange={this.ignorefieldvaluechange} on-formItemValueChange={(value) => {
                this.onFormItemValueChange(value);
            }} controlInstance={this.controlInstance}>
        {editor && isEditorRender && (<app-default-editor editorInstance={editor} containerCtrl={this.controlInstance} parentItem={modelJson} value={this.data[editor === null || editor === void 0 ? void 0 : editor.name]} contextData={this.data} valueFormat={modelJson.valueFormat} context={Util.deepCopy(this.context)} viewparams={Util.deepCopy(this.viewparams)} service={this.service} disabled={(_a = this.detailsModel[modelJson.name]) === null || _a === void 0 ? void 0 : _a.disabled} isDebounce={isDebounce} ignorefieldvaluechange={this.ignorefieldvaluechange} on-change={(value) => {
                    this.onFormItemValueChange(value);
                }}/>)}
      </app-default-form-item>);
    }
    /**
     * 绘制分页部件panel
     *
     * @returns
     * @memberof AppFormBase
     */
    renderTabPanel(modelJson, index) {
        var _a, _b, _c;
        return (<app-default-form-tab-panel detailsInstance={modelJson} index={index} modelService={this.modelService} runtimeModel={this.detailsModel[modelJson.name]} controlInstance={this.controlInstance}>
        {((_b = (_a = modelJson.getPSDEFormTabPages) === null || _a === void 0 ? void 0 : _a.call(modelJson)) === null || _b === void 0 ? void 0 : _b.length) &&
                ((_c = modelJson.getPSDEFormTabPages()) === null || _c === void 0 ? void 0 : _c.map((item, index2) => {
                    return this.renderTabPage(item, index2);
                }))}
      </app-default-form-tab-panel>);
    }
    /**
     * 绘制分页部件
     *
     * @returns
     * @memberof AppFormBase
     */
    renderTabPage(modelJson, index) {
        return (<app-default-form-tab-page modelService={this.modelService} detailsInstance={modelJson} index={index} runtimeModel={this.detailsModel[modelJson.name]} controlInstance={this.controlInstance}>
        {this.renderDetails(modelJson)}
      </app-default-form-tab-page>);
    }
    /**
     * 绘制分组面板
     *
     * @returns
     * @memberof AppFormBase
     */
    renderGroupPanel(modelJson, index) {
        return (<app-default-group-panel detailsInstance={modelJson} id={modelJson.codeName} modelService={this.modelService} index={index} runtimeModel={this.detailsModel[modelJson.name]} controlInstance={this.controlInstance} on-groupUIActionClick={(...params) => throttle(this.handleActionClick, params, this)} on-managecontainerclick={(...params) => throttle(this.manageContainerClick, params, this)} context={this.context} viewparams={this.viewparams} data={this.data}>
        {this.renderDetails(modelJson)}
      </app-default-group-panel>);
    }
    /**
     * 绘制表单分页
     *
     * @returns
     * @memberof AppFormBase
     */
    renderFormPage(modelJson, index) {
        const { noTabHeader } = this.controlInstance;
        if (noTabHeader) {
            return this.renderDetails(modelJson);
        }
        return (<app-default-form-page modelService={this.modelService} detailsInstance={modelJson} index={index} runtimeModel={this.detailsModel[modelJson.name]} controlInstance={this.controlInstance}>
        {this.renderDetails(modelJson)}
      </app-default-form-page>);
    }
    /**
     * 绘制表单内容
     *
     * @returns
     * @memberof AppFormBase
     */
    renderFormContent() {
        var _a, _b, _c;
        const { noTabHeader, codeName, name, controlType } = this.controlInstance;
        const formPages = this.controlInstance.getPSDEFormPages();
        if (formPages && formPages.length > 0) {
            if (noTabHeader) {
                return formPages.map((item, index) => {
                    if (this.detailsModel[item.name].visible) {
                        return this.renderFormPage(item, index);
                    }
                    else {
                        return;
                    }
                });
            }
            else {
                const tabsName = `${(_b = (_a = this.controlInstance.getPSAppDataEntity()) === null || _a === void 0 ? void 0 : _a.codeName) === null || _b === void 0 ? void 0 : _b.toLowerCase()}_${controlType === null || controlType === void 0 ? void 0 : controlType.toLowerCase()}_${codeName === null || codeName === void 0 ? void 0 : codeName.toLowerCase()}`;
                return (<tabs animated={false} name={tabsName} value={(_c = this.detailsModel[name]) === null || _c === void 0 ? void 0 : _c.activatedPage} on-on-click={(e) => {
                        var _a;
                        throttle((_a = this.detailsModel[name]) === null || _a === void 0 ? void 0 : _a.clickPage, [e], this);
                    }}>
            {formPages.map((item, index) => {
                        if (this.detailsModel[item.name].visible) {
                            return this.renderFormPage(item, index);
                        }
                        else {
                            return;
                        }
                    })}
          </tabs>);
            }
        }
    }
    /**
     * 绘制内容
     *
     * @returns
     * @memberof AppFormBase
     */
    render() {
        var _a, _b, _c;
        if (!this.controlIsLoaded) {
            return null;
        }
        const { controlClassNames } = this.renderOptions;
        let formId = ((_b = (_a = this.controlInstance.getPSAppDataEntity()) === null || _a === void 0 ? void 0 : _a.codeName) === null || _b === void 0 ? void 0 : _b.toLowerCase()) + ((_c = this.controlInstance.codeName) === null || _c === void 0 ? void 0 : _c.toLowerCase());
        let controlStyle = {
            width: this.controlInstance.width ? this.controlInstance.width + 'px' : '',
            height: this.controlInstance.height ? this.controlInstance.height + 'px' : '',
        };
        const viewType = this.controlInstance.getParentPSModelObject().viewType;
        return (<i-form props={{ model: this.data }} class={Object.assign(Object.assign({}, controlClassNames), { 'app-form': true })} ref={this.controlInstance.name} id={formId} style={controlStyle} on-on-validate={this.formItemValidate.bind(this)}>
        <input style='display:none;'/>
        {this.showFormNavBar && this.groupAnchorDatas.length > 0 ? <app-anchor viewType={viewType} anchorDatas={this.groupAnchorDatas}></app-anchor> : null}
        <row>{this.renderFormContent()}</row>
      </i-form>);
    }
}
