<template>
    <div :class="{'ibiz-group-select':true,'ibiz-group-select-tree':editorMode == 'tree'}">
        <div v-if="editorMode == 'tree'" class="ibiz-group-select-tree-content">
            <ibiz-select-tree  :NodesData="nodesData" v-model="curValue" :disabled="disabled" :multiple="multiple"></ibiz-select-tree>
        </div>
        <template v-else>
            <div class="ibiz-group-content">
                <span class="group-item-text" v-if="!multiple">
                    {{ selectName }}
                </span>
                <template v-else v-for="(select, index) of selects">
                    <div :key="index" class="ibiz-group-item">
                        <span class="group-item-multiple">{{ select.label }}</span>
                        <i v-if="!disabled" class="el-icon-circle-close" @click="remove(select)"></i>
                    </div>
                </template>
            </div>
            <div v-if="!disabled" class="ibiz-group-open">
                <i v-if="!disabled && !multiple && selects.length > 0" class="el-icon-circle-close" @click="remove(selects[0])"></i>
                <i class="el-icon-search" @click="openView" style="color: #c0c4cc;"></i>
            </div>
        </template>
    </div>
</template>

<script lang="ts">
import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
import { Subject } from 'rxjs';
import { CodeListService } from '@ibizstudio/runtime';
import { LogUtil, Util } from '@ibizstudio/runtime';
import axios from 'axios';

@Component({})
export default class AppGroupSelect extends Vue {
    /**
     * 名称标识
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    @Prop() name!: string;

    /**
     * 树加载地址
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    @Prop() treeurl?:boolean;

    /**
     * 数据接口地址
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    @Prop() url!: string;

    /**
     * 多选
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    @Prop({default: false}) multiple?: boolean;

    /**
     * 数据对象
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    @Prop() data: any;

    /**
     * 代码表标识
     * 
     * @memberof AppGroupSelect
     */
    @Prop() tag?:string;

    /**
     * 代码表类型
     * 
     * @memberof AppGroupSelect
     */
    @Prop() codelistType?:string;

    /**
     * 过滤属性标识
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    @Prop() filter?: string;

    /**
     * 是否启用
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    @Prop() disabled?: boolean;

    /**
     * 值
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    @Prop() value: any;

    /**
     * 上下文参数
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    @Prop() context: any;

    /**
     * 关联属性
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    @Prop() valueitem: any;

    /**
     * 填充属性
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    @Prop() fillMap: any;

    /**
     * 请求方式
     *
     * @type {stinr}
     * @memberof AppGroupSelect
     */ 
    @Prop({ default: 'get'})
    requestMode!: 'get' | 'post' | 'delete' | 'put';

    /**
     * 树双向绑定值
     *
     * @memberof AppGroupSelect
     */ 
    get curValue(){
        return JSON.stringify(this.selects);
    }
    
    set curValue(newVal:any ){
        this.onSelect(newVal);
    }

    /**
     * 分组编辑器模式
     *
     * @memberof AppGroupSelect
     */ 
    @Prop({ default: ''})
    editorMode ?:string ;

    /**
     * 选中项集合
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    protected selects: any[] = [];

    /**
     * 树模式数据
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    nodesData:any[] = [];

    /**
     * 树模式下模拟树父节点标识（用于过滤父节点）
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    groupIDArray:string[] = [];

    /**
     * 值变化
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    @Watch('data',{immediate:true,deep:true})
    onValueChange(newVal: any, oldVal: any) {
        this.selects = [];
        if (newVal) {
            let item: any = {};
            item.label = this.data[this.name]?this.data[this.name].split(','):[];
            item.id = this.data[this.valueitem] ? this.data[this.valueitem].split(',') : [];
            if(this.fillMap) {
                for(let key in this.fillMap) {
                    item[this.fillMap[key]] = this.data[key] ? this.data[key].split(',') : [];
                }
            }
            const callback:any = (item:any) =>{
                item.label.forEach((val: string, index: number) => {
                    let _item: any = {};
                    for(let key in item) {
                        _item[key] = item[key][index] ? item[key][index] : null;
                    }
                    this.selects.push(_item)
                })
            }
            if(item.label.length == 0 && item.id.length > 0){
                this.fillLabel(item,item.id,(result:any) =>{
                    item.label = result.label;
                    callback(item);
                });
            }else{
                callback(item);
            }
            
        }
    }

    /**
     * 单选时选中名称
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    get selectName() {
        if(this.selects.length > 0) {
            return this.selects[0].label;
        }
    }

    /**
     * 打开选择视图
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    openView() {
        const view: any = {
            viewname: 'app-group-picker',
            title: (this.$t('components.appgroupselect.groupselect') as string)
        };
        const context: any = JSON.parse(JSON.stringify(this.context));
        let filtervalue:string = "";
        if(this.filter){
            if(this.data[this.filter]){
                filtervalue = this.data[this.filter];
            }else if(context[this.filter]){
                filtervalue = context[this.filter];
            }else{
                filtervalue = context.srforgid;
            }
        }else{
            filtervalue = context.srforgid;
        }
        const param: any = {};
        Object.assign(param, {
            showtree: this.treeurl?true:false,
            url:this.url,
            treeurl:this.treeurl,
            filtervalue: filtervalue,
            multiple: this.multiple,
            selects: this.selects,
            requestMode: this.requestMode,
        });
        let container: Subject<any> = this.$appmodal.openModal(view, context, param);
        container.subscribe((result: any) => {
            if (!result || !Object.is(result.ret, 'OK')) {
                return;
            }
            this.openViewClose(result);
        });
    }

    /**
     * 选择视图关闭
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    openViewClose(result: any) {
        this.selects = [];
        if (result.datas && result.datas.length > 0) {
            this.selects = result.datas
        }
        this.setValue()
    }

    /**
     * 数据删除
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    remove(item: any) {
        this.selects.splice(this.selects.indexOf(item), 1);
        this.setValue()
    }

    /**
     * 设置值
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    setValue() {
        let item: any = {};
        item[this.name] = null;
        if(this.valueitem) {
            item[this.valueitem] = null;
        }
        if(this.fillMap) {
            for(let key in this.fillMap) {
                item[key] = null;
            }
        }
        if(this.multiple) {
            this.selects.forEach((select: any) => {
                item[this.name] = item[this.name] ? `${item[this.name]},${select.label}` : select.label;
                if(this.valueitem) {
                    item[this.valueitem] = item[this.valueitem] ? `${item[this.valueitem]},${select.id}` : select.id;
                }
                if(this.fillMap) {
                    for(let key in this.fillMap) {
                        item[key] = item[key] ? `${item[key]},${select[this.fillMap[key]]}` : select[this.fillMap[key]];
                    }
                }
            });
        } else {
            item[this.name] = this.selects.length > 0 ? this.selects[0].label : null;
            if(this.valueitem) {
                item[this.valueitem] = this.selects.length > 0 ? this.selects[0].id : null;
            }
            if(this.fillMap) {
                for(let key in this.fillMap) {
                    item[key] = this.selects.length > 0 ? this.selects[0][this.fillMap[key]] : null;
                }
            }
        }
        for(let key in item) {
            this.$emit('formitemvaluechange', { name: key, value: item[key] });
        }
    }

    /**
     * 填充label
     * 
     * @memberof AppGroupSelect
     */
    fillLabel(tempObject:any,valueItem:Array<any>,callback:any){
        if(tempObject.label.length === 0 && tempObject.id.length >0 && this.tag && this.codelistType && Object.is(this.codelistType,"DYNAMIC")){
        let codeListService:CodeListService = new CodeListService();
        codeListService.getItems(this.tag).then((items:any) =>{
            if(items && items.length >0 && valueItem.length >0){
            let tempLabel:Array<any> = [];
            valueItem.forEach((value:any) =>{
                let result:any = items.find((item:any) =>{
                    return item.id === value;
                })
                tempLabel.push(result.label);
            })
            Object.assign(tempObject,{label:tempLabel});
            }
            callback(tempObject);
        }).catch((error:any) =>{
            LogUtil.log(error);
        })
        }
    }

    /**
     * 声明周期
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    mounted(){
        if(this.editorMode == 'tree'){
            this.loadTree();
        }
    }

    /**
     * 加载树数据
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    loadTree() {
        const context: any = JSON.parse(JSON.stringify(this.context));
        let orgid:string = "";
        if(this.filter){
            if(this.data[this.filter]){
                orgid = this.data[this.filter];
            }else if(context[this.filter]){
                orgid = context[this.filter];
            }else{
                orgid = context.srforgid;
            }
        }else{
            orgid = context.srforgid;
        }
        let tempTreeUrl = this.url?.replace('${selected-orgid}',orgid);
        if(!tempTreeUrl){
            return;
        }
        axios({method: this.requestMode, url: tempTreeUrl, data: {}}).then((response: any) => {
            if(response.status === 200) {
                this.parseTreeData(response.data);
            }
        }).catch((error: any) => {
            LogUtil.log(error)
        })
    }

    /**
     * 树选择事件
     *
     * @type {*}
     * @memberof AppGroupSelect
     */  
    onSelect(event: any) {
        if (!event || JSON.parse(event).length == 0) {
            return;
        }
        const items: any[] = JSON.parse(event);
        this.selects = [];
        const _this: any = this;
        // 过滤根节点
        const curValue = items.filter((item: any) => {
            return !(
                _this.groupIDArray.findIndex((_item: any) => {
                    return item.id === _item;
                }) != -1
            );
        });
        this.selects = curValue;
        this.setValue();
    }


    /**
     * 构造树数据
     *
     * @type {*}
     * @memberof AppGroupSelect
     */
    parseTreeData(data:any) {
        let treeData:any = [];
        data.forEach((item:any) => {
            const index = treeData.findIndex((_item:any)=>{return _item.label == item.group});
            if(index != -1){
                treeData[index].children.push(item);
            }else{
                const uuid = Util.createUUID();
                this.groupIDArray.push(uuid);
                treeData.push({id:uuid,label:item.group,children:[item]});
            }
        });
        this.nodesData =treeData;
    }
  
}
</script>

<style lang="less">
@import './app-group-select.less';
</style>