import { Subscription } from 'rxjs';
import { CodeListServiceBase, throttle, MDControlInterface, ModelTool, Util } from '@ibizstudio/runtime'
import { MainControlBase } from './main-control-base';
import { GlobalService } from '@ibizstudio/runtime';
import { AppCenterService, AppViewLogicService } from '../app-service';
import { IPSAppCodeList, IPSAppDataEntity, IPSDETBUIActionItem, IPSDEToolbar, IPSDEToolbarItem, IPSDEUIAction } from '@ibizstudio/runtime';


/**
 * 多数据部件基类
 *
 * @export
 * @class MDControlBase
 * @extends {MainControlBase}
 */
export class MDControlBase extends MainControlBase implements MDControlInterface{
    /**
     * 代码表服务对象
     *
     * @type {CodeListService}
     * @memberof MDControlBase
     */
    codeListService!: CodeListServiceBase;

    /**
     * 应用状态事件
     *
     * @public
     * @type {(Subscription | undefined)}
     * @memberof MDControlBase
     */
    declare appStateEvent: Subscription | undefined;

    /**
     * 多数据部件实例
     *
     * @public
     * @type {(IPSMDControl)}
     * @memberof MDControlBase
     */
    declare controlInstance: any;

    /**
     * 快速工具栏实例
     *
     * @type {IPSDEToolbar}
     * @memberof MDControlBase
     */
    quickToolbarInstance!: IPSDEToolbar;
    
    /**
     * 批处理工具栏实例
     *
     * @type {IPSDEToolbar}
     * @memberof MDControlBase
     */
    batchToolbarInstance!: IPSDEToolbar;

    /**
     * 快速行为模型数据
     *
     * @protected
     * @type {[]}
     * @memberof MDControlBase
     */
     quickToolbarModels: Array<any> = [];

     /**
      * 批操作行为模型数据
      *
      * @protected
      * @type {[]}
      * @memberof MDControlBase
      */
     batchToolbarModels: Array<any> = [];

    /**
     * 选中行数据
     *
     * @type {any[]}
     * @memberof MDControlBase
     */
    selections: any[] = [];

    /**
     * 当前页
     *
     * @type {number}
     * @memberof MDControlBase
     */
    curPage: number = 1;

    /**
     * 多数据部件数据激活模式
     * 0 不激活
     * 1 单击激活
     * 2 双击激活
     *
     * @type {(number | 0 | 1 | 2)}
     * @memberof GridControlBase
     */
    mDCtrlActiveMode: number | 0 | 1 | 2 = 2;

    /**
     * 数据
     *
     * @type {any[]}
     * @memberof MDControlBase
     */
    items: any[] = [];

    /**
     * 是否支持分页
     *
     * @type {boolean}
     * @memberof MDControlBase
     */
    isEnablePagingBar: boolean = true;

    /**
     * 是否禁用排序
     *
     * @type {boolean}
     * @memberof MDControlBase
     */
    isNoSort: boolean = false;

    /**
     * 分页条数
     *
     * @type {number}
     * @memberof MDControlBase
     */
    limit: number = 20;

    /**
     * 总条数
     *
     * @type {number}
     * @memberof MDControlBase
     */
    totalRecord: number = 0;

    /**
     * 是否单选
     *
     * @type {boolean}
     * @memberof MDControlBase
     */
    declare isSingleSelect?: boolean;

    /**
     * 是否默认选中第一条数据
     *
     * @type {boolean}
     * @memberof MDControlBase
     */
    isSelectFirstDefault: boolean = false;

    /**
     * 排序方向
     *
     * @type {string}
     * @memberof MDControlBase
     */
    minorSortDir: string = "";

    /**
     * 排序字段
     *
     * @type {string}
     * @memberof MDControlBase
     */
    minorSortPSDEF: string = "";

    /**
     * 建立数据行为
     *
     * @readonly
     * @memberof MDControlBase
     */
    createAction: string = "";
    /**
     * 查询数据行为
     *
     * @readonly
     * @memberof MDControlBase
     */
    fetchAction: string = "";

    /** 
     * 更新数据行为
     *
     * @readonly
     * @memberof MDControlBase
     */
    updateAction: string = "";

    /**
     * 删除数据行为
     *
     * @readonly
     * @memberof MDControlBase
     */
    removeAction: string = "";

    /**
     * 查询数据行为
     *
     * @readonly
     * @memberof MDControlBase
     */
    loadAction: string = "";

    /**
     * 获取草稿数据行为
     *
     * @readonly
     * @memberof MDControlBase
     */
    loaddraftAction: string = "";

    /**
     * 数据映射（数据项名称和UI名称的映射）
     * 
     * @memberof MDControlBase
     */
    dataMap: Map<string, any> = new Map();

    /**
     * 分组模式
     * 
     * @type {string}
     * @memberof MDControlBase
     */
    groupMode: string = '';

    /**
     * 是否开启分组
     * 
     * @type {boolean}
     * @memberof MDControlBase
     */
    isEnableGroup: boolean = false;

    /**
     * 分组属性
     * 
     * @type {string}
     * @memberof MDControlBase
     */
    groupField: string = '';

    /**
     * 分组代码表
     * 
     * @type {IPSAppCodeList}
     * @memberof MDControlBase
     */
    groupCodeList?: IPSAppCodeList;

    /**
     * 获取视图样式
     *
     * @readonly
     * @memberof MDControlBase
     */
    get viewStyle(){
        const parentModel: any = this.controlInstance?.getParentPSModelObject?.();
        if (parentModel && parentModel.viewStyle) {
            return parentModel.viewStyle;
        } else {
            if (parentModel && parentModel.controlType) {
                return parentModel.getParentPSModelObject?.()?.viewStyle || 'DEFAULT';
            }
            return 'DEFAULT';
        }
    }

    /**
     * 监听静态参数变化
     *
     * @param {*} newVal
     * @param {*} oldVal
     * @memberof MDControlBase
     */
    onStaticPropsChange(newVal: any, oldVal: any) {
        this.isSingleSelect = newVal.isSingleSelect !== false;
        this.isSelectFirstDefault = newVal.isSelectFirstDefault === true;
        this.mDCtrlActiveMode = newVal.mDCtrlActiveMode;
        super.onStaticPropsChange(newVal, oldVal);
    }

    /**
     * 部件模型数据初始化
     *
     * @memberof MDControlBase
     */
    async ctrlModelInit(args?: any) {
        await super.ctrlModelInit();
        const { name } = this.controlInstance;
        if (this.controlInstance?.getPSAppDataEntity?.() && !(this.Environment && this.Environment.isPreviewMode)) {
            if(!this.controlInstance?.getPSAppDataEntity()?.isFill){
                await this.controlInstance?.getPSAppDataEntity().fill();
            }
            this.appEntityService = await new GlobalService().getService((this.controlInstance.getPSAppDataEntity() as IPSAppDataEntity).codeName, this.context);
        }
        this.loaddraftAction = this.controlInstance?.getGetDraftPSControlAction?.()?.getPSAppDEMethod?.()?.codeName || "GetDraft";
        this.loadAction = this.controlInstance?.getGetPSControlAction?.()?.getPSAppDEMethod?.()?.codeName || "Get";
        this.removeAction = this.controlInstance?.getRemovePSControlAction?.()?.getPSAppDEMethod?.()?.codeName || "Remove";
        this.updateAction = this.controlInstance?.getUpdatePSControlAction?.()?.getPSAppDEMethod?.()?.codeName || "Update";
        this.fetchAction = this.controlInstance?.getFetchPSControlAction?.()?.getPSAppDEMethod?.()?.codeName || "FetchDefault";
        this.createAction = this.controlInstance?.getCreatePSControlAction?.()?.getPSAppDEMethod?.()?.codeName || "Create";
        if(this.controlInstance?.getPSControls?.()){
            this.quickToolbarInstance = ModelTool.findPSControlByName(`${name}_quicktoolbar`, this.controlInstance.getPSControls())
            this.batchToolbarInstance = ModelTool.findPSControlByName(`${name}_batchtoolbar`, this.controlInstance.getPSControls())
        }
        this.initToolBarModels();
        this.initDataMap();
        this.initGroupOptions();
    }

    /**
     * 初始化工具栏模型
     *
     * @memberof MDControlBase
     */
     initToolBarModels() {
        const getModelData = (_item: IPSDEToolbarItem) => {
            const item: IPSDETBUIActionItem = _item as IPSDETBUIActionItem;
            const uiAction: IPSDEUIAction | null = item.getPSUIAction ? (item?.getPSUIAction() as IPSDEUIAction) : null;
            return {
                name: item.name,
                showCaption: item.showCaption,
                showIcon: item.showIcon,
                tooltip: this.$tl(item.getTooltipPSLanguageRes()?.lanResTag, item.tooltip),
                iconcls: item.getPSSysImage()?.cssClass,
                icon: item.getPSSysImage()?.imagePath,
                actiontarget: item.uIActionTarget,
                caption: this.$tl(item.getCapPSLanguageRes()?.lanResTag, item.caption),
                disabled: false,
                itemType: item.itemType,
                visabled: true,
                noprivdisplaymode: uiAction?.noPrivDisplayMode,
                actionLevel:(_item as any).actionLevel,
                dataaccaction: '',
                uiaction: {
                    tag: uiAction?.uIActionTag ? uiAction.uIActionTag : uiAction?.id ? uiAction.id : '',
                    target: uiAction?.actionTarget,
                },
            };
        };
        if (this.quickToolbarInstance) {
            let targetViewToolbarItems: any[] = [];
            this.quickToolbarInstance.getPSDEToolbarItems()?.forEach((item: IPSDEToolbarItem) => {
                targetViewToolbarItems.push(getModelData(item));
            });
            this.quickToolbarModels = targetViewToolbarItems;
        }
        if (this.batchToolbarInstance) {
            let targetViewToolbarItems: any[] = [];
            this.batchToolbarInstance.getPSDEToolbarItems()?.forEach((item: IPSDEToolbarItem) => {
                targetViewToolbarItems.push(getModelData(item));
            });
            this.batchToolbarModels = targetViewToolbarItems;
        }
    }

    /**
     * 多数据部件初始化
     *
     * @memberof MDControlBase
     */
    ctrlInit() {
        super.ctrlInit();
        let _this: any = this;
        // 全局刷新通知
        if (AppCenterService.getMessageCenter()) {
            _this.appStateEvent = AppCenterService.getMessageCenter().subscribe(({ name, action, data }: { name: string, action: string, data: any }) => {
                if (!_this.appDeCodeName || !Object.is(name, _this.appDeCodeName)) {
                    return;
                }
                if (Object.is(action, 'appRefresh')) {
                    _this.refresh(data);
                }
            })
        }
        _this.codeListService = new CodeListServiceBase({ $store: _this.$store });
    }

    /**
     * 执行destroyed后的逻辑
     *
     * @memberof MDControlBase
     */
    ctrlDestroyed() {
        super.ctrlDestroyed();
        if (this.appStateEvent) {
            this.appStateEvent.unsubscribe();
        }
    }

    /**
     * 部件工具栏点击
     *
     * @param ctrl 部件
     * @param data 工具栏回传数据
     * @param $event 事件源对象
     * @memberof MDControlBase
     */
    handleItemClick(ctrl: string, data: any, $event: any) {
        AppViewLogicService.getInstance().executeViewLogic(
            this.getViewLogicTag(this.controlInstance.name, ctrl, data.tag),
            $event,
            this,
            undefined,
            this.controlInstance.getPSAppViewLogics() as Array<any>,
        );
    }

    /**
     * 获取多项数据
     *
     * @returns {any[]}
     * @memberof MDControlBase
     */
    getDatas(): any[] {
        return this.selections;
    }

    /**
     * 获取单项数据
     *
     * @returns {*}
     * @memberof MDControlBase
     */
    getData(): any {
        return this.selections[0];
    }

   /**
     * 绘制加载数据提示信息
     *
     * @return {*} 
     * @memberof MDControlBase
     */
    renderLoadDataTip(){
        return <div class="load-data-tip">
            <span class="tip-text">{this.$t('app.warn.load')}</span>
        </div>
    }

    /**
     * 绘制无数据提示信息
     *
     * @return {*} 
     * @memberof MDControlBase
     */
    renderEmptyDataTip(){
        return <div class="empty-data-tip">
            <span class="tip-text">{this.$t('app.warn.nofind')}</span>
            {this.renderQuickToolbar()}
        </div>
    }

    /**
     * 绘制快速工具栏
     *
     * @return {*} 
     * @memberof MDControlBase
     */
    renderQuickToolbar(): any{
        return <span class='quick-toolbar'>
            <view-toolbar
                toolbarModels={this.quickToolbarModels}
                on-item-click={(data: any, $event: any) => {
                    throttle(this.handleItemClick,['quicktoolbar', data, $event],this);
                }}
            ></view-toolbar>
        </span>
    }

    /**
     * 绘制批处理工具栏
     *
     * @return {*} 
     * @memberof MDControlBase
     */
    renderBatchToolbar(): any{
        for (let index = 0; index < this.batchToolbarModels.length; index++) {
            this.batchToolbarModels[index].disabled = this.selections.length <= 0;
        }
        return <span v-show={this.selections.length > 0 || this.viewStyle == 'DEFAULT'} class="batch-toolbar">
            <view-toolbar
                toolbarModels={this.batchToolbarModels}
                on-item-click={(data: any, $event: any) => {
                    throttle(this.handleItemClick,['batchtoolbar', data, $event],this);
                }}
            ></view-toolbar>
        </span>
    }

    /**
     * 初始化数据映射
     * 
     * @memberof MDControlBase
     */
    initDataMap() {}

    /**
     * 将数据项数据转化为UI数据
     * 
     * @param data 源数据
     */
    dataItemTransition(data: any[]) {
        let _data: any[] = Util.deepCopy(data);
        if (data.length > 0) {
            data.forEach((item: any, index: number) => {
                for (const key in item) {
                    const itemUI: any = this.dataMap.get(key);
                    if (itemUI && !Object.is(itemUI.itemUIName, key)) {
                        delete _data[index][key];
                        Object.assign(_data[index],{ [itemUI.itemUIName]: item[key]});
                    };
                };
            });
        };
        return _data;
    }

    /**
     * 将项UI数据转为数据项数据
     * 
     * @param data 多数据部件数据
     */
    itemUIDataTransition(data: any[]) {
        let _data: any[] = Util.deepCopy(data);
        let dataItems: any[] = [];
        if (_data) {
            for (const [dataItemName, itemUI] of this.dataMap) {
                if (!Object.is(dataItemName, itemUI.itemUIName)) {
                    dataItems.push(dataItemName);
                };
            };
            data.forEach((item: any, index: number) => {
                if (dataItems.length > 0) {
                    for (const key in item) {
                        dataItems.forEach((dataItemName: any) => {
                            const itemUI: any = this.dataMap.get(dataItemName);
                            if (itemUI && Object.is(itemUI.itemUIName, key)) {
                                delete _data[index][key];
                                Object.assign(_data[index],{ [dataItemName]: item[key]});
                            }
                        })
                    };
                };
            });
        };
        return _data;
    }

    /**
     * 初始化分组配置
     * 
     * @memberof MDControlBase
     */
    initGroupOptions() {
        this.isEnableGroup = (this.controlInstance.enableGroup && this.controlInstance.getGroupPSAppDEField?.()) ? true : false;
        if (this.isEnableGroup) {
            this.groupMode = this.controlInstance.groupMode;
            this.groupField = this.controlInstance.getGroupPSAppDEField().codeName?.toLowerCase();
            this.groupCodeList = this.controlInstance.getGroupPSCodeList?.() as IPSAppCodeList;
        }
    }

    /**
     * 分组
     * 
     * @memberof MDControlBase
     */
    group() {
        if (Object.is(this.groupMode, "AUTO")) {
            this.drawGroup();
        } else if (Object.is(this.groupMode, "CODELIST")) {
            this.drawCodelistGroup();
        }
    }

    /**
     * 自动分组
     * 
     * @memberof MDControlBase
     */
    drawGroup() { }

    /**
     * 代码表分组
     * 
     * @memberof MDControlBase
     */
    drawCodelistGroup() { }
}
