<template>
    <el-popover v-model:visible="visible"
                :width="300"
                placement="bottom"
                trigger="click">
        <template #reference>
            <el-icon
                slot="reference"
                class="setting">
                <Setting />
            </el-icon>
        </template>
        <infoForm
            :key="updateKey"
            :modelData="entity"
            :config="formConfig"
        >
            <template #divider>
                <el-divider />
            </template>
        </infoForm>
    </el-popover>
</template>
<script lang="ts">
import { Setting } from '@element-plus/icons-vue'
import infoForm from '../infoForm/infoForm.vue'
import {
    FormConfig
} from '../form'
import { defineComponent, reactive, ref, watch, PropType } from 'vue'
import { serverApi } from '../../script/serverApi'
import { ObjectInterface } from '../../script/util'
import tableApi from './model/api'

export default defineComponent({
    components: {
        infoForm,
        Setting
    },
    props: {
        columns: {
            type: Array as PropType<ObjectInterface[]>,
            default: () => []
        },
        options: { // table options
            type: Object,
            default: () => {
            }
        }
    },
    emits: ['setColumns'],
    setup (props, ctx) {
        const visible = ref(false)
        const updateKey = ref(0)
        const columnsGroup = reactive<ObjectInterface>({
            list: []
        })
        const headers = reactive<ObjectInterface>({
            list: []
        })
        const entity = reactive<ObjectInterface>({
            prop: []
        })
        const handlerShow = () => {
            entity.prop = headers.list
        }
        const setColumns = () => {
            headers.list = JSON.parse(JSON.stringify(entity.prop))
            ctx.emit('setColumns', entity.prop) // 通知表格过滤
        }
        const saveColumns = () => {
            let arr: string[] = []
            if (props.options?.isDymnicList) {
                arr = [...props.columns.filter((item: ObjectInterface) => {
                                return typeof item.show === 'function' ? !item.show() : false
                            }).map((column: ObjectInterface) => column.prop), ...entity.prop]
            } else {
                arr = entity.prop
            }
            const params = {
                name: location.pathname,
                tabId: location.pathname,
                headers: {
                    columns: arr
                }
            }
            serverApi({
                params,
                interface: props.options?.saveColumns || tableApi.saveColumns,
                success: () => {
                    setColumns()
                }
            })
        }
        const getColumns = () => {
            return new Promise((resolve, reject) => {
                serverApi({
                    params: { tabId: location.pathname },
                    interface: props.options?.getColumns || tableApi.getColumns,
                    success: (res: ObjectInterface) => {
                        const propArr = props.columns.filter((item: ObjectInterface) => {
                                    return typeof item.show === 'function' ? item.show() : true
                                }).map((column: ObjectInterface) => column.prop)
                        if (!res?.headers) {
                            if (props.options?.isDymnicList) {
                                entity.prop = propArr
                            } else {
                                // 无记录 默认展示所有
                                entity.prop = props.columns.map((column: ObjectInterface) => column.prop)
                            }
                        } else {
                            if (props.options?.isDymnicList) {
                                entity.prop = res.headers.columns.filter((item: ObjectInterface) => propArr.includes(item))
                            } else {
                                entity.prop = res.headers.columns
                            }
                        }
                        // 通知表格过滤
                        setColumns()
                        resolve(entity.prop)
                    }
                })  
            })
        }
        // 按照获取到的列顺序，对props.columns进行排序
        // checkbox 选项
        const getColumnsGroup = () => {
            // 判断是否有name或disabled
            const included = props.columns.findIndex(column => {
                return column.prop === 'name' || column.disabled
            })
            const columns = props.columns.filter((column: ObjectInterface) => {
                let show = typeof column.show === 'function' ? column.show() : true
                return show
            })

            const group = [] as any[]
            // 入库的
            entity.prop.forEach((item: string) => {
               const column = columns.find((column: ObjectInterface) => column.prop === item)
               if (column) {
                   group.push(column)
               } 
            })
            // 未入库保存的 调整位置
            const notHeaders = columns.filter((column: ObjectInterface) => {
                return !entity.prop.includes(column.prop) 
            }).forEach((column: ObjectInterface) => {
                const index = columns.findIndex((item: ObjectInterface) => item.prop === column.prop)
                group.splice(index, 0, column)
            })
            columnsGroup.list = group.map((column: ObjectInterface, index: number) => {
                return {
                    label: column.label,
                    value: column.prop,
                    disabled: () => included >= 0 ? (column.prop === 'name' || column.disabled) : index === 0
                }
            })
        }
        if (props.options.localHeaders) {
            entity.prop = props.columns.map((column: ObjectInterface) => column.prop)
            setColumns()
            getColumnsGroup()
        } else {
            getColumns().then(() => {
                getColumnsGroup()
            })
        }
        // getColumnsGroup()
        // !props.options.localHeaders && getColumns()
        const formConfig = new FormConfig({
            validate: {},
            labelWidth: '0',
            inline: false
        })
        formConfig.setRule({
            model: 'prop',
            type: 'infoCheckbox',
            inline: false,
            label: '',
            allElectionText: 'selectAll',
            allElection: true,
            checkbox: () => columnsGroup.list,
            methods: (val) => {
                // 排序
                entity.prop = columnsGroup.list.filter(item => val.includes(item.value)).map((item: ObjectInterface) => item.value)
            }
        })
        formConfig.setRule({
            type: 'infoSlot',
            slotName: 'divider',
            label: ''
        })
        formConfig.setRule({
            model: '',
            type: 'infoButton',
            label: '',
            operation: [
                {
                    show: () => true,
                    label: 'confirm',
                    type: 'primary',
                    methods: () => {
                        props.options.localHeaders ? setColumns() : saveColumns()
                        // 保存列信息
                        visible.value = false
                    }
                },
                {
                    show: () => true,
                    label: 'cancel',
                    methods: () => {
                        visible.value = false
                    }
                }
            ]
        })
        watch(props.columns, () => {
            getColumnsGroup()
        })
        watch(() => columnsGroup.list, () => {
            updateKey.value = Math.random()
        })
        return {
            formConfig,
            entity,
            headers,
            handlerShow,
            visible,
            columnsGroup,
            saveColumns,
            updateKey
        }
    }
})
</script>
<style lang="scss" scoped>
:deep(.info-form) {
    padding: 0;
    .info-checkbox {
        max-height: 380px;
        overflow-y: auto;
    }

    .el-divider {
        margin: 0;
    }
}

.setting {
    width: 16px;
    height: 16px;
    position: absolute;
    top: 19px;
}
</style>
