import { Store } from 'vuex';
import { Util } from '@/utils/util/util';
import CodeListService from "@/codelist/codelist-service";

/**
 * 部件服务基类
 *
 * @export
 * @class ControlService
 */
export default class ControlService {

    /**
     * Vue 状态管理器
     *
     * @private
     * @type {(any | null)}
     * @memberof Service
     */
    private $store: Store<any> | null = null;

    /**
     * 部件模型
     *
     * @type {(any | null)}
     * @memberof ControlService
     */
    public model: any | null = null;

    /**
     * 代码表服务对象
     *
     * @type {any}
     * @memberof ControlService
     */  
    public codeListService:any;

    /**
     * 是否为从数据模式
     *
     * @type {boolean}
     * @memberof ControlService
     */
    public isTempMode:boolean = false;

    /**
     * Creates an instance of ControlService.
     * 
     * @param {*} [opts={}]
     * @memberof ControlService
     */
    constructor(opts: any = {}) {
        this.$store = opts.$store;
        this.setTempMode();
        this.codeListService = new CodeListService({ $store:opts.$store });
    }

    /**
     * 获取状态管理器
     *
     * @returns {(any | null)}
     * @memberof ControlService
     */
    public getStore(): Store<any> | null {
        return this.$store;
    }

    /**
     * 获取部件模型
     *
     * @returns {*}
     * @memberof ControlService
     */
    public getMode(): any {
        return this.model;
    }

    /**
     * 设置零时模式
     *
     * @returns {(any | null)}
     * @memberof ControlService
     */
    protected setTempMode(){
        
    }

    /**
     * 处理请求数据
     * 
     * @param action 行为 
     * @param data 数据
     * @memberof ControlService
     */
    public handleRequestData(action: string,context:any ={},data: any = {},isMerge:boolean = false){
        let model: any = this.getMode();
        if (!model && model.getDataItems instanceof Function) {
            return data;
        }
        let dataItems: any[] = model.getDataItems();
        let requestData:any = {};
        if(isMerge && (data && data.viewparams)){
            Object.assign(requestData,data.viewparams);
        }
        dataItems.forEach((item:any) =>{
            if(item && item.dataType && Object.is(item.dataType,'FONTKEY')){
                if(item && item.prop && item.name ){
                    requestData[item.prop] = context[item.name];
                }
            }else{
                if(item && item.prop && item.name && (data[item.name] || Object.is(data[item.name],0)) ){
                    requestData[item.prop] = data[item.name];
                }
            }
        });
        let tempContext:any = JSON.parse(JSON.stringify(context));
        if(tempContext && tempContext.srfsessionid){
            tempContext.srfsessionkey = tempContext.srfsessionid;
            delete tempContext.srfsessionid;
        }
        return {context:tempContext,data:requestData};
    }

    /**
     * 处理response
     *
     * @param {string} action
     * @param {*} response
     * @memberof ControlService
     */
    public async handleResponse(action: string, response: any,isCreate:boolean = false){
        let result = null;
        if (!response.data) {
            return
        }
        const handleResult:any = (action: string, response: any,isCreate:boolean,codelistArray?:any) =>{
            if (response.data instanceof Array) {
                result = [];
                response.data.forEach((item:any) =>{
                    result.push(this.handleResponseData(action, item, isCreate,codelistArray));
                });
            }else{
                result = this.handleResponseData(action, response.data, isCreate,codelistArray);
            }
            // response状态，头文件
            if(response.headers){
                if(response.headers['x-page']){
                    Object.assign(response,{page:Number(response.headers['x-page'])});
                }
                if(response.headers['x-per-page']){
                    Object.assign(response,{size:Number(response.headers['x-per-page'])});
                }
                if(response.headers['x-total']){
                    Object.assign(response,{total:Number(response.headers['x-total'])});
                }
            }
            response.data = result;
        }
        let codelistModel:Array<any> = this.handleCodelist();
        if(codelistModel.length >0){
            let res:any = await this.getAllCodeList(codelistModel);
            handleResult(action, response,isCreate,res);
        }else{
            handleResult(action, response,isCreate);
        }
    }

    /**
     * 处理返回数据
     *
     * @param {string} action
     * @param {*} response
     * @memberof ControlService
     */
    public handleResponseData(action: string, data: any = {},isCreate?:boolean,codelistArray?:any){
        let model: any = this.getMode();
        if (!model && model.getDataItems instanceof Function) {
            return data;
        }
        let item: any = {};
        let dataItems: any[] = model.getDataItems();
        dataItems.forEach(dataitem => {
            let val = data.hasOwnProperty(dataitem.prop) ? data[dataitem.prop] : null;
            if (val === null) {
                val = data.hasOwnProperty(dataitem.name) ? data[dataitem.name] : null;
            }
            if((isCreate === undefined || isCreate === null ) && Object.is(dataitem.dataType, 'GUID') && Object.is(dataitem.name, 'srfkey') && (val && !Object.is(val, ''))){
                isCreate = true;
            }
            item[dataitem.name] = val;
            // 转化代码表
            if(codelistArray && dataitem.codelist){
                if(codelistArray.get(dataitem.codelist.tag) && codelistArray.get(dataitem.codelist.tag).get(val)){
                    item[dataitem.name] = codelistArray.get(dataitem.codelist.tag).get(val);
                }
            }
        });
        item.srfuf = data.srfuf ? data.srfuf : (isCreate ? "0" : "1");
        return item;
    }

    /**
     * 处理工作流数据
     * 
     * @param data 传入数据
     */
    public handleWFData(data:any, isMerge:boolean = false){
        let model: any = this.getMode();
        if (!model && model.getDataItems instanceof Function) {
            return data;
        }
        let dataItems: any[] = model.getDataItems();
        let requestData:any = {};
        dataItems.forEach((item:any) =>{
            if(item && item.prop){
                requestData[item.prop] = data[item.name];
            }else{
                if(item && item.dataType && Object.is(item.dataType,"FORMITEM")){
                    requestData[item.name] = data[item.name]
                }
            }
        });
        if(isMerge && (data.viewparams && Object.keys(data.viewparams).length > 0)){
            Object.assign(requestData,data.viewparams);
        }
        return requestData;
    }

    /**
     * 处理代码表
     * 
     * @memberof ControlService
     */
    public handleCodelist(){
        let model: any = this.getMode();
        if (!model) {
            return [];
        }
        let dataItems: any[] = model.getDataItems();
        let codelistMap:Map<string,any> = new Map();
        if(dataItems && dataItems.length >0){
            dataItems.forEach((item:any) =>{
                if(item.codelist){
                    codelistMap.set(item.name,item.codelist);
                }
            })
        }
        if(codelistMap.size >0){
            return  Array.from(codelistMap).map(item => item[1]);
        }else{
            return [];
        }
    }

    /**
     * 获取所有代码表
     * 
     * @param codelistArray 代码表模型数组
     * @memberof ControlService
     */
    public getAllCodeList(codelistArray:Array<any>):Promise<any>{
        return new Promise((resolve:any,reject:any) =>{
            let codeListMap:Map<string,any> = new Map();
            let promiseArray:Array<any> = [];
            codelistArray.forEach((item:any) =>{
                if(!codeListMap.get(item.tag)){
                    promiseArray.push(this.getCodeList(item));
                    Promise.all(promiseArray).then((result:any) =>{
                        if(result && result.length >0){
                            result.forEach((codeList:any) =>{
                                let tempCodeListMap:Map<number,any> = new Map();
                                if(codeList.length >0){
                                    codeList.forEach((codeListItem:any) =>{
                                        tempCodeListMap.set(codeListItem.value,codeListItem.text);
                                    })
                                }
                                codeListMap.set(item.tag,tempCodeListMap);       
                            })
                            resolve(codeListMap);
                        }
                    })
                }
            })
        })
    }

    /**
     * 获取代码表
     * 
     * @param codeListObject 传入代码表对象
     * @memberof ControlService
     */
    public getCodeList(codeListObject:any):Promise<any>{
        return new Promise((resolve:any,reject:any) =>{
            if(codeListObject.tag && Object.is(codeListObject.codelistType,"STATIC")){
                const codelist = (this.getStore() as Store<any>).getters.getCodeList(codeListObject.tag);
                if (codelist) {
                    resolve([...JSON.parse(JSON.stringify(codelist.items))]);
                } else {
                    resolve([]);
                    console.log(`----${codeListObject.tag}----代码表不存在`);
                }
            }else if(codeListObject.tag && Object.is(codeListObject.codelistType,"DYNAMIC")){
                this.codeListService.getItems(codeListObject.tag).then((res:any) => {
                    resolve(res);
                }).catch((error:any) => {
                    resolve([]);
                    console.log(`----${codeListObject.tag}----代码表不存在`);
                });
            }
        })
    }

    /**
     * 根据后台标识获取数据标识名称
     * 
     * @param prop 后台标识
     * @memberof ControlService
     */
    public getNameByProp(prop: any) {
        let model: any = this.getMode();
        if(!model || !prop) {
            return false;
        }
        let dataItems: any[] = model.getDataItems();
        prop = prop.replace(/([A-Z])/g,"_$1").toLowerCase();
        let data: any = dataItems.find((item:any) => {
            return Object.is(prop, item.prop);
        });
        return data.name;
    }
}