<!--suppress ALL -->
<template>
    <infoDialog
        class="info-resource"
        :options="optionsDialog"
        @closeDialog="closeDialog"
        @confirmDialog="confirmDialog"
    >
        <info-container
            :layout="{
                aside: propsConfig.isShowTree !== false,
                subContainerClass: 'sub-container'
            }"
        >
            <template #aside>
                <el-scrollbar
                    style="height: 53vh"
                >
                    <info-tree
                        ref="treeRef"
                        v-loading="treeLoading.isLoading"
                        class="tree-ref"
                        :data-tree="dataTree.data"
                        :isShowFilterText="() => true"
                        @treeCurrentData="treeCurrentData"
                    />
                    <slot name="custom-aside" />
                </el-scrollbar>
            </template>
            <template
                v-if="propsConfig.isShowTable !== false"
                #header
            >
                <info-operation-panel>
                    <!--筛选条件-->
                    <template #left>
                    <info-form
                        :config="headConfig"
                        :modelData="parameter"
                    />
                    </template>
                </info-operation-panel>
            </template>
            <template
                v-if="propsConfig.isShowTable !== false"
                #main
            >
                <info-table
                    ref="infoTableRef"
                    v-loading="treeLoading.isLoading"
                    :columns="columns"
                    :list="list"
                    :options="options"
                    :operates="operates.data"
                    @handleRowClick="handleCurrentChange"
                    @handleCurrentChange="handleCurrentChange"
                    @handleRowDblclick="handleRowDblclick"
                    @handleSelectionChange="handleSelectionChange"
                />
            </template>
            <template
                v-if="propsConfig.isShowTable !== false"
                #footer
            >
                <info-pagination
                    :state-flag="false"
                    :parameter="parameter"
                    :totalNumber="total"
                    :pagerCount="4"
                    @changeTableData="changeTableData"
                />
            </template>
        </info-container>
        <template #footer>
            <slot name="footer" />
        </template>
    </infoDialog>
    <!-- 数据集预览 -->
    <previewDataset
        ref="previewRef"
        :schemaColumnsSort="schemaColumnsSort"
    />
</template>

<script lang="ts">

import { defineComponent, nextTick, onMounted, PropType, reactive, ref } from 'vue'
import { DataTreeInterface, ParameterInterface, resourceInterface } from './index'
import configMap from './types'
import treeApi from './api/tree/tree'
import tableTree from './api/table/table'
import { ElMessage } from 'element-plus'
import $ from 'jquery'
import infoDialog from '../../components/infoDialog/index.vue'
import infoTree from '../../components/infoTree/customTree.vue'
import infoOperationPanel from '../../components/infoOperationPanel/index.vue'
import infoTable from '../../components/table/table.vue'
import infoPagination from '../../components/table/pagination.vue'
import infoForm from '../../components/infoForm/infoForm.vue'
import { FormConfig } from '../../components/form/formConfig'
import { OperatesInterface, ColumnsInterface } from '../../components/table/model/table'
import { requestPayload, ObjectInterface, isPromise, serverApi } from '../../script/index'
import infoContainer from '../../components/layout/infoContainer.vue'
import { checkType, InputInterface } from '../../components/form/index'
import previewDataset from './previewDataset/index.vue'

export default defineComponent({
    name: 'InfoResource',
    components: {
        infoDialog,
        infoContainer,
        infoTree,
        infoOperationPanel,
        infoForm,
        infoTable,
        infoPagination,
        previewDataset
    },
    props: {
        config: {
            type: Object as PropType<resourceInterface>,
            default: {}
        },
        columns: {
            type: Array as PropType<ColumnsInterface[]>,
            default: () => []
        },
        selected: {
            type: Array, // ids
            default: []
        },
        isFilter: { // 已废弃
            type: Boolean,
            default: false
        },
        // eslint-disable-next-line
        dataFilter: [Function] // 处理树数据的回调
    },
    emits: ['handleSelectionChange', 'treeCurrentData'],
    setup (props, context) {
        const propsConfig = reactive(props.config) // 根据类型配置的参数
        const splitType = ref<string | undefined>('')
        const optionsDialog = reactive({
            isShowDialog: false,
            isShowBtn: true,
            title: ref(''),
            width: '70%'
        })
        const treeRef = ref()
        const dataTree = reactive<DataTreeInterface>({ data: [] }) // 树的数据
        const treeLoading = reactive({ isLoading: false })
        const headConfig = new FormConfig({
            labelWidth: '80px',
            labelPosition: 'right',
            inline: true
        }) // 筛选条件
        headConfig.setRule(checkType<InputInterface>({
            type: 'infoInput',
            label: '',
            model: 'name.model',
            placeholder: () => 'pleaseEnterContent',
            button: {
                show: true,
                disabled: () => false,
                methods: (data: string) => {
                    queryTableData()
                }
            }
        }))
        let parameter: ParameterInterface = reactive({
            pageSize: 20,
            pageNum: 1,
            name: {
                oper: 'LIKE',
                model: ''
            },
            parentId: {
                oper: 'EQUAL',
                model: ''
            }
        })
        const columns = ref([]) // 列
        const schemaColumnsSort = ref({})
        const options = reactive({
            // i18n: true,
            index: true,
            isHideSet: true,
            showHeader: true,
            tooltip: true,
            height: '370px',
            rowKey: 'id',
            loading: { isLoading: false },
            multiple: !!props.config?.multiple,
            treeProps: { hasChildren: 'hasChildren', children: 'children111' },
            localHeaders: true,
            reserveSelection: props.config?.reserveSelection,
            chooseOne: props.config?.chooseOne,
            selectable: props.config.selectable
        })
        const infoTableRef = ref()
        let list = ref([])
        let total = ref<number>(0)
        let operates = reactive({
            data: checkType<OperatesInterface>({
                isHiddenOperates: true,
                width: 220,
                // i18n: true,
                showNumber: true,
                list: []
            })
        })

        let currentRow: ObjectInterface = reactive({})
        let nodeData: ObjectInterface = reactive({})
        let selectData: ObjectInterface[] = reactive([])
        const getTreeData = () => {
            let params = {
                allUser: true,
                excludes: '',
                includes: propsConfig.type ? (configMap['treeInterface'][(propsConfig.type as string)] || propsConfig.type) : undefined,
                strict: true,
                 ...(propsConfig.treeParams?.() || {} )
            }
            serverApi({
                params: params,
                loading: treeLoading,
                interface: propsConfig.treeApi || treeApi.treeApi,
                success: (data: ObjectInterface[]) => {
                    if (props.dataFilter) {
                        const value = props.dataFilter(data)
                        if (isPromise(value)) {
                            value.then(res => {
                                dataTree.data = res
                            })
                        } else {
                            dataTree.data = value
                        }
                    } else {
                        dataTree.data = data
                    }
                    dataTree.data[0] && treeRef.value?.setCurrent(dataTree.data[0])
                }
            })
        }
        const queryTableData = () => {
            if (propsConfig.isShowTable === false || (propsConfig.isShowTree !== false && dataTree.data.length === 0)) {
                return false
            }
            Object.assign(parameter, (props.config.parameter ? props.config.parameter : {}))
            /**
             * 1. formatFn 优先使用传入的参数构建方法buildParameter/requestPayload 已废弃
             * 2. dataTableApi 仅传入接口 默认使用buildParameter
             * 3. tableInterface 默认
             * 4. params 已经构建好的参数 不需要再做处理
             */
            const type = typeof propsConfig.type === 'function' ? propsConfig.type() : propsConfig.type
            let params = propsConfig.dataTableApi ?
                (propsConfig.params ? propsConfig.params(parameter) : requestPayload(parameter as any)) :
                { params: requestPayload(parameter as any), type: configMap['tableInterface'][type] }
                // 自定义 | 默认
            if (propsConfig.other) {
                Object.assign(params.params, propsConfig.other)
            }
            serverApi({
                params: params,
                loading: options.loading,
                interface: propsConfig.dataTableApi || tableTree.dataTable,
                success: (data: ObjectInterface) => {
                    propsConfig.tableCallback?.(data)
                    list.value = data.content || data.list
                    total.value = data.totalCount
                    makeSelection()
                }
            })
        }
        const treeCurrentData = (data: ObjectInterface, isClick: Boolean) => {
            if (props.config.parameter?.resourceId !== undefined) {
                // eslint-disable-next-line vue/no-mutating-props
                props.config.parameter.resourceId = data.id
            } else {
                parameter.parentId.model = data.id
            }
            nodeData = data
            context.emit('treeCurrentData', data)
            // isClick &&
            list.value.splice(0)
            total.value = 0
            queryTableData()
        }
        const previewRef = ref()

        const isInit = ref(true)
        const init = (type: string) => {
            parameter.name.model = ''
            selectData.length = 0
            propsConfig.type = type || 'datasource'
            options.multiple = !!props.config?.multiple || !!props.config?.mutiSelect // mutiSelect 已废弃
            options.reserveSelection = props.config?.reserveSelection
            options.chooseOne = !!props.config?.chooseOne
            options.selectable = props.config?.selectable
            options.rowKey = propsConfig.rowKey || 'id'
            columns.value = props.columns?.length ? props.columns : configMap['column']([propsConfig.type]) // 获取列数据
            if (propsConfig.type === 'dataset') { // 数据集预览
                operates.data = {
                    isHiddenOperates: false,
                    width: 100,
                    fixed: 'right',
                    // i18n: true,
                    list: [
                        {
                            label: 'preview',
                            type: 'primary',
                            text: true,
                            plain: true,
                            method: (index: number, row: ObjectInterface) => {
                                /* let param = {
                                    id: row.id,
                                    name: row.name,
                                    schemaId: row.schemaId
                                } */
                                schemaColumnsSort.value = row?.schema || {}
                                previewRef.value.previewinit(row)
                            }
                        }
                    ]
                }
            }
            optionsDialog.width = propsConfig.width || (propsConfig.isShowTree === false || propsConfig.isShowTable === false) ? '50%' : '70%'
            optionsDialog.title = propsConfig.title || configMap['title'][propsConfig.type] // 获取title
            propsConfig.isShowTree !== false && getTreeData()
            isInit.value = true
            optionsDialog.isShowDialog = true
        } // 显示弹窗

        const closeDialog = () => {
            optionsDialog.isShowDialog = false
            currentRow.value = {}
            Object.assign(parameter, {
                pageSize: 20,
                pageNum: 1,
                name: {
                    oper: 'LIKE',
                    model: ''
                },
                parentId: {
                    oper: 'EQUAL',
                    model: ''
                }
            })
        }// 关闭按钮

        // 同步已选择数据
        const makeSelection = () => {
            if (props.selected?.length > 0) {
                const selected = list.value.filter((item) => {
                    return props.selected.includes(item[options.rowKey])
                })
                // setTimeout(toggleSelection.bind(context, selected))
                toggleSelection(selected)
                isInit.value = false
            }
        }
        // 设置勾选
        const toggleSelection = (rows) => {
            infoTableRef.value.toggleSelection(rows)
        }

        const handleRowDblclick = (data: any) => {
            // 如果是多选不支持单选
            if (options.multiple) {
                return false
            }
            context.emit('handleSelectionChange', data)
            closeDialog()
        }// 双击关闭弹框返回数据

        const handleCurrentChange = (data: ObjectInterface) => {
            currentRow.value = data
        }// 单击

        const changeTableData = (data: ObjectInterface, isClick?: boolean) => {
            (isClick || propsConfig.isShowTree === false) && queryTableData()
        }// 分页修改

        const handleSelectionChange = (data: ObjectInterface[]) => {
            selectData = data
        } // 选中修改
        const onMouseDown = (event: any) => {
            splitType.value = $(event.currentTarget).attr('data-type')
        }
        const confirmDialog = () => {
            if (propsConfig.isShowTable === false) {
                context.emit('handleSelectionChange', nodeData)
            } else {
                // 如果是多选,不支持单选
                if (options.multiple) {
                    if (props.config.reserveSelection) {
                        selectData = infoTableRef.value.multipleTable.getSelectionRows()
                    }
                    if (!selectData.length) {
                        // 提示错误
                        ElMessage.error($t('pleaseSelectAtLeastOneData'))
                        return false
                    }
                    context.emit('handleSelectionChange', selectData)
                    closeDialog()
                    return false
                }
                // 显示table的时候一定要选一条数据
                if (!!propsConfig.isShowTable !== false && !currentRow.value) {
                    ElMessage.error($t('pleaseSelectAtLeastOneData'))
                    // 提示错误
                    return false
                }
                context.emit('handleSelectionChange', currentRow.value) // 单击-确定
            }
            closeDialog()
        }// 确认按钮

        onMounted(() => {
            nextTick(() => {
            })
        })
        return {
            optionsDialog,
            propsConfig,
            dataTree,
            treeLoading,
            headConfig,
            parameter,
            columns,
            options,
            list,
            total,
            splitType,
            operates,
            currentRow,
            selectData,
            nodeData,
            treeRef,
            previewRef,
            infoTableRef,
            schemaColumnsSort,
            treeCurrentData,
            queryTableData,
            getTreeData,
            handleCurrentChange,
            handleRowDblclick,
            handleSelectionChange,
            changeTableData,
            init,
            closeDialog,
            confirmDialog,
            toggleSelection,
            onMouseDown
        }
    }
})
</script>

<style lang="scss" scoped>
.tree-aside {
    height: 100%;
    width: 220px;
    .tree-ref {
        height: calc(53vh);
    }
}
</style>
