<template>
    <el-popover v-model:visible="visible"
                placement="bottom"
                trigger="click"
                :popper-class="column.prop"
                width="auto"
                @show="handlerShow"
                @hide="handlerHide">
        <template v-slot:reference >
           <div
                class="column-filter-style"
                @click.stop
            >
                <img
                    v-if="tempValue.value.length > 0"
                    src="../../assets/images/columnfilter-active.png"
                >
                <img
                    v-else
                    src="../../assets/images/columnfilter.png"
                >
           </div>
        </template>
        <infoForm
            ref="infoFormRef"
            :modelData="entity"
            :config="config"
        >
            <template #numberRange>
                <div class="info-number-range">
                    <el-form-item
                        prop="model[0]"
                        :rules="[
                            { validator: validate, trigger: 'change' }
                        ]"
                    >
                        <el-input
                            v-model="tempValue.range.min"
                            :placeholder="$t('minValue')"
                        />
                    </el-form-item>
                    <span>-</span>
                    <el-form-item
                        prop="model[1]"
                        :rules="[
                            { validator: validate, trigger: 'change' }
                        ]"
                    >
                        <el-input
                            v-model="tempValue.range.max"
                            :placeholder="$t('maxValue')"
                        />
                    </el-form-item>
                </div>
            </template>
            <template #divider>
                <el-divider />
            </template>
        </infoForm>
    </el-popover>
</template>
<script lang="ts">
import { ArrowDown, ArrowUp } from '@element-plus/icons-vue'
import infoForm from '../infoForm/infoForm.vue'
import { FormConfig } from '../form'
import { __getItem, __setItem } from '../../script/index'
import { defineComponent, reactive, ref, computed, watch, onBeforeMount } from 'vue'

interface entityInterface {
    label: string[]
    model: string[] | number[]
    oper: string
}

export default defineComponent({
    components: {
        infoForm,
        ArrowDown,
        ArrowUp
    },
    props: {
        column: {
            type: Object,
            default: () => {
            }
        },
        parameter: {
            type: Object,
            default: () => {
                return {}
            }
        },
        tableOptions: {
            type: Object,
            default: () => {
            }
        }
    },
    setup (props) {
        let { column } = props
        let targetParameter = reactive({})
        let visible = ref<boolean>(false)
        let entity: entityInterface = reactive({
            label: [],
            model: [],
            oper: 'BETWEEN' // IN
        })
        let tempValue = reactive({
            value: [] as any[],
            range: { min: '', max: '' }
        })
        const infoFormRef = ref()
        
        const showFormItem = computed(() => {
            let type = 'infoNumberRange'
            if (column.type === 'enum') {
                type = 'infoCheckbox'
            } else if (column.type === 'date') {
                type = 'infoDatePicker'
            }
            return type
        })

        const options = computed(() => {
            let formatOptions = column.options?.()
            if (column.optionsLabel || column.optionsValue) {
                formatOptions = formatOptions.map(item => {
                    return {
                        label: item[column.optionsLabel || 'label'],
                        value: item[column.optionsValue || 'value']
                    }
                })
            }
            return formatOptions
        })

        const parameterValue = computed(() => {
            const current = props.parameter?.[column.prop]
            return current?.model || []
        })
        // const parameterValue = ref()
        watch(() => parameterValue.value, (nv) => { // paramList删除清空parameter改变
            if (nv) {
                entity.model = nv as []
                tempValue.value = entity.model
            }
        }, { immediate: true })

        onBeforeMount(() => {
            const routeBase = (window as any).router?.options.history.base
            const routeName = routeBase + (window as any).route?.fullPath
            // 获取缓存参数
            const value = __getItem('myVuex', 'localStorage')
            const saveParameter = value?.saveCurrentData.saveCurrentData[routeName]
            if (saveParameter) {
                Object.assign(targetParameter, props.parameter, saveParameter)
                // parameterValue.value = targetParameter[column.prop]?.model
            }
        })

        let setDatepickerValue:Function
        let formConfig = new FormConfig({
            validate: {},
            labelWidth: '0'
        })
        // 枚举enum
        formConfig.setRule({
            label: '',
            model: 'model',
            type: 'infoCheckbox',
            inline: false,
            allElection: false,
            show: () => showFormItem.value === 'infoCheckbox',
            checkbox: () => options,
            methods: (val) => {
                const labels = options.value.filter(item => val.includes(item.value)).map(item => {
                    return item.label
                })
                entity.label = labels
            }
        })
        // 日期date
        formConfig.setDatePickerRule({
            label: '',
            type: 'infoDatePicker',
            valueFormat: () => 'x',
            model: 'model',
            teleported: false,
            show: () => showFormItem.value === 'infoDatePicker',
            initMethods: true,
            methods: (val, fn) => {
                fn && (setDatepickerValue = fn)
            }
        })
        // 区间number
        formConfig.setRule({
            label: '',
            type: 'infoSlot',
            slotName: 'numberRange',
            show: () => showFormItem.value === 'infoNumberRange'
        })

        formConfig.setRule({
            label: '',
            type: 'infoSlot',
            model: 'divider',
            slotName: 'divider'
        })
        formConfig.setRule({
            model: 'operation.button',
            type: 'infoButton',
            label: '',
            style: {
                float: 'right'
            },
            operation: [{
                show: () => true,
                label: 'confirm',
                type: 'primary',
                methods: () => {
                    infoFormRef.value.validate((valid) => {
                        if (!valid) return
                        if (showFormItem.value === 'infoNumberRange') {
                            entity.model = []
                            const { min, max } = tempValue.range // ['', '']
                            if (min && max) {
                                entity.model = [min, max]
                            }
                        } else if (showFormItem.value === 'infoCheckbox') {
                            entity.oper = 'IN'
                        }
                        tempValue.value = entity.model
                        column.filterMethod(entity, column, handleQuery)
                        visible.value = false
                    })
                }
            }, {
                show: () => true,
                label: 'reset',
                methods: () => {
                    const isFirst = tempValue.value.length === 0
                    tempValue.range = {
                        min: '',
                        max: ''
                    }
                    tempValue.value = []
                    entity.model = tempValue.value
                    setDatepickerValue?.()
                    !isFirst && column.filterMethod(entity, column, handleQuery)
                }
            }]
        })
        
        const handleQuery = (parameter, query) => {
            parameter[column.prop] = entity
            query() // 执行传入的查询方法
            visible.value = false
        }
        const handlerShow = () => {
            entity.model = tempValue.value
            setDatepickerValue?.()
        }
        const handlerHide = () => {
            // props.column.highlight = tempChecked.length > 0
        }
        const validate = (rule, value, callback) => {
            if (showFormItem.value === 'infoNumberRange') {
                const { min, max } = tempValue.range
                if (min === '' && max === '') {
                    return callback()
                }
                const minValue = Number(min)
                const maxValue = Number(max)
                const isMinField = rule.field === 'model[0]'
                const isMaxField = rule.field === 'model[1]'
                const isMinInvalid = isNaN(minValue) || min === ''
                const isMaxInvalid = isNaN(maxValue) || max === ''
                const isRangeInvalid = !isMinInvalid && !isMaxInvalid && minValue > maxValue // 合法值的比较

                if ((isMinField && isMinInvalid) || (isMaxField && isMaxInvalid) || isRangeInvalid) {
                    return callback(new Error(' '))
                }
            }
            callback()
        }
        return { visible, entity, tempValue, config: reactive(formConfig), handlerShow, handlerHide, validate, infoFormRef }
    }
})
</script>
<style lang="scss" scoped>
.wrap {
    padding-left: 0;
}

:deep(.info-form) {
    .el-divider {
        margin: 0;
    }

    .el-form-item {
        margin-bottom: 5px;
    }
    
    .info-checkbox {
        width: 100%;
        max-height: 220px;
        overflow: auto;
    }
    
    .info-number-range {
        width: 270px;
        display: flex;
        > span {
            padding: 0 8px;
        }
    }
}

.column-filter-style {
    display: inline-block;
    img {
        width: 20px;
        height: 20px;
        vertical-align: middle;
    }
}
.column-filter-style:hover {
    background: #C9cdd4;
}
</style>
