import { __decorate } from "tslib";
import { Subject } from 'rxjs';
import { Provide } from 'vue-property-decorator';
import { ModelTool, Verify, AppErrorCode, EntityFieldErrorCode } from '@ibizstudio/runtime';
import { MainControlBase } from './main-control-base';
/**
 * 表单部件基类
 *
 * @export
 * @class FormControlBase
 * @extends {MainControlBase}
 */
export class FormControlBase extends MainControlBase {
    constructor() {
        super(...arguments);
        /**
         * 表单数据对象
         *
         * @type {*}
         * @memberof FormControlBase
         */
        this.data = {};
        /**
         * 表单状态
         *
         * @type {Subject<any>}
         * @memberof FormControlBase
         */
        this.formState = new Subject();
        /**
         * 忽略表单项值变化
         *
         * @type {boolean}
         * @memberof FormControlBase
         */
        this.ignorefieldvaluechange = false;
        /**
         * 值规则
         *
         * @type {*}
         * @memberof FormControlBase
         */
        this.rules = {};
        /**
         * 转化代码项值映射
         *
         * @type {Map<string,IParams>}
         * @memberof FormControlBase
         */
        this.codeItemTextMap = new Map();
    }
    /**
     * 获取多项数据
     *
     * @returns {any[]}
     * @memberof FormControlBase
     */
    getDatas() {
        return [this.getData()];
    }
    /**
     * 获取单项数据
     *
     * @returns {*}
     * @memberof FormControlBase
     */
    getData() {
        const data = {};
        for (const key in this.data) {
            if (Object.prototype.hasOwnProperty.call(this.data, key)) {
                const item = this.detailsModel[key];
                if ((item === null || item === void 0 ? void 0 : item.ignoreInput) === 4 && item.disabled) {
                    continue;
                }
                const val = this.data[key];
                data[key] = val;
            }
        }
        if (this.codeItemTextMap.size > 0) {
            this.codeItemTextMap.forEach((value, key) => {
                const { val } = value;
                data[key] = val;
            });
        }
        return data;
    }
    /**
     * 重置表单项值
     *
     * @public
     * @param {{ name: string, newVal: any, oldVal: any }} { name, newVal, oldVal } 名称,新值，旧值
     * @memberof FormControlBase
     */
    resetFormData({ name, newVal, oldVal }) { }
    /**
     * 表单逻辑
     *
     * @public
     * @param {{ name: string, newVal: any, oldVal: any }} { name, newVal, oldVal } 名称,新值，旧值
     * @memberof FormControlBase
     */
    async formLogic({ name, newVal, oldVal }) { }
    /**
     * 表单值变化
     *
     * @public
     * @param {{ name: string, newVal: any, oldVal: any }} { name, newVal, oldVal } 名称,新值，旧值
     * @returns {void}
     * @memberof FormControlBase
     */
    formDataChange({ name, newVal, oldVal }) { }
    /**
     * 表单加载完成
     *
     * @public
     * @param {*} [data={}] 表单数据
     * @param {string} [action] 行为标识
     * @memberof FormControlBase
     */
    onFormLoad(data = {}, action) { }
    /**
     * 值填充
     *
     * @param {*} [_datas={}] 表单数据
     * @param {string} [action] 行为标识
     * @memberof FormControlBase
     */
    fillForm(_datas = {}, action) {
        this.ignorefieldvaluechange = true;
        Object.keys(_datas).forEach((name) => {
            if (this.data.hasOwnProperty(name)) {
                this.data[name] = _datas[name];
            }
        });
        if (Object.is(action, 'loadDraft')) {
            this.createDefault();
        }
        this.$nextTick(function () {
            this.ignorefieldvaluechange = false;
        });
    }
    /**
     * 设置表单项是否启用
     *
     * @public
     * @param {*} data 表单数据
     * @memberof FormControlBase
     */
    setFormEnableCond(data) {
        Object.values(this.detailsModel).forEach((detail) => {
            if (!Object.is(detail.detailType, 'FORMITEM')) {
                return;
            }
            const formItem = detail;
            formItem.setEnableCond(data.srfuf);
        });
    }
    /**
     * 新建默认值
     * @memberof FormControlBase
     */
    createDefault() { }
    /**
     * 重置草稿表单状态
     *
     * @public
     * @memberof FormControlBase
     */
    resetDraftFormStates() {
        const form = this.$refs[this.controlInstance.name];
        if (form) {
            form.resetFields();
        }
    }
    /**
     * 重置校验结果
     *
     * @memberof FormControlBase
     */
    resetValidates() {
        Object.values(this.detailsModel).forEach((detail) => {
            if (!Object.is(detail.detailType, 'FORMITEM')) {
                return;
            }
            const formItem = detail;
            formItem.setError('');
        });
    }
    /**
     * 填充校验结果 （后台）
     *
     * @param {any[]} fieldErrors 校验数组
     * @memberof FormControlBase
     */
    fillValidates(fieldErrors) {
        fieldErrors.forEach((error) => {
            const formItem = this.detailsModel[error.field];
            if (!formItem) {
                return;
            }
            this.$nextTick(() => {
                formItem.setError(error.message);
            });
        });
    }
    /**
     * 表单校验状态
     *
     * @returns {boolean}
     * @memberof FormControlBase
     */
    formValidateStatus() {
        const form = this.$refs[this.controlInstance.name];
        let validatestate = true;
        form.validate((valid) => {
            validatestate = valid ? true : false;
        });
        return validatestate;
    }
    /**
     * 表单项值变更
     *
     * @param {{ name: string, value: any }} $event 名称，值
     * @returns {void}
     * @memberof FormControlBase
     */
    onFormItemValueChange($event) {
        if (!$event || !$event.name || Object.is($event.name, '') || !this.data.hasOwnProperty($event.name)) {
            return;
        }
        this.validateEditorRuleAction($event.name, $event.value);
        this.data[$event.name] = $event.value;
        this.formDataChange({ name: $event.name, newVal: $event.value, oldVal: null });
    }
    /**
     * 校验编辑器基础规则后续行为
     *
     * @param {string} name 名称
     * @param {*} value 值
     * @returns {void}
     * @memberof FormControlBase
     */
    validateEditorRuleAction(name, value) {
        let allFormItems = ModelTool.getAllFormItems(this.controlInstance);
        if ((allFormItems === null || allFormItems === void 0 ? void 0 : allFormItems.length) > 0) {
            let curFormItem = allFormItems === null || allFormItems === void 0 ? void 0 : allFormItems.find((item) => {
                return item.name === name;
            });
            if (!curFormItem)
                return;
            let condition = Verify.buildVerConditions(curFormItem.getPSEditor());
            if (condition && condition.length > 0) {
                // todo 提示info
            }
        }
    }
    /**
     * @description 校验是否忽略输入值
     * @protected
     * @param {string} name
     * @param {('before' | 'change')} [step='change'] {before：表单值变化之前，change：表单值变化}
     * @return {*}  {boolean}
     * @memberof FormControlBase
     */
    checkIgnoreInput(name, step = 'change') {
        const formDetail = this.detailsModel[name];
        if (formDetail) {
            switch (formDetail.ignoreInput) {
                case 4: //表单项禁用
                    if (formDetail.disabled) {
                        return true;
                    }
                    break;
            }
        }
        return false;
    }
    /**
     * 设置数据项值
     *
     * @param {string} name 名称
     * @param {*} value 值
     * @returns {void}
     * @memberof FormControlBase
     */
    setDataItemValue(name, value) {
        if (!name || Object.is(name, '') || !this.data.hasOwnProperty(name)) {
            return;
        }
        if (Object.is(this.data[name], value)) {
            return;
        }
        this.data[name] = value;
    }
    /**
     * 分组界面行为事件
     *
     * @param {*} $event
     * @memberof FormControlBase
     */
    groupUIActionClick($event) { }
    /**
     * 编辑表单初始化
     *
     * @memberof FormControlBase
     */
    ctrlInit(args) {
        super.ctrlInit(args);
        // 初始化默认值
        this.dataChang = new Subject();
        this.ignorefieldvaluechange = false;
    }
    viewStateAction(tag, action, data) {
        if (!Object.is(tag, this.name)) {
            return;
        }
        super.viewStateAction(tag, action, data);
        if (Object.is('autoload', action)) {
            this.autoLoad(data);
        }
        if (Object.is('load', action)) {
            this.load(data);
        }
        if (Object.is('loaddraft', action)) {
            this.loadDraft(data);
        }
    }
    /**
     * 表单销毁
     *
     * @memberof FormControlBase
     */
    ctrlDestroyed(args) {
        var _a;
        super.ctrlDestroyed();
        (_a = this.dataChang) === null || _a === void 0 ? void 0 : _a.complete();
        this.formState.complete();
    }
    /**
     * 表单自动加载
     *
     * @param {*} [arg={}] 加载参数
     * @returns {void}
     * @memberof FormControlBase
     */
    autoLoad(arg = {}) {
        if (arg.srfkey && !Object.is(arg.srfkey, '')) {
            Object.assign(arg, { srfkey: arg.srfkey });
            this.load(arg);
            return;
        }
        if (arg.srfkeys && !Object.is(arg.srfkeys, '')) {
            Object.assign(arg, { srfkey: arg.srfkeys });
            this.load(arg);
            return;
        }
        this.loadDraft(arg);
    }
    /**
     * 加载
     *
     * @public
     * @param {*} [opt={}] 加载参数
     * @memberof FormControlBase
     */
    async load(opt = {}) {
        if (!this.loadAction) {
            this.$throw(`${this.controlInstance.codeName}` + this.$t('app.formpage.notconfig.loadaction'), 'load');
            return;
        }
        const arg = Object.assign({}, opt);
        let tempContext = JSON.parse(JSON.stringify(this.context));
        let viewparamResult = Object.assign(arg, this.viewparams);
        let beforeloadResult = await this.executeCtrlEventLogic('onbeforeload', {
            action: this.loadAction,
            sender: this,
            navContext: this.context,
            navParam: viewparamResult,
            navData: this.navdatas,
            data: this.getData(),
        });
        if (beforeloadResult && (beforeloadResult === null || beforeloadResult === void 0 ? void 0 : beforeloadResult.hasOwnProperty('srfret')) && !beforeloadResult.srfret) {
            return;
        }
        this.ctrlEvent({
            controlname: this.controlInstance.name,
            action: 'onbeforeload',
            data: { action: this.loadAction, sender: this, navContext: this.context, navParam: viewparamResult, navData: this.navdatas, data: this.getData() },
        });
        this.onControlRequset('load', tempContext, viewparamResult);
        const get = this.service.get(this.loadAction, tempContext, { viewparams: viewparamResult }, this.showBusyIndicator);
        get
            .then(async (response) => {
            this.onControlResponse('load', response);
            if (!response.status || response.status !== 200) {
                let loaderrorResult = await this.executeCtrlEventLogic('onloaderror', {
                    action: this.loadAction,
                    sender: this,
                    navContext: this.context,
                    navParam: viewparamResult,
                    navData: this.navdatas,
                    data: response === null || response === void 0 ? void 0 : response.data,
                });
                if (loaderrorResult && (loaderrorResult === null || loaderrorResult === void 0 ? void 0 : loaderrorResult.hasOwnProperty('srfret')) && !loaderrorResult.srfret) {
                    return;
                }
                this.ctrlEvent({
                    controlname: this.controlInstance.name,
                    action: 'onloaderror',
                    data: { action: this.loadAction, sender: this, navContext: this.context, navParam: viewparamResult, navData: this.navdatas, data: response === null || response === void 0 ? void 0 : response.data },
                });
                this.$throw(response, 'load');
                return;
            }
            const data = response.data;
            let loadsuccessResult = await this.executeCtrlEventLogic('onloadsuccess', {
                action: this.loadAction,
                sender: this,
                navContext: this.context,
                navParam: viewparamResult,
                navData: this.navdatas,
                data: data,
            });
            if (loadsuccessResult && (loadsuccessResult === null || loadsuccessResult === void 0 ? void 0 : loadsuccessResult.hasOwnProperty('srfret')) && !loadsuccessResult.srfret) {
                return;
            }
            this.ctrlEvent({
                controlname: this.controlInstance.name,
                action: 'onloadsuccess',
                data: { action: this.loadAction, sender: this, navContext: this.context, navParam: viewparamResult, navData: this.navdatas, data: data },
            });
            this.onFormLoad(data, 'load');
            this.ctrlEvent({
                controlname: this.controlInstance.name,
                action: 'load',
                data: this.data,
            });
            this.$nextTick(() => {
                this.formState.next({ type: 'load', data: data });
            });
        })
            .catch(async (error) => {
            this.onControlResponse('load', error);
            let loaderrorResult = await this.executeCtrlEventLogic('onloaderror', {
                action: this.loadAction,
                sender: this,
                navContext: this.context,
                navParam: viewparamResult,
                navData: this.navdatas,
                data: error === null || error === void 0 ? void 0 : error.data,
            });
            if (loaderrorResult && (loaderrorResult === null || loaderrorResult === void 0 ? void 0 : loaderrorResult.hasOwnProperty('srfret')) && !loaderrorResult.srfret) {
                return;
            }
            this.ctrlEvent({
                controlname: this.controlInstance.name,
                action: 'onloaderror',
                data: { action: this.loadAction, sender: this, navContext: this.context, navParam: viewparamResult, navData: this.navdatas, data: error === null || error === void 0 ? void 0 : error.data },
            });
            this.$throw(error, 'load');
        });
    }
    /**
     * 加载草稿
     *
     * @param {*} [opt={}]
     * @memberof FormControlBase
     */
    loadDraft(opt = {}, mode) {
        if (!this.loaddraftAction) {
            this.$throw(this.$t('app.searchform.notconfig.loaddraftaction'), 'loadDraft');
            return;
        }
        const arg = Object.assign({}, opt);
        Object.assign(arg, { viewparams: this.viewparams });
        const tempContext = JSON.parse(JSON.stringify(this.context));
        this.onControlRequset('loadDraft', tempContext, arg);
        let post = this.service.loadDraft(this.loaddraftAction, tempContext, arg, this.showBusyIndicator);
        post
            .then((response) => {
            this.onControlResponse('loadDraft', response);
            if (!response.status || response.status !== 200) {
                this.$throw(response, 'loadDraft');
                return;
            }
            const data = response.data;
            this.resetDraftFormStates();
            this.onFormLoad(data, 'loadDraft');
            setTimeout(() => {
                const form = this.$refs[this.controlInstance.name];
                if (form) {
                    form.fields.forEach((field) => {
                        field.validateMessage = '';
                        field.validateState = '';
                        field.validateStatus = false;
                    });
                }
            });
            if (Object.is(mode, 'RESET')) {
                if (!this.formValidateStatus()) {
                    return;
                }
            }
            this.ctrlEvent({
                controlname: this.controlInstance.name,
                action: 'load',
                data: data,
            });
            this.$nextTick(() => {
                this.formState.next({ type: 'load', data: data });
            });
        })
            .catch((response) => {
            this.onControlResponse('loadDraft', response);
            this.$throw(response, 'loadDraft');
        });
    }
    /**
     * 表单项更新
     *
     * @param {string} mode 界面行为名称
     * @param {*} [data={}] 请求数据
     * @param {string[]} updateDetails 更新项
     * @param {boolean} [showloading] 是否显示加载状态
     * @returns {void}
     * @memberof FormControlBase
     */
    updateFormItems(mode, data = {}, updateDetails, showloading) { }
    /**
     * 回车事件
     *
     * @param {*} $event
     * @memberof FormControlBase
     */
    onEnter($event) { }
    /**
     * 搜索
     *
     * @memberof FormControlBase
     */
    onSearch() {
        if (!this.formValidateStatus()) {
            return;
        }
        this.ctrlEvent({
            controlname: this.controlInstance.name,
            action: 'search',
            data: this.data,
        });
    }
    /**
     * 重置
     *
     * @memberof FormControlBase
     */
    onReset() {
        this.loadDraft({}, 'RESET');
    }
    /**
     * 通过属性名获取表单项
     *
     * @memberof FormControlBase
     */
    findFormItemByField(fieldName) {
        const formItems = ModelTool.getAllFormItems(this.controlInstance);
        return formItems.find((formItem) => {
            var _a;
            return ((_a = formItem.getPSAppDEField()) === null || _a === void 0 ? void 0 : _a.name) == fieldName;
        });
    }
    /**
     * 处理部件UI请求
     *
     * @param {string} action 行为名称
     * @param {*} context 上下文
     * @param {*} viewparam 视图参数
     * @memberof FormControlBase
     */
    onControlRequset(action, context, viewparam) {
        if (!Object.is(action, 'updateFormItems')) {
            this.ctrlBeginLoading();
        }
    }
    /**
     * 处理部件UI响应
     *
     * @param {string} action 行为名称
     * @param {*} response 响应
     * @memberof FormControlBase
     */
    onControlResponse(action, response) {
        var _a;
        if (!Object.is(action, 'updateFormItems')) {
            this.ctrlEndLoading();
        }
        if (Object.is(action, 'load')) {
            this.isControlLoaded = true;
        }
        if (response && response.status && response.status == 403) {
            this.enableControlUIAuth = false;
            this.ctrlEvent({
                controlname: this.controlInstance.name,
                action: 'authlimit',
                data: response,
            });
        }
        if (response && response.status && response.status != 200 && response.data) {
            const data = response.data;
            if (data.code && Object.is(AppErrorCode.INPUTERROR, data.code) && ((_a = data.details) === null || _a === void 0 ? void 0 : _a.length) > 0) {
                let errorMsg = '';
                data.details.forEach((detail) => {
                    if (Object.is(EntityFieldErrorCode.ERROR_VALUERULE, detail.fielderrortype) && detail.fieldname) {
                        const tempFormItem = this.findFormItemByField(detail.fieldname);
                        if (tempFormItem) {
                            Object.assign(this.detailsModel[tempFormItem.name], { error: new String(detail.fielderrorinfo ? detail.fielderrorinfo : data.message) });
                        }
                        else {
                            errorMsg += `${detail.fieldlogicname}${detail.fielderrorinfo ? detail.fielderrorinfo : data.message}<br/>`;
                        }
                    }
                });
                response.data.message = errorMsg ? errorMsg : this.$t('app.searchform.globalerrortip');
                this.$forceUpdate();
            }
        }
    }
}
__decorate([
    Provide('formState')
], FormControlBase.prototype, "formState", void 0);
