import { Util } from '@ibizstudio/runtime';
import { MDControlBase } from './md-control-base';
import { AppViewLogicService } from '../app-service';
import { AppKanbanService } from '../ctrl-service';
/**
 * 看板视图部件基类
 *
 * @export
 * @class KanbanControlBase
 * @extends {MDControlBase}
 */
export class KanbanControlBase extends MDControlBase {
    constructor() {
        super(...arguments);
        /**
         * 看板数据
         *
         * @type {Array<any>}
         * @memberof KanbanControlBase
         */
        this.items = [];
        /**
         * 加载的数据是否附加在items之后
         *
         * @type {boolean}
         * @memberof KanbanControlBase
         */
        this.isAddBehind = false;
        /**
         * 代码表数据
         *
         * @type {Array<any>}
         * @memberof KanbanControlBase
         */
        this.allCodeList = [];
        /**
         * 是否分组
         *
         * @type {string}
         * @memberof KanbanControlBase
         */
        this.isGroup = true;
        /**
         * 分组集合
         *
         * @type {string}
         * @memberof KanbanControlBase
         */
        this.groups = [];
        /**
         * 分组属性名称
         *
         * @type {string}
         * @memberof KanbanControlBase
         */
        this.groupField = '';
        /**
         * 分组模式
         *
         * @type {string}
         * @memberof KanbanControlBase
         */
        this.groupMode = '';
        /**
         * this引用
         *
         * @type {number}
         * @memberof KanbanControlBase
         */
        this.thisRef = this;
    }
    /**
     * 部件模型数据初始化
     *
     * @param {*} [args]
     * @memberof KanbanControlBase
     */
    async ctrlModelInit(args) {
        var _a, _b, _c, _d, _e, _f, _g, _h;
        await super.ctrlModelInit();
        if (!(this.Environment && this.Environment.isPreviewMode)) {
            this.service = new AppKanbanService(this.controlInstance, this.context);
        }
        this.limit = ((_a = this.controlInstance) === null || _a === void 0 ? void 0 : _a.pagingSize) ? this.controlInstance.pagingSize : 20;
        this.minorSortPSDEF = ((_c = (_b = this.controlInstance.getMinorSortPSAppDEField()) === null || _b === void 0 ? void 0 : _b.codeName) === null || _c === void 0 ? void 0 : _c.toLowerCase()) || '';
        this.minorSortDir = this.controlInstance.minorSortDir;
        this.groupField = ((_e = (_d = this.controlInstance.getGroupPSAppDEField()) === null || _d === void 0 ? void 0 : _d.codeName) === null || _e === void 0 ? void 0 : _e.toLowerCase()) || "";
        this.isGroup = (_f = this.controlInstance) === null || _f === void 0 ? void 0 : _f.enableGroup;
        this.groupMode = (_g = this.controlInstance) === null || _g === void 0 ? void 0 : _g.groupMode;
        this.updateGroupAction = (_h = this.controlInstance.getUpdateGroupPSControlAction()) === null || _h === void 0 ? void 0 : _h.actionName;
        const codeList = this.controlInstance.getGroupPSCodeList();
        await (codeList === null || codeList === void 0 ? void 0 : codeList.fill());
        this.groupCodeList = codeList ? { type: codeList.codeListType, tag: codeList.codeName, data: codeList } : {};
    }
    /**
     * 部件事件
     *
     * @param {string} controlname
     * @param {string} action
     * @param {*} data
     * @memberof KanbanControlBase
     */
    onCtrlEvent(controlname, action, data) {
        if (action == 'panelDataChange') {
            this.onPanelDataChange(data.item, data.data);
        }
        else {
            super.onCtrlEvent(controlname, action, data);
        }
    }
    /**
     * 计算项布局面板部件所需参数
     *
     * @param {*} controlInstance
     * @param {*} item
     * @returns
     * @memberof KanbanControlBase
     */
    computeTargetCtrlData(controlInstance, item) {
        const { targetCtrlName, targetCtrlParam, targetCtrlEvent } = super.computeTargetCtrlData(controlInstance);
        Object.assign(targetCtrlParam.dynamicProps, {
            navdatas: [item],
            actionModel: this.actionModel,
        });
        Object.assign(targetCtrlParam.staticProps, {
            transformData: this.transformData,
            opendata: this.opendata,
            newdata: this.newdata,
            remove: this.remove,
            refresh: this.refresh,
        });
        targetCtrlEvent['ctrl-event'] = ({ controlname, action, data }) => {
            this.onCtrlEvent(controlname, action, { item: item, data: data });
        };
        return { targetCtrlName, targetCtrlParam, targetCtrlEvent };
    }
    /**
     * 执行mounted后的逻辑
     *
     *  @memberof KanbanControlBase
     */
    ctrlMounted() {
        super.ctrlMounted();
        if (!this.isEnablePagingBar) {
            this.$el.addEventListener('scroll', () => {
                if (this.$el.scrollTop + this.$el.clientHeight >= this.$el.scrollHeight) {
                    this.loadMore();
                }
            });
        }
    }
    /**
     * 初始化看板部件
     *
     * @memberof KanbanControlBase
     */
    ctrlInit() {
        super.ctrlInit();
        // 绑定this
        this.transformData = this.transformData.bind(this);
        this.remove = this.remove.bind(this);
        this.refresh = this.refresh.bind(this);
    }
    viewStateAction(tag, action, data) {
        if (!Object.is(tag, this.name)) {
            return;
        }
        super.viewStateAction(tag, action, data);
        if (Object.is(action, 'load')) {
            this.refresh(data);
        }
        if (Object.is(action, 'filter')) {
            this.refresh(data);
        }
    }
    /**
     * 看板数据加载
     *
     * @param {*} [opt={}] 额外参数
     * @param {boolean} [isReset=false] 是否重置items
     * @return {*}
     * @memberof KanbanControlBase
     */
    async load(opt = {}, isReset = false) {
        if (!this.fetchAction) {
            this.$throw(this.$t('app.kanban.notconfig.fetchaction'), 'load');
            return;
        }
        const arg = Object.assign({}, opt);
        const page = {};
        if (this.isEnablePagingBar) {
            Object.assign(page, { page: this.curPage - 1, size: this.limit });
        }
        // 设置排序
        if (!Object.is(this.minorSortDir, '') && !Object.is(this.minorSortPSDEF, '')) {
            const sort = this.minorSortPSDEF + "," + this.minorSortDir;
            Object.assign(page, { sort: sort });
        }
        Object.assign(arg, page);
        const parentdata = {};
        this.$emit("ctrl-event", { controlname: "kanban", action: "beforeload", data: parentdata });
        Object.assign(arg, parentdata);
        let tempViewParams = parentdata.viewparams ? parentdata.viewparams : {};
        Object.assign(tempViewParams, Util.deepCopy(this.viewparams));
        Object.assign(arg, { viewparams: tempViewParams });
        let tempContext = Util.deepCopy(this.context);
        this.onControlRequset('load', tempContext, arg);
        const post = this.service.search(this.fetchAction, tempContext, arg, this.showBusyIndicator);
        post.then((response) => {
            this.onControlResponse('load', response);
            if (!response || response.status !== 200) {
                this.$throw(response, 'load');
                return;
            }
            const data = response.data;
            if (!this.isAddBehind) {
                this.items = [];
            }
            if (Object.keys(data).length > 0) {
                let datas = Util.deepCopy(data);
                datas.map((item) => {
                    if (!item.srfchecked) {
                        Object.assign(item, { srfchecked: 0 });
                    }
                });
                this.totalRecord = response.total;
                if (isReset) {
                    this.items = datas;
                }
                else {
                    this.items.push(...datas);
                }
            }
            this.isAddBehind = false;
            this.setGroups();
            this.$emit("ctrl-event", { controlname: "kanban", action: "load", data: this.items });
            if (this.isSelectFirstDefault) {
                this.handleClick(this.items[0]);
            }
        }, (response) => {
            this.onControlResponse('load', response);
            this.$throw(response, 'load');
        });
    }
    /**
     * 加载更多
     *
     * @memberof KanbanControlBase
     */
    loadMore() {
        if (this.totalRecord > this.items.length) {
            this.curPage = ++this.curPage;
            this.isAddBehind = true;
            this.load({});
        }
    }
    /**
     * 刷新
     *
     * @param {*} [opt={}] 额外参数
     * @memberof KanbanControlBase
     */
    refresh(args) {
        this.curPage = 1;
        this.load(args, true);
    }
    /**
     * 删除
     *
     * @param {any[]} datas 删除数据
     * @returns {Promise<any>}
     * @memberof KanbanControlBase
     */
    async remove(datas) {
        if (!this.removeAction) {
            this.$throw(`${this.controlInstance.codeName}` + this.$t('app.kanban.notconfig.removeaction'), 'remove');
            return;
        }
        let _datas = [];
        datas.forEach((record, index) => {
            if (Object.is(record.srfuf, '0')) {
                this.items.some((val, num) => {
                    if (JSON.stringify(val) == JSON.stringify(record)) {
                        this.items.splice(num, 1);
                        return true;
                    }
                });
            }
            else {
                _datas.push(datas[index]);
            }
        });
        if (_datas.length === 0) {
            return;
        }
        let dataInfo = '';
        _datas.forEach((record, index) => {
            let srfmajortext = record.srfmajortext;
            if (index < 5) {
                if (!Object.is(dataInfo, '')) {
                    dataInfo += '、';
                }
                dataInfo += srfmajortext;
            }
            else {
                return false;
            }
        });
        if (_datas.length < 5) {
            dataInfo = dataInfo + this.$t('app.dataview.sum') + _datas.length + this.$t('app.dataview.data');
        }
        else {
            dataInfo = dataInfo + '...' + this.$t('app.dataview.sum') + _datas.length + this.$t('app.dataview.data');
        }
        const removeData = () => {
            var _a, _b, _c;
            let keys = [];
            _datas.forEach((data) => {
                keys.push(data.srfkey);
            });
            let _removeAction = keys.length > 1 ? 'removeBatch' : this.removeAction;
            let tempContext = Util.deepCopy(this.context);
            Object.assign(tempContext, { [(_c = (_b = (_a = this.controlInstance) === null || _a === void 0 ? void 0 : _a.getPSAppDataEntity) === null || _b === void 0 ? void 0 : _b.codeName) === null || _c === void 0 ? void 0 : _c.toLowerCase()]: keys.join(';') });
            let arg = { [this.controlInstance.getPSAppDataEntity.codeName.toLowerCase()]: keys.join(';') };
            Object.assign(arg, { viewparams: this.viewparams });
            this.onControlRequset('remove', tempContext, arg);
            const post = this.service.delete(_removeAction, tempContext, arg, this.showBusyIndicator);
            return new Promise((resolve, reject) => {
                post.then((response) => {
                    this.onControlResponse('remove', response);
                    if (!response || response.status !== 200) {
                        this.$throw(this.$t('app.commonwords.deldatafail') + ',' + response.info, 'remove');
                        return;
                    }
                    else {
                        this.$success(this.$t('app.commonwords.deletesuccess'), 'remove');
                    }
                    //删除items中已删除的项
                    _datas.forEach((data) => {
                        this.items.some((item, index) => {
                            if (Object.is(item.srfkey, data.srfkey)) {
                                this.items.splice(index, 1);
                                return true;
                            }
                        });
                    });
                    this.$emit("ctrl-event", { controlname: "kanban", action: "remove", data: null });
                    this.selections = [];
                    resolve(response);
                }).catch((response) => {
                    this.onControlResponse('remove', response);
                    this.$throw(response, 'remove');
                    reject(response);
                });
            });
        };
        dataInfo = dataInfo.replace(/[null]/g, '').replace(/[undefined]/g, '').replace(/[ ]/g, '');
        this.$Modal.confirm({
            title: this.$t('app.commonwords.warning'),
            content: this.$t('app.kanban.delete1') + dataInfo + '，' + this.$t('app.kanban.delete2'),
            onOk: () => {
                removeData();
            },
            onCancel: () => { }
        });
        return removeData;
    }
    /**
     * 界面行为
     *
     * @param {*} detail 界面行为
     * @param {*} $event 事件源
     * @param {*} group 看板分组
     * @memberof KanbanControlBase
     */
    uiActionClick(detail, $event, group) {
        var _a;
        let row = this.selections.length > 0 && group.items.includes(this.selections[0]) ? this.selections[0] : {};
        if (!row.hasOwnProperty('srfgroup')) {
            Object.assign(row, { srfgroup: group.value });
        }
        AppViewLogicService.getInstance().executeViewLogic(this.getViewLogicTag(this.controlInstance.name, 'group', detail.name), $event, this, row, (_a = this.controlInstance) === null || _a === void 0 ? void 0 : _a.getPSAppViewLogics());
    }
    /**
     * 面板数据变化处理事件
     * @param {any} item 当前列数据
     * @param {any} $event 面板事件数据
     *
     * @memberof KanbanControlBase
     */
    onPanelDataChange(item, $event) {
        Object.assign(item, $event, { rowDataState: 'update' });
    }
    /**
     * 拖拽结束
     *
     */
    onDragEnd() {
        this.$forceUpdate();
    }
    /**
     * 拖拽变化
     *
     * @param {*} evt 拖住对象
     * @param {*} name 分组名
     * @memberof KanbanControlBase
     */
    async onDragChange(evt, name) {
        var _a, _b;
        if ((_a = evt === null || evt === void 0 ? void 0 : evt.added) === null || _a === void 0 ? void 0 : _a.element) {
            let item = Util.deepCopy(evt.added.element);
            let updateView = await this.getUpdateView(name);
            if (updateView) {
                let view = {
                    viewname: 'app-view-shell',
                    height: updateView.height,
                    width: updateView.width,
                    title: this.$tl((_b = updateView.getCapPSLanguageRes()) === null || _b === void 0 ? void 0 : _b.lanResTag, updateView.caption),
                };
                const _context = Util.deepCopy(this.context);
                const _param = Util.deepCopy(this.viewparams);
                Object.assign(_context, { [this.appDeCodeName.toLowerCase()]: item.srfkey });
                if (updateView && updateView.modelPath) {
                    Object.assign(_context, { viewpath: updateView.modelPath });
                }
                let container;
                if (updateView.openMode && !Object.is(updateView.openMode, '') && updateView.openMode.indexOf('DRAWER') !== -1) {
                    if (Object.is(updateView.openMode, 'DRAWER_TOP')) {
                        Object.assign(view, { isfullscreen: true });
                        container = this.$appdrawer.openTopDrawer(view, Util.getViewProps(_context, _param));
                    }
                    else {
                        Object.assign(view, { placement: updateView.openMode });
                        container = this.$appdrawer.openDrawer(view, Util.getViewProps(_context, _param));
                    }
                }
                else {
                    container = this.$appmodal.openModal(view, _context, _param);
                }
                container.subscribe((result) => {
                    if (!result || !Object.is(result.ret, 'OK')) {
                        this.setGroups();
                        return;
                    }
                    this.refresh();
                });
            }
            else {
                this.updateData(item, name);
            }
        }
    }
    /**
     * 修改分组集合
     *
     * @param {*} opt 数据
     * @param {*} newVal 新分组值
     * @memberof KanbanControlBase
     */
    updateData(opt, newVal) {
        var _a, _b, _c;
        const oldVal = opt[this.groupField];
        if (newVal) {
            opt[this.groupField] = newVal;
        }
        const arg = Object.assign({}, opt);
        Object.assign(arg, { viewparams: this.viewparams });
        let tempContext = Util.deepCopy(this.context);
        if ((_a = this.controlInstance.getPSAppDataEntity()) === null || _a === void 0 ? void 0 : _a.codeName) {
            Object.assign(tempContext, { [(_c = (_b = this.controlInstance.getPSAppDataEntity()) === null || _b === void 0 ? void 0 : _b.codeName) === null || _c === void 0 ? void 0 : _c.toLowerCase()]: opt.srfkey });
        }
        this.onControlRequset('updateData', tempContext, arg);
        const post = this.service.update(this.updateGroupAction, tempContext, arg, this.showBusyIndicator);
        post.then((response) => {
            this.onControlResponse('updateData', response);
            if (!response.status || response.status !== 200) {
                this.$throw(response, 'updateData');
                opt[this.groupField] = oldVal;
                this.setGroups();
                return;
            }
            let item = this.items.find((item) => Object.is(item.srfkey, response.data.srfkey));
            Object.assign(item, response.data);
            this.setGroups();
            this.$emit("ctrl-event", { controlname: "kanban", action: "update", data: this.items });
        }).catch((response) => {
            this.onControlResponse('updateData', response);
            opt[this.groupField] = oldVal;
            this.setGroups();
            this.$throw(response, 'updateData');
        });
    }
    /**
     * 单击事件
     *
     * @param {*} args 数据
     * @memberof KanbanControlBase
     */
    handleClick(args) {
        if (this.mDCtrlActiveMode === 1) {
            this.ctrlEvent({ controlname: this.name, action: 'rowclick', data: args });
            return;
        }
        args.srfchecked = Number(!args.srfchecked);
        this.items.forEach((item) => {
            if (item.srfkey !== args.srfkey) {
                item.srfchecked = 0;
            }
        });
        this.selectchange();
    }
    /**
     * 双击事件
     *
     * @param {*} args 数据
     * @memberof KanbanControlBase
     */
    handleDblClick(args) {
        if (this.mDCtrlActiveMode !== 0) {
            args.srfchecked = 1;
            this.items.forEach((item) => {
                if (item.srfkey !== args.srfkey) {
                    item.srfchecked = 0;
                }
            });
            this.$emit("ctrl-event", { controlname: "kanban", action: "rowdblclick", data: args });
        }
    }
    /**
     * 触发事件
     * @memberof KanbanControlBase
     *
     */
    selectchange() {
        this.selections = [];
        this.items.map((item) => {
            if (item.srfchecked === 1) {
                this.selections.push(item);
            }
        });
        this.$emit("ctrl-event", { controlname: "kanban", action: "selectionchange", data: this.selections });
    }
    /**
     * 点击时触发看板的展开和收起
     *
     * @param group 分组看板
     * @param index 分组看板编号
     * @memberof KanbanControlBase
     */
    onClick(group, index) {
        group.folding = !group.folding;
        this.$forceUpdate();
    }
    /**
     * 设置分组集合
     *
     * @memberof KanbanControlBase
     */
    async setGroups() {
        let tempGroups = this.groups;
        if (!this.isGroup || !this.groupField || Object.is(this.groupMode, 'NONE')) {
            return;
        }
        if (Object.is(this.groupMode, 'AUTO')) {
            this.groups = [];
            this.items.forEach(item => {
                let group = this.groups.find((group) => Object.is(group.name, item[this.groupField]));
                let state = tempGroups.filter((temp) => Object.is(item[this.groupField], temp.value))[0];
                if (!group) {
                    this.groups.push({
                        name: item[this.groupField],
                        value: item[this.groupField],
                        folding: (state && !state.folding) ? state.folding : true,
                        items: this.getGroupItems(item[this.groupField])
                    });
                }
            });
        }
        if (Object.is(this.groupMode, 'CODELIST') && this.groupCodeList) {
            this.groups = [];
            let codelistItems = await this.codeListService.getDataItems(Object.assign(Object.assign({}, this.groupCodeList), { context: this.context }));
            this.allCodeList = Util.deepCopy(codelistItems);
            if (codelistItems && codelistItems.length > 0) {
                codelistItems.forEach((item) => {
                    let state = tempGroups.filter((temp) => Object.is(item.value, temp.value))[0];
                    this.groups.push({
                        name: item.value,
                        value: item.value,
                        color: item.color,
                        folding: (state && !state.folding) ? state.folding : true,
                        items: this.getGroupItems(item.value)
                    });
                });
            }
        }
    }
    /**
     * 拖拽更新页面
     *
     * @param {string} group 分组名称
     * @memberof KanbanControlBase
     */
    async getUpdateView(group) {
        var _a;
        if (!group)
            return null;
        let parentModel = this.controlInstance.parentModel;
        if (parentModel.getPSAppViewRefs() && parentModel.getPSAppViewRefs().length > 0) {
            let activeAppViewRef = (_a = parentModel.getPSAppViewRefs()) === null || _a === void 0 ? void 0 : _a.find((item) => {
                return item.name === `EDITDATA:${group.toUpperCase()}`;
            });
            if (!activeAppViewRef || !activeAppViewRef.getRefPSAppView())
                return null;
            const openView = activeAppViewRef.getRefPSAppView();
            await openView.fill();
            return openView;
        }
        else {
            return null;
        }
    }
    /**
     * 获取对应分组的数据集合
     *
     * @param {string} name 分组值
     * @memberof KanbanControlBase
     */
    getGroupItems(name) {
        let datas = [];
        this.items.forEach(item => {
            if (Object.is(item[this.groupField], name)) {
                datas.push(item);
            }
        });
        return datas;
    }
    /**
     * 获取分组的text
     *
     * @param {string} name 分组值
     * @memberof KanbanControlBase
     */
    getGroupText(name) {
        if (Object.is(this.groupMode, 'CODELIST') && this.groupCodeList) {
            if (this.allCodeList && this.allCodeList.length > 0) {
                if (!name) {
                    return this.$t('app.chart.undefined');
                }
                let item = this.allCodeList.find((item) => Object.is(item.value, name));
                if (item) {
                    return item.text;
                }
            }
        }
        else {
            return name;
        }
    }
}
