<template>
    <view class="comp-form_query">
        <view class="bar-form_query">
            <view class="quickSelect">
                <template v-for="(item, key) in controls" :key="key">
                    <template v-if="item.quick">
                        <comp-form_query-quickselect class="comp-form_query-quickselect" :KEY="key" :data="data_in" :controls="controls" @change:data="(e:any)=>changeData(key,e)" @select="(e:any)=>selectData(key,e)" />
                    </template>
                </template>
            </view>
            <view class="btn-open_form" hover-class="hover" @click="change_showPopup_sort" v-if="sort.show">
                {{ translate('sort') }} 
            </view>
            <view class="btn-open_form" hover-class="hover" :class="[getIsFilted()]" @click="change_showPopup">
                <template v-if="!showPopup">
                    {{ translate('query filter') }} <iconfont class="iconfont" icon="menu"/> 
                </template>
                <template v-else>
                    {{ translate('close query filter') }} <iconfont class="iconfont" icon="caret-up"/> 
                </template>

                <view :class="[getIsFilted()]" class="dot"></view>
            </view>
        </view>
        <view class="bar-search"> 
            <template v-for="(item, key) in controls">
                <template v-if="item.search">
                    <comp-form_query-search class="comp-form_query-search"  :KEY="key" :data="data_in" :controls="controls" @change:data="(e:any)=>changeData(key,e,)" @select="(e:any)=>selectData(key,e)"/>
                </template>
            </template>
        </view>

        <view class="popup-form_query" v-show="showPopup">
            <view class="main-form_query">
                
                <view class="main">
                    <view class="left">
                        <template v-for="(item, key) in controls" :key="key">
                            <view class="item" hover-class="hover" :class="[control_class(item)]" v-if="item.render">
                                {{ item.label }} 
                            </view>
                        </template>
                    </view>
                    <view class="right">
                        <template v-for="(item, key) in controls" :key="key">
                            <view class="item" :class="[control_class(item)]" v-if="item.render">
                                <view class="title">{{ item.label }} {{ (item.select?.multiple)?`(${translate('multiple_select')})`:'' }}</view>
                                <view>
                                    <template v-if="item.type == 'input'">
                                        <input-form-query :KEY="key" :data="data_in" :controls="controls" @change:data="(e:any)=>changeData(key,e)"/>
                                    </template>
                                    <template v-else-if="item.type == 'select'">
                                        <select-form-query :KEY="key" :data="data_in" :controls="controls" @change:data="(e:any)=>changeData(key,e)" :show="showPopup"/>
                                    </template>
                                    <template v-else-if="item.type == 'selectmultiple'">
                                        <select-form-query :KEY="key" :data="data_in" :controls="controls" @change:data="(e:any)=>changeData(key,e)" :show="showPopup"/>
                                    </template>
                                    <template v-else-if="item.type == 'number'">
                                        <input-form-query :KEY="key" :data="data_in" :controls="controls" @change:data="(e:any)=>changeData(key,e)" />
                                    </template>
                                    <template v-else-if="item.type == 'date'">
                                        <date-form-query :KEY="key" :data="data_in" :controls="controls" @change:data="(e:any)=>changeData(key,e)" />
                                    </template>
                                    <template v-else-if="item.type == 'datetimerange'">
                                        <datetimerange-form-query :KEY="key" :data="data_in" :controls="controls" @change:data="(e:any)=>changeData(key,e)" />
                                    </template>
                                </view>
                            </view>
                        </template>
                    </view>
                </view>


                <view class="btn">
                    <view class="reset" hover-class="hover" @click="reset">{{ translate('reset') }}</view>
                    <view class="query" hover-class="hover" @click="submit">{{ translate('query') }}</view>
                </view>
            </view>
            <view class="mark"  @click="change_showPopup"></view>
        </view>



        <view class="popup-form_sort" v-show="showPopup_sort" >
            <view class="main-form_sort">
                
                <view class="main">
                    <template v-for="(item, index) in sort.sort" :key="key">
                        <view class="li" @click="change_sort(item)"> 
                            <view class="name">{{translate(item.key)}}</view>
                            <view class="right" v-if="item.active">
                                <view class="index">{{item.index || ''}}</view>
                                <view class="type" @click.stop="change_sort_type(item)">
                                    <template v-if="item.type == 'ASC'"><iconfont class="iconfont" icon="arrowup"/></template>
                                    <template v-else-if="item.type == 'DESC'"><iconfont class="iconfont" icon="arrowdown"/></template>
                                </view>
                            </view>
                        </view>
                    </template>
                </view>

                <view class="btn">
                    <view class="query" hover-class="hover" @click="change_showPopup_sort">{{ translate('close') }}</view>
                </view>
            </view>
            <view class="mark"  @click="change_showPopup_sort"></view>
        </view>
    </view>
</template>
  
<script setup lang="ts">
import { ref, reactive, computed, onBeforeMount, onMounted, onUnmounted, watch, nextTick } from 'vue'
import Storage from '@/common/utils/storage/index'
import EXEC from '@/common/utils/exec';
import { translate } from '@/common/utils/language/index'
import { setChildrens, clearChildrensData } from './js/index'
  
    
    const props = defineProps({
        menuID: <any>{ default: ''},  
        controls:  <any>{ type: Object, default: () => {}, }, 
        quickSelect:  <any>{ type: Object, default: () => {}, },
        search:  <any>{ type: Object, default: () => {}, },
        sort:  <any>{ type: Object, default: () => {}, },
        data: { type: Object, default: () => {}, }, // 表单数据 v-modal
        buttons: <any>{ type: Array, default: () => [], },
        module_info: {type:Object, default: () => {}, },  
    })
    const control_class = (item:any) => {
        let newClass:any = ''
        if(item.required){
            newClass = newClass + ' required'
        }
        if(!item.show){
            newClass = newClass + ' hidden'
        }
        return newClass
    }

    // 备份值 （渲染完成后，获取默认后的值的集合）
    const data_backup = <any>ref({})
    // 内部值  （在没有保存之前的值的集合）
    const data_in = <any>ref({})


    // 弹窗层
    const showPopup = ref(false)
    const change_showPopup = ()=>{
        showPopup.value = !showPopup.value
    }
    const getIsFilted = () => { // 获取是否有值
        let isFilted = false
        for(let key in props.controls){
            if(props.data[key]) {
                isFilted = true
                break
            }
        }
        return isFilted?'isFilted':''
    }

    // gather 获取值
    const gather = () => {
        return new Promise((resolve, reject)=>{
            let obj:any = {}
            for(let key in data_in.value){
                // 数组转字符串，逗号分隔
                let e = Array.isArray(data_in.value[key])?data_in.value[key].join(','):data_in.value[key]
                Object.assign(obj,{ [key]: e })
            }
            if(sortIndex.value.length>0){
                let query_sort_field:any = []
                for(let i in sortIndex.value){
                    for(let row of props.sort.sort){
                        if(sortIndex.value[i] == row.key){
                            query_sort_field.push({
                                "sort_type":row.type,
                                "field":row.key,
                                "sort_seq":row.index,
                            })
                        }
                    }
                }
                obj.query_sort_field = query_sort_field
            }
            resolve(obj)
        })
    }

    // 确定按钮 
    const submit = () => {
        gather().then((obj:any)=>{
            showPopup.value = false
            emit('submit', obj)
        })
    }
    // 重置按钮
    const reset = () => {
        data_in.value = {...data_backup.value}
        emit('submit', data_in.value)
    }
    const changeData = (KEY:any, e:any, ) => { // 控件change事件
        data_in.value[KEY] = e
        // 处理时间区间
        if( props.controls[KEY].type == 'datetimerange'){
            if(e){
                Object.assign(data_in.value,{ 
                    [`time_type_value`]: `Between$$${e[0]}@@${e[1]}` ,
                })
            }else{
                delete data_in.value.time_type_value
            }
        }
        if(KEY=='time_type'){
            data_in.value.time_type_code = data_in.value['time_type']
        }

        clearChildrensData(KEY,data_in.value, props.controls)
    }
    const selectData = (KEY:any, e:any) => {
        data_in.value[KEY] = e
        clearChildrensData(KEY,data_in.value, props.controls)
        submit()
    }
    


    // 排序
    const showPopup_sort = ref(false)
    const sortIndex = <any>ref([])
    const change_showPopup_sort = () => {
        showPopup_sort.value = !showPopup_sort.value
        if(!showPopup_sort.value){
            submit()
        }
    }
    const change_sort = (item:any) => {
        if(item.active==undefined) item.active = true
        else item.active = !item.active
        
        if(sortIndex.value.indexOf(item.key)>=0 && !item.active){
            sortIndex.value.splice(sortIndex.value.indexOf(item.key),1)
        }else if(item.active){
            sortIndex.value.push(item.key)
        }
        
        for(let i in sortIndex.value){
            for(let row of props.sort.sort){
                if(sortIndex.value[i] == row.key){
                    row.index = Number(i)+1
                }
            }
        }
    }
    const change_sort_type = (item:any) => {
        if(item.type == 'ASC'){
            item.type = 'DESC'
        }else if(item.type == 'DESC'){
            item.type = 'ASC'
        }
    }

  
    defineExpose({
        gather, 
        submit,
    })
    onBeforeMount(async() => {
        for(let key in props.controls){
            if(props.data[key] == undefined){
                props.data[key] = ''
            }
        }
    })
    onMounted(()=>{
        data_in.value = Object.assign(data_in.value,{ ...props.data })
        let timer = setTimeout(()=>{
            data_backup.value = { ...data_in.value }
            clearTimeout(timer)
        },1000)
    })
    onUnmounted(() => {
    })
    const emit = defineEmits(['changeData' , 'submit', 'change'])

    // 联动 
    watch( 
        ()=>data_in.value,
        (newData,oldData)=>{
            setChildrens(data_in.value, props.controls)
        },
        { immediate: true, deep: true, }
    )

</script>
  
<style lang="scss">
.comp-form_query{
    position: relative;
    top: 0;
    z-index: 999;
    width: 100vw;


    .bar-search{
        .comp-form_query-search{
            padding: 15rpx;
            background: #ddd;
            border-bottom: 1rpx solid #eaf1f7;
            display: block;
        }
    }
    .bar-form_query{
        height: 80rpx;
        background: #fff;
        border-bottom: 1rpx solid #eaf1f7;
        display: flex;
        >.quickSelect{
            width: calc(100% - 120rpx);
            display: flex;
            flex-wrap: nowrap;
            .comp-form_query-quickselect{
                padding: 10rpx;
            }
        }
        >.btn-open_form{
            width: 120rpx;
            height: 80rpx;
            line-height: 80rpx;
            color: #333;
            display: flex;
            font-size: 14px;
            position: relative;
            &.hover{
                color: $primary-color
            }
            >.iconfont{
                font-size: 18rpx;
                margin-left: 10rpx;
                view{
                    font-size: 18rpx !important;
                }
            }
            &.isFilted{
                >.iconfont{
                    view{
                        color:  $primary-color;  
                        font-size: 20rpx !important;
                    }
                }
            }
            >.dot{
                position: absolute;
                border-radius: 50%;
                width: 6px;
                height: 6px;
                background:  $primary-color;    
                top: 10px;
                right: 16px;
                display: none;
                &.isFilted{
                    display: block;
                }   
            }
        }
    }
    .popup-form_query{
        position: absolute;
        top: 80rpx;
        left: 0;
        right: 0;
        z-index: 9;
        >.main-form_query{
            background: #fff;
            height: 80vh;
            position: relative;
            z-index: 2;
            border-top: 1rpx solid #ddd;
            
            >.main{
                display: flex;
                width: 100vw;
                min-height: 100%;
                >.left{
                    width: 200rpx;
                    height: calc(80vh - 80rpx);
                    overflow-x: hidden;
                    overflow-y: scroll;
                    border-right: 1rpx solid #ddd;
                    >.item{
                        line-height: 1;
                        padding: 20rpx 10rpx;
                        border-bottom: 1rpx solid #f1f1f1;
                        text-align: center;
                        font-size: 13px;
                        color: #444;
                        &.hover{
                            background: #ddd;
                        }
                        &.active{
                            background: $primary-color;
                            color: #fff;
                        }


                        &.hidden{
                            height: 0 !important;
                            width: 0 !important;
                            overflow: hidden !important;
                            padding: 0 !important;
                            margin: 0 !important;
                        }
                        &.required{
                            color: $primary-color !important;
                        }
                    }
                }
                >.right{
                    width: calc(100% - 200rpx);    
                    height: calc(80vh - 80rpx);
                    overflow-x: hidden;
                    overflow-y: scroll;
                    >.item{
                        line-height: 1;
                        padding: 20rpx 20rpx;
                        border-bottom: 1rpx solid #f1f1f1;
                        font-size: 13px;
                        color: #444;
                        >.title{
                            font-size: 12px;
                            color: #666;
                            margin-bottom: 10rpx;
                        }

                        &.hidden{
                            height: 0 !important;
                            width: 0 !important;
                            overflow: hidden !important;
                            padding: 0 !important;
                            margin: 0 !important;
                        }
                        &.required{
                            >.title{
                                color: $primary-color !important;
                            }
                        }
                    }
                }
            }



            >.btn{
                position: absolute;
                bottom: 0;
                left: 0;
                right: 0;
                display: flex;
                border-top: 1rpx solid #ddd;
                >view{
                    width: 50%;
                    height: 80rpx;
                    text-align: center;
                    opacity: 0.9;
                    line-height: 80rpx;
                    
                    &.hover{
                        opacity: 1;
                    }
                    &.query{
                        background: $primary-color;
                        color: #fff;
                    }
                    &.reset{
                        background: #f3f3f3;
                    }
                }
            }
        }
        >.mark{
            width: 100vw;
            height: calc(100vh - 80rpx);
            background: rgba(0, 0, 0, 0.5);
            position: absolute;
            z-index: 1;
            top: 0;
            left: 0;
            right: 0;
        }
    }
    .popup-form_sort{
        position: absolute;
        top: 80rpx;
        left: 0;
        right: 0;
        z-index: 9;
        >.main-form_sort{
            background: #fff;
            height: 80vh;
            position: relative;
            z-index: 2;
            border-top: 1rpx solid #ddd;
            
            >.main{
                display: flex;
                width: 100vw;
                min-height: 100%;
                flex-wrap: wrap;
                align-content: baseline;
                >.li{
                    width: 100%;
                    height: 80rpx;
                    line-height: 80rpx;
                    box-sizing: border-box;
                    display: flex;
                    flex-shrink: 0;
                    justify-content: space-between;
                    padding: 0 40rpx;
                    border-bottom: 1rpx solid #ddd;
                    &.hover{
                        background: #eee;
                    }
                    >.name{
                        font-size: 24rpx;
                        color: #666;
                    }
                    >.right{
                        display: flex;
                        >.index{
                            border-radius: 50%;
                            width: 40rpx;
                            height: 40rpx;
                            line-height: 40rpx;
                            text-align: center;
                            background: #666;
                            color: #fff;
                            margin-right: 20rpx;
                            margin-top: 20rpx;
                            font-size: 20rpx;
                        }
                        >.type{
                            border-radius: 50%;
                            width: 60rpx;
                            height: 60rpx;
                            background: #007aff;
                            color: #fff;
                            margin-top: 10rpx;
                            text-align: center;
                            line-height: 60rpx;
                            font-size: 30rpx;
                        }
                    }
                }
            }



            >.btn{
                position: absolute;
                bottom: 0;
                left: 0;
                right: 0;
                display: flex;
                border-top: 1rpx solid #ddd;
                >view{
                    width: 100%;
                    height: 80rpx;
                    text-align: center;
                    opacity: 0.9;
                    line-height: 80rpx;
                    
                    &.hover{
                        opacity: 1;
                    }
                    &.query{
                        background: $primary-color;
                        color: #fff;
                    }
                    &.reset{
                        background: #f3f3f3;
                    }
                }
            }
        }
        >.mark{
            width: 100vw;
            height: calc(100vh - 80rpx);
            background: rgba(0, 0, 0, 0.5);
            position: absolute;
            z-index: 1;
            top: 0;
            left: 0;
            right: 0;
        }
    }
  }
  </style>
  