<template>
    <el-dialog
        draggable
        class="cn-operate-dialog statistical-type-binding"
        v-model="dialogVisible"
        title="绑定监测点"
        style="width: 1040px"
    >
        <el-scrollbar style="padding-right: 0" v-loading="loading">
            <div class="box">
                <div class="box-left">
                    <el-input v-model="filterText" placeholder="请输入内容" clearable>
                        <template #prefix>
                            <Icon name="el-icon-Search" style="font-size: 16px" />
                        </template>
                    </el-input>
                    <el-tree
                        ref="leftTree"
                        class="mt10"
                        style="width: 100%; height: calc(60vh - 140px); overflow-y: auto"
                        :props="props"
                        :data="fromDataValue"
                        default-expand-all
                        :default-expanded-keys="leftDefaultExpandedKeys"
                        show-checkbox
                        node-key="id"
                        :filter-node-method="filterNode"
                        @check="leftCheckChange"
                    />
                </div>
                <div class="box-center">
                    <el-button
                        style="margin-left: 0"
                        class="mt20"
                        type="primary"
                        icon="el-icon-ArrowRight"
                        @click="bind"
                        :disabled="fromData.length === 0"
                    >
                        绑定
                    </el-button>
                    <el-button
                        style="margin-left: 0"
                        icon="el-icon-ArrowLeft"
                        class="mt20"
                        type="primary"
                        @click="unbind"
                        :disabled="toData.length === 0"
                    >
                        解绑
                    </el-button>
                </div>
                <div class="box-right">
                    <el-input v-model="filterText1" placeholder="请输入内容" clearable>
                        <template #prefix>
                            <Icon name="el-icon-Search" style="font-size: 16px" />
                        </template>
                    </el-input>
                    <el-tree
                        ref="rightTree"
                        class="mt10"
                        style="width: 100%; height: calc(60vh - 140px); overflow-y: auto"
                        :props="props"
                        default-expand-all
                        :data="toDataValue"
                        :default-expanded-keys="rightDefaultExpandedKeys"
                        show-checkbox
                        node-key="id"
                        :filter-node-method="filterNode1"
                        @check="rightCheckChange"
                    />
                </div>
            </div>
        </el-scrollbar>

        <template #footer>
            <span class="dialog-footer">
                <el-button @click="dialogVisible = false">取消</el-button>
                <el-button type="primary" @click="submit">确认</el-button>
            </span>
        </template>
    </el-dialog>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue'
import { CascaderValue, ElMessage } from 'element-plus'
import { getDeptBindDeptLineTree } from '@/api/user-boot/terminalTree'
import { deptBindLine } from '@/api/user-boot/deptLine'

defineOptions({
    name: 'govern/setting/statisticalType/binding'
})
const pid = ref('')
const binData = reactive({
    deptId: '',
    deptType: '',
    id: '',
    type: 0
})
const dialogVisible = ref(false)
const loading = ref(false)
const leftTree = ref()
const rightTree = ref()
const fromData = ref<treeData[]>([])
const fromDataValue = ref<treeData[]>([])
const leftDefaultExpandedKeys = ref<string[]>([])
const toData = ref<treeData[]>([])
const toDataValue = ref<treeData[]>([])
const rightDefaultExpandedKeys = ref<string[]>([])
const props = {
    label: 'name',
    value: 'id',
    children: 'children'
}
const filterText = ref('')
const filterText1 = ref('')
const getExpandedKeys = (originArr: treeData[]) => {
    let arr: string[] = []
    const call = (originArr: treeData[]) => {
        originArr.forEach((item: treeData) => {
            if (item.level === 6) {
                arr.push(item.id as string)
            } else {
                call(item.children)
            }
        })
    }
    call(originArr)
    return arr
}
const init = () => {
    loading.value = true
    getDeptBindDeptLineTree(binData).then(res => {
        fromData.value = []
        fromDataValue.value = res.data[0]?.nothingBindTree || []
        toData.value = []
        toDataValue.value = res.data[0]?.myselfBindTree || []
        leftDefaultExpandedKeys.value = getExpandedKeys(fromDataValue.value)
        rightDefaultExpandedKeys.value = getExpandedKeys(toDataValue.value)
        loading.value = false
    })
}
// 左侧源数据选中事件
const leftCheckChange = (e: any) => {
    fromData.value = leftTree.value.getCheckedNodes().filter((item: any) => {
        return item.level === 6
    })
}
// 右侧目标数据选中事件
const rightCheckChange = (e: any) => {
    toData.value = rightTree.value.getCheckedNodes().filter((item: any) => {
        return item.level === 6
    })
}

// 定义一个函数来创建映射
const createMapping = (data: treeData[], key: 'pid' | 'id') => {
    const map = new Map<string, treeData[]>()
    data.forEach((item: treeData) => {
        const list = map.get(item[key]) || []
        list.push(item)
        map.set(item[key], list)
    })
    return map
}

// 定义一个函数来添加子节点
const addChildren = (data: treeData[], map: Map<string, treeData[]>) => {
    data.forEach((item: treeData) => {
        if (item.level === 3) {
            let children =
                map.get(item.id as string)?.filter((child: treeData) => {
                    return !item.children.find(child2 => (child.id as string) === child2.id)
                }) || []
            item.children.push(...children)
        } else {
            addChildren(item.children, map)
        }
    })
}

// 定义一个函数来过滤子节点
const filterChildren = (data: treeData[], map: Map<string, treeData[]>) => {
    data.forEach((item: treeData) => {
        if (item.level === 3) {
            const childrenIds = map.get(item.id as string)?.map(child => child.id as string) || []
            item.children = item.children.filter(child => !childrenIds.includes(child.id as string))
        } else {
            filterChildren(item.children, map)
        }
    })
}

const bind = () => {
    const map = createMapping(fromData.value, 'pid')
    filterChildren(fromDataValue.value, map)
    addChildren(toDataValue.value, map)
    rightDefaultExpandedKeys.value = getExpandedKeys(toDataValue.value)
    fromData.value = []
    leftTree.value.setCheckedKeys([])
}

const unbind = () => {
    const map = createMapping(toData.value, 'pid')
    filterChildren(toDataValue.value, map)
    addChildren(fromDataValue.value, map)
    toData.value = []
    rightTree.value.setCheckedKeys([])
    leftDefaultExpandedKeys.value = getExpandedKeys(fromDataValue.value)
}

const open = (row: any) => {
    filterText.value = ''
    filterText1.value = ''
    dialogVisible.value = true
    binData.deptId = row.id
    binData.deptType = row.type
    binData.id = row.area
    init()
}
const submit = async () => {
    deptBindLine({
        id: binData.deptId,
        ids: getExpandedKeys(toDataValue.value)
    }).then(() => {
        ElMessage.success('绑定成功')
        dialogVisible.value = false
    })
}
watch(filterText, val => {
    leftTree.value!.filter(val)
})
watch(filterText1, val => {
    rightTree.value!.filter(val)
})
const filterNode = (value: string, data: any, node: any) => {
    if (!value) return true
    // return data.name.includes(value)
    if (data.name) {
        return chooseNode(value, data, node)
    }
}
const filterNode1 = (value: string, data: any, node: any) => {
    if (!value) return true
    // return data.name.includes(value)
    if (data.name) {
        return chooseNode(value, data, node)
    }
}
// 过滤父节点 / 子节点 (如果输入的参数是父节点且能匹配，则返回该节点以及其下的所有子节点；如果参数是子节点，则返回该节点的父节点。name是中文字符，enName是英文字符.
const chooseNode = (value: string, data: any, node: any) => {
    if (data.name.indexOf(value) !== -1) {
        return true
    }
    const level = node.level
    // 如果传入的节点本身就是一级节点就不用校验了
    if (level === 1) {
        return false
    }
    // 先取当前节点的父节点
    let parentData = node.parent
    // 遍历当前节点的父节点
    let index = 0
    while (index < level - 1) {
        // 如果匹配到直接返回，此处name值是中文字符，enName是英文字符。判断匹配中英文过滤
        if (parentData.data.name.indexOf(value) !== -1) {
            return true
        }
        // 否则的话再往上一层做匹配
        parentData = parentData.parent
        index++
    }
    // 没匹配到返回false
    return false
}
defineExpose({ open })
</script>
<style lang="scss">
.statistical-type-binding-button-group {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-gap: 10px;
}

.statistical-type-binding {
    .box {
        display: flex;
        width: 1000px;
        height: calc(60vh - 95px);
        margin: 0 auto;
        text-align: left;

        .box-center {
            display: flex;
            align-items: center;
            width: 100px;
            padding-top: 20px;
            margin: 0 20px;
            flex-direction: column;
        }

        .box-right,
        .box-left {
            height: 100%;
            overflow-x: hidden;
            overflow-y: scroll;
            flex: 1;

            .el-cascader-menu {
                padding-right: 0;

                .el-scrollbar__wrap {
                    height: 100%;
                }
            }

            .el-cascader-panel {
                height: 100%;

                .el-cascader-menu__list {
                    height: 100% !important;
                }
            }
        }
    }
}
</style>
