import { GetModelService, Util } from '@ibizstudio-ex/runtime';
import { acc } from '@ibizstudio/api';
import { generateOrderValue } from 'qx-util';
import { LayoutUtil } from '../../utils';
import { DesignItemBase } from '../design-item/design-item-base';
import { message, Modal } from 'ant-design-vue';
import './drag-design-item-base.less';
/**
 * 表单设计项基类
 *
 * @export
 * @class DragDesignItemBase
 * @extends {DesignItemBase<T>}
 * @template T
 */
export class DragDesignItemBase extends DesignItemBase {
    constructor() {
        super(...arguments);
        /**
         * 布局工具
         *
         * @memberof DragDesignItemBase
         */
        this.layoutUtil = LayoutUtil.getInstance();
        /**
         * 是否为flex布局
         *
         * @memberof DragDesignItemBase
         */
        this.isFlexStyle = false;
        /**
         * 应用消息订阅
         *
         * @type {string[]}
         * @memberof DragDesignItemBase
         */
        this.accSubs = [];
        /**
         * 视图部件服务
         */
        this.viewCtrlService = '';
        /**
         * 视图部件数据
         */
        this.viewCtrlData = [];
        /**
         * 部件控件删除模式
         */
        this.ctrlPosDeleteMode = '';
    }
    /**
     * 监听素材项双击
     *
     * @author zhanghengfeng
     * @date 2023-05-18 14:05:13
     * @param {IMaterialItem} [item]
     */
    onItemDblClick(item) {
        var _a;
        if (this.active && item && item.data && this.data && Array.isArray(this.list)) {
            const type = this.data.detailtype;
            if (type) {
                if (DragDesignItemBase.containerType.includes(type)) {
                    this.list.push(item.data);
                    this.add({
                        element: item.data,
                        newIndex: this.list.length - 1,
                    });
                }
                else if (DragDesignItemBase.childType.includes(type)) {
                    (_a = this.ctx.ctrl.itemEvt) === null || _a === void 0 ? void 0 : _a.emit('child-item-dblclick', {
                        item,
                        child: this.data,
                    });
                }
            }
        }
    }
    /**
     * 监听子项触发的素材项双击
     *
     * @author zhanghengfeng
     * @date 2023-05-18 14:05:36
     * @param {{ item: IMaterialItem; child: IPSDEFormDetailPreview }} [args]
     */
    onChildItemDblClick(args) {
        if (args) {
            const { item, child } = args;
            if (item && item.data && child && this.data && Array.isArray(this.list)) {
                const id = this.data.psdeformdetailid;
                const parentId = child.ppsdeformdetailid;
                const childId = child.psdeformdetailid;
                if (id && parentId && childId && id === parentId) {
                    const index = this.list.findIndex(data => {
                        const dataId = data.psdeformdetailid;
                        return dataId && dataId === childId;
                    });
                    if (index !== -1) {
                        this.list.splice(index + 1, 0, item.data);
                        this.add({
                            element: item.data,
                            newIndex: index + 1,
                        });
                    }
                }
            }
        }
    }
    async componentCreated() {
        var _a;
        if (this.data && this.data.itemtype && Object.is(this.data.itemtype, 'CTRLPOS')) {
            this.viewCtrlService = await ___ibz___.gs.getPSDEViewCtrlService();
            this.loadViewCtrl();
        }
        this.subAcc();
        this.deletePanel = this.deletePanel.bind(this);
        const event = this.ctrl.evt;
        if (event) {
            event.on('removePanel', this.deletePanel);
        }
        this.modelService = await GetModelService(this.ctx.context);
        if (this.ctx.ctrl.itemEvt) {
            this.onItemDblClick = this.onItemDblClick.bind(this);
            this.ctx.ctrl.itemEvt.on('item-dblclick', this.onItemDblClick);
            const type = (_a = this.data) === null || _a === void 0 ? void 0 : _a.detailtype;
            if (type && DragDesignItemBase.containerType.includes(type)) {
                this.onChildItemDblClick = this.onChildItemDblClick.bind(this);
                this.ctx.ctrl.itemEvt.on('child-item-dblclick', this.onChildItemDblClick);
            }
        }
    }
    async componentMounted() {
        this.service = this.ctx.ctrl.itemService;
        if (this.ctx.ctrl.previewService) {
            this.previewService = this.ctx.ctrl.previewService;
        }
        else {
            this.previewService = this.ctx.ctrl.itemService;
        }
        this.load();
    }
    componentDestroyed() {
        this.accSubs.forEach(str => acc.unsubscribeLocal(str));
        const event = this.ctrl.evt;
        if (event) {
            event.off('removePanel', this.deletePanel);
        }
        if (this.ctx.ctrl.itemEvt) {
            this.ctx.ctrl.itemEvt.off('item-dblclick', this.onItemDblClick);
            this.ctx.ctrl.itemEvt.off('child-item-dblclick', this.onChildItemDblClick);
        }
    }
    /**
     * 订阅应用中心消息
     *
     * @memberof DragDesignItemBase
     */
    subAcc() {
        var _a, _b;
        const entityName = (_b = (_a = this.ctx.ctrl.itemEntity) === null || _a === void 0 ? void 0 : _a.codeName) === null || _b === void 0 ? void 0 : _b.toUpperCase();
        this.accSubs.push(acc.commandLocal((data) => {
            if (!this.isAcc) {
                return;
            }
            this.accCreated(data);
        }, 'create', entityName));
        this.accSubs.push(acc.commandLocal((data) => {
            if (!this.isAcc) {
                return;
            }
            this.accRemove(data);
        }, 'remove', entityName));
        this.accSubs.push(acc.commandLocal((data) => {
            if (!this.isAcc) {
                return;
            }
            this.accUpdate(data);
        }, 'update', entityName));
        if (this.viewCtrlService) {
            this.accSubs.push(...acc.commandLocals((data) => {
                if (Object.is(this.context.psdeviewbase, data.psdeviewbaseid)) {
                    this.loadViewCtrl();
                }
            }, ['create', 'remove'], this.viewCtrlService.APPDENAME.toUpperCase()));
        }
    }
    accCreated(data) {
        var _a;
        if (((_a = this.data) === null || _a === void 0 ? void 0 : _a.srfkey) === data.srfpkey || !data.srfpkey) {
            this.load();
        }
    }
    accRemove(data) {
        var _a;
        if (((_a = this.data) === null || _a === void 0 ? void 0 : _a.srfkey) === data.srfpkey || !data.srfpkey) {
            this.load();
        }
    }
    accUpdate(data) {
        var _a, _b;
        if (((_a = this.data) === null || _a === void 0 ? void 0 : _a.srfkey) === data.srfkey && this.data.srftempdate !== data.srftempdate) {
            this.reloadData();
        }
        else if (((_b = this.data) === null || _b === void 0 ? void 0 : _b.srfkey) === data.srfpkey) {
            this.load();
        }
    }
    /**
     * 加载数据
     *
     * @author chitanda
     * @date 2021-04-15 10:04:34
     * @return {*}  {Promise<any>}
     */
    async load() { }
    /**
     * 加载视图部件数据
     *
     * @memberof CollapseList
     */
    async loadViewCtrl() {
        const res = await this.viewCtrlService.FetchDefault(this.ctx.context);
        if (res && res.data.length > 0) {
            this.viewCtrlData = res.data;
        }
    }
    /**
     * 删除项
     *
     * @param {string} srfKey
     * @return {*}  {Promise<any>}
     * @memberof DragDesignItemBase
     */
    async remove(srfKey) {
        const tab = this.list.find((item) => {
            return item.srfkey === srfKey;
        });
        const res = await this.service.RemoveTemp(this.ctx.context, tab);
        if (res.ok === false) {
            message.error(res.statusText || '');
            return res;
        }
        return res;
    }
    /**
     * 新增表单项
     *
     * @param {any} entity
     * @return {*}  {(Promise<any>)}
     * @memberof DragDesignItemBase
     */
    async create(entity) {
        const res = await this.service.CreateTemp(this.ctx.context, entity);
        if (res.ok) {
            this.setSelect(res.data);
            return res.data;
        }
    }
    /**
     * 更新表单项
     *
     * @param {any} entity
     * @return {*}  {(Promise<any>)}
     * @memberof DragDesignItemBase
     */
    update(entity) {
        return this.service.UpdateTemp(this.ctx.context, entity);
    }
    /**
     * 获取表单项
     *
     * @param {string} srfkey
     * @return {*}  {(Promise<any>)}
     * @memberof DragDesignItemBase
     */
    get(srfkey) {
        return this.previewService.getLocal(this.ctx.context, srfkey);
    }
    /**
     * @description 获取内容样式
     * @param {*} data
     * @return {*}
     * @memberof DragDesignItemBase
     */
    getContentStyle(data) {
        if (data && data.rawcssstyle) {
            const res = data.rawcssstyle.split('\n');
            const target = [];
            for (let i = 0; i < res.length; i++) {
                target.push(...res[i].split(';').filter((value) => value));
            }
            return target
                .filter((value) => {
                return value.split(':').length === 2;
            })
                .join(';');
        }
    }
    /**
     * 获取默认值
     *
     * @param {any} data
     * @return {*}  {(Promise<any>)}
     * @memberof DragDesignItemBase
     */
    async getDraft(data) {
        var _a, _b, _c;
        const res = await this.service.GetDraftTemp(Object.assign(Object.assign({}, this.ctx.context), { [(_b = (_a = this.ctx.ctrl.itemEntity) === null || _a === void 0 ? void 0 : _a.codeName) === null || _b === void 0 ? void 0 : _b.toLowerCase()]: (_c = this.data) === null || _c === void 0 ? void 0 : _c.srfkey }), data);
        if (res.ok && res.data) {
            return res.data;
        }
        return {};
    }
    /**
     * 重新加载当前数据
     *
     * @memberof DragDesignItemBase
     */
    async reloadData() {
        const data = await this.get(this.data.srfkey);
        if (data) {
            this.data._reset(data);
            this.$forceUpdate();
        }
    }
    /**
     * 新增子项
     *
     * @param {{ element: any; newIndex: number }} opt
     * @memberof DragDesignItemBase
     */
    async add(opt) {
        var _a;
        const { element, newIndex } = opt;
        await this.updateOrderValue(newIndex + 1);
        this.list.splice(newIndex, 1);
        let data = await this.get(element.srfkey);
        if (data == null) {
            data = await this.getDraft(element);
            data.ordervalue = generateOrderValue(newIndex);
            data.srfordervalue = data.ordervalue;
            data.formtype = this.ctx.context.formtype;
            await this.create(data);
        }
        else {
            data.ordervalue = generateOrderValue(newIndex);
            data.srfordervalue = data.ordervalue;
            if (!this.data || this.data.itemtype == 'PSSysViewPanel') {
                data.srfpkey = null;
                data.srfpmajortext = null;
            }
            else {
                data.srfpkey = this.data.srfkey;
                data.srfpmajortext = this.data.srfmajortext;
            }
            await this.update(data);
            if (!this.data || this.data.itemtype == 'PSSysViewPanel') {
                const panelCtrl = ((_a = this.ctrl.ctx) === null || _a === void 0 ? void 0 : _a.panelCtrl) || this.ctrl;
                if (panelCtrl.evt) {
                    panelCtrl.evt.emit('refreshPanel');
                }
            }
        }
    }
    /**
     * 激活数据点击
     *
     * @param {MouseEvent} event
     * @param {any} data
     * @memberof DragDesignItemBase
     */
    onActiveClick(event, data) {
        if (event) {
            event.stopPropagation();
        }
        this.setSelect(data);
    }
    /**
     * 计算当前布局是否为Flex
     *
     * @param {*} node
     * @memberof DragDesignItemBase
     */
    calcLayoutMode() {
        if (this.parentData && Object.is(this.parentData.layoutmode, 'FLEX')) {
            this.isFlexStyle = true;
        }
        else {
            this.isFlexStyle = false;
        }
    }
    /**
     * 计算当前项样式
     *
     * @memberof DragDesignItemBase
     */
    calcStyle() {
        this.calcLayoutMode();
        this.style = this.layoutUtil.formatStyle(this.data, this.parentData, this.isFlexStyle);
    }
    /**
     * 计算栅格布局样式
     *
     * @param {*} item
     * @returns {*}
     * @memberof DragDesignItemBase
     */
    calcColClass(item) {
        return this.layoutUtil.calcColClass(item, this.parentData, this.isFlexStyle);
    }
    /**
     * 绘制其他内容
     *
     * @returns {*}
     * @memberof DragDesignItemBase
     */
    renderOther() {
        return [this.renderHandle(), this.renderActions()];
    }
    /**
     * 绘制拖拽节点
     *
     * @returns {*}
     * @memberof DragDesignItemBase
     */
    renderHandle() {
        // 视图设计中表单预览不允许移动编辑
        if (!this.ctx.ctrl.isViewDesign) {
            return (<div class='drag-handle'>
          <a-icon type='drag'/>
        </div>);
        }
    }
    /**
     * 绘制行为
     *
     * @returns {*}
     * @memberof DragDesignItemBase
     */
    renderActions() {
        return (<div class='drag-item-actions'>
        <ul>{this.renderActionItems()}</ul>
      </div>);
    }
    /**
     * 删除当前数据
     *
     * @param {MouseEvent} e
     * @return {*}  {Promise<void>}
     * @memberof DragDesignItemBase
     */
    async deleteHandle(e) {
        e.stopPropagation();
        if (Object.is(this.data.itemtype, 'CTRLPOS')) {
            this.deletePromptMessage(e);
            return;
        }
        this.removeDesingItem(e);
    }
    /**
     * 删除占位控件
     * @param {MouseEvent} e
     *
     */
    async removeDesingItem(e) {
        var _a;
        if ((_a = this.ctrl) === null || _a === void 0 ? void 0 : _a.isDefaultLayout) {
            this.userOperationTips(e);
        }
        else {
            const res = await this.service.RemoveTemp(this.ctx.context, this.data);
            if (res.ok === false) {
                message.error(res.statusText || '');
                return;
            }
            this.setSelect(this.parentData);
        }
    }
    /**
     * @description 删除当前面板
     * @param {*} data
     * @memberof DragDesignItemBase
     */
    async deletePanel(data) {
        if (this.data.srfpkey && Object.is(this.data.srfpkey, data.srfkey)) {
            const res = await this.service.RemoveTemp(this.ctx.context, this.data);
            if (res.ok === false) {
                message.error(res.statusText || '');
                return;
            }
        }
    }
    /**
     * 拷贝当前表单项数据
     *
     * @param {MouseEvent} e
     * @return {*}  {Promise<void>}
     * @memberof DragDesignItemBase
     */
    async copyHandle(e) {
        e.stopPropagation();
        const res = await this.service.DeepCopy(this.ctx.context, this.data);
        if (res.ok) {
            console.log(res);
        }
    }
    /**
     * @description 保存为自定义部件
     * @param {MouseEvent} e
     * @return {*}  {Promise<void>}
     * @memberof DragDesignItemBase
     */
    async saveHandle(e) {
        e.stopPropagation();
        //todo 待补充
    }
    /**
     * @description 编辑部件
     * @param {MouseEvent} e
     * @return {*}  {Promise<void>}
     * @memberof DragDesignItemBase
     */
    async editorHandle(event) {
        var _a;
        event.stopPropagation();
        if (!Object.is(this.data.itemtype, 'CTRLPOS')) {
            return;
        }
        const evt = this.ctrl.evt;
        const curCtrl = this.getActiveCtrl();
        if (curCtrl && evt) {
            Object.assign(curCtrl, { linktype: curCtrl.psdeviewctrltype });
            evt.emit('itemClick', { tag: 'redirectctrldesign', param: curCtrl });
        }
        else {
            const ctrlCtrl = (_a = this.ctrl.ctx.ctrl) === null || _a === void 0 ? void 0 : _a.ctrlCtrl;
            if (ctrlCtrl && evt && ctrlCtrl.deUIActionItems.length > 0) {
                evt.emit('addCtrl', {
                    event,
                    item: ctrlCtrl.deUIActionItems[0],
                    callback: (_data) => {
                        var _a;
                        if (_data.codename) {
                            const result = {
                                caption: _data.psctrlname,
                                psdeviewctrltype: _data.psctrltypename,
                                pssysviewpanelitemname: _data.codename,
                                [`psde${(_a = _data.psctrltypename) === null || _a === void 0 ? void 0 : _a.toLowerCase()}id`]: _data.psctrlid,
                                srfkey: this.data.srfkey,
                            };
                            const data = Object.assign(Util.deepCopy(this.data), result);
                            this.update(data);
                        }
                    },
                });
            }
        }
    }
    /**
     * @description 获取激活部件
     * @return {*}
     * @memberof DragDesignItemBase
     */
    getActiveCtrl() {
        const data = this.ctrl.ctx.ctrl.select.data;
        if (data) {
            return Object.is(data.psdeviewctrlname, this.data.pssysviewpanelitemname) ? data : null;
        }
    }
    /**
     * 绘制删除占位提示信息
     * @param {MouseEvent} e
     */
    deletePromptMessage(e) {
        this.ctrlPosDeleteMode = '';
        const modal = Modal.confirm({
            class: 'delete-prompt-message-main',
            mask: true,
            centered: true,
            icon: 'info-circle',
            width: 400,
            cancelText: '取消',
            okText: '确定',
            title: '请确认是否删除控件占位元素',
            okButtonProps: {
                props: {
                    disabled: !this.ctrlPosDeleteMode,
                },
            },
            content: () => {
                return (<div>
            <a-radio-group v-model={this.ctrlPosDeleteMode}>
              <a-radio value='synchroDeleteViewCtrl' onClick={() => deletePlaceholderPro('synchroDeleteViewCtrl')}>
                是，同步删除已加入视图部件
              </a-radio>
              <a-radio value='onlyDeletePlaceholder' onClick={() => deletePlaceholderPro('onlyDeletePlaceholder')}>
                是，仅删除控件占位元素
              </a-radio>
            </a-radio-group>
          </div>);
            },
            onOk: async () => {
                if (Object.is(this.ctrlPosDeleteMode, 'synchroDeleteViewCtrl')) {
                    // 筛选删除部件数据
                    await this.viewCtrlData.find((item) => {
                        return Object.is(item.psdeviewctrlname.toUpperCase(), this.data.pssysviewpanelitemname.toUpperCase());
                    });
                    const res = await this.viewCtrlService.RemoveTemp(this.ctx.context, this.data);
                    if (res.ok === false) {
                        message.error(res.statusText || '');
                        return;
                    }
                }
                await this.removeDesingItem(e);
            },
            onCancel: () => { },
        });
        const deletePlaceholderPro = (model) => {
            this.ctrlPosDeleteMode = model;
            modal.update({
                okButtonProps: {
                    props: {
                        disabled: !this.ctrlPosDeleteMode,
                    },
                },
            });
        };
    }
    /**
     * 打开动态逻辑设计界面
     *
     * @author zhanghengfeng
     * @date 2023-03-14 18:03:19
     */
    async openFormItemLogicView() {
        var _a, _b, _c, _d, _e, _f;
        const entity = this.ctx.ctrl.itemEntity;
        if (entity && this.data) {
            const codeName = (_a = entity.codeName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
            const key = (_c = (_b = entity.getKeyPSAppDEField()) === null || _b === void 0 ? void 0 : _b.codeName) === null || _c === void 0 ? void 0 : _c.toLowerCase();
            const majorKey = (_e = (_d = entity.getMajorPSAppDEField()) === null || _d === void 0 ? void 0 : _d.codeName) === null || _e === void 0 ? void 0 : _e.toLowerCase();
            if (codeName && key && majorKey) {
                const tempContext = Util.deepCopy(this.ctx.context);
                tempContext.viewpath = 'PSSYSAPPS/FormDesign/PSAPPDEVIEWS/PSDEFormDetailFDLogicEditView.json';
                tempContext.srfparentdemapname = entity.getPSDEName();
                tempContext[codeName] = this.data[key];
                const viewparams = {
                    [key]: this.data[key],
                    [majorKey]: this.data[majorKey],
                };
                const parentObj = {
                    srfparentdename: codeName,
                    srfparentkey: tempContext[codeName],
                };
                Object.assign(tempContext, parentObj);
                Object.assign(viewparams, parentObj);
                const type = this.data.detailtype;
                if (type === 'FORMITEM' || type === 'FORMITEMEX') {
                    tempContext.viewpath = 'PSSYSAPPS/FormDesign/PSAPPDEVIEWS/PSDEFormDetailFDLogic2EditView.json';
                }
                const appView = await this.modelService.getPSAppView(tempContext.viewpath);
                const view = {
                    viewname: 'app-view-shell',
                    height: appView.height,
                    width: appView.width,
                    title: this.$tl((_f = appView.getCapPSLanguageRes()) === null || _f === void 0 ? void 0 : _f.lanResTag, appView.caption),
                    placement: appView.openMode,
                };
                const container = this.$appdrawer.openDrawer(view, Util.getViewProps(tempContext, viewparams, [this.data]));
                container.subscribe((result) => {
                    if (!result || !Object.is(result.ret, 'OK')) {
                        return;
                    }
                });
            }
        }
    }
    /**
     * 绘制行为项
     *
     * @param {*} h
     * @returns {*}
     * @memberof DragDesignItemBase
     */
    renderActionItems() {
        var _a;
        return [
            Object.is(this.data.itemtype, 'CTRLPOS') ? (<li v-show={this.active}>
          <el-tooltip effect='dark' enterable={false} content='编辑' placement='top' open-delay={300}>
            <a-icon type='form' on-click={(e) => this.editorHandle(e)}/>
          </el-tooltip>
        </li>) : null,
            // <li>
            //     <el-tooltip effect='dark' enterable={false} content='保存为自定义部件' placement='top' open-delay={300}>
            //         <a-icon type='save' on-click={(e: any) => this.saveHandle(e)} />
            //     </el-tooltip>
            // </li>,
            // <li>
            //     <el-tooltip effect='dark' enterable={false} content='拷贝' placement='top' open-delay={300}>
            //         <a-icon type='copy' on-click={(e: any) => this.copyHandle(e)} />
            //     </el-tooltip>
            // </li>,
            <li class={['form-item-logic-btn', ((_a = this.data) === null || _a === void 0 ? void 0 : _a.fdlogiccount) ? '' : 'hidden']} on-click={() => this.openFormItemLogicView()}>
        <el-tooltip effect='dark' enterable={false} content='表单项逻辑' placement='top' open-delay={300}>
          <ion-icon icon={'./assets/svg/lightning.svg'}/>
        </el-tooltip>
      </li>,
            <li v-show={this.active}>
        <el-tooltip effect='dark' enterable={false} content='删除' placement='top' open-delay={300}>
          <a-icon type='delete' on-click={(e) => this.deleteHandle(e)}/>
        </el-tooltip>
      </li>,
        ];
    }
    /**
     * 根据项类型绘制
     *
     * @param {any} item
     * @return {*}
     * @memberof DragDesignItemBase
     */
    renderChildItem(item) {
        return this.ctx.ctrl.renderChildItem(this.$createElement, this.ctx, item, this.data);
    }
    /**
     * 绘制子数据
     *
     * @return {*}  {any[]}
     * @memberof DragDesignItemBase
     */
    renderChild() {
        return this.list.map(item => this.renderChildItem(item));
    }
    /**
     * 绘制内容
     *
     * @return {*}  {*}
     * @memberof DragDesignItemBase
     */
    renderContent() { }
    render() {
        const { srfkey } = this.data;
        this.calcStyle();
        return (<div id={srfkey} key={srfkey} style={this.style} class={Object.assign({ 'layout-item-container': true }, this.calcColClass(this.data))} on-click={(e) => this.onActiveClick(e, this.data)} on-dblclick={(e) => this.editorHandle(e)}>
        {this.renderContent()}
        {this.renderOther()}
      </div>);
    }
}
/**
 * 容器类型
 *
 * @author zhanghengfeng
 * @date 2023-05-18 14:05:54
 */
DragDesignItemBase.containerType = ['FORMPAGE', 'TABPAGE', 'GROUPPANEL'];
/**
 * 子项类型
 *
 * @author zhanghengfeng
 * @date 2023-05-18 15:05:05
 * @static
 */
DragDesignItemBase.childType = ['FORMITEM', 'RAWITEM', 'BUTTON', 'IFRAME', 'FORMITEMEX', 'DRUIPART', 'MDCTRL'];
