<template>
    <el-tree-v2
        ref="ElTreeRef"
        :class="[ui, submitCounts ? 'tree-line1' : '', isTreeShow ? 'is-tree-show': '']"
        :data="datas"
        :props="ElTreeProps"
        class="hc-tree-node-v2 tree-line  el-radio-group"
        :filter-method="filterMethod"
        :height="treeHeight"
        @node-click="ElTreeClick"
        accordion
        highlight-current
        :default-expand-all="false"
        node-key="primaryKeyId"
        :indent="24"
        @node-contextmenu="ElTreeLabelContextMenu"
        >
            <template #default="{ node, data }">
                <div  :id="`${idPrefix}${data['primaryKeyId']}`" class="data-custom-tree-node">
                    <!--树组件，节点名称-->
                    <div :class="node.level === 1?'level-name':''" class="label">
                        <span
                            v-if="(data['type'] > 0 && data['majorDataType'] > 0) || (data['type'] > 0 && data['majorDataType'] <= 0)"
                            class="hc-tree-node-type">{{
                                getTreeNodeType(data['type'], data['majorDataType'])
                            }}</span>
                        <span
                            v-if="isColor"
                            :class="data?.colorStatus === 2?'text-blue':data?.colorStatus === 3?'text-orange':data?.colorStatus === 4?'text-green':''">{{
                                node.label
                            }}</span>
                        <span v-else>{{ node.label }}</span>
                    </div>
                    <div v-if="isSubmitCounts" class="text-blue submit-counts">【{{ data.submitCounts ?? 0 }}】</div>
                    <!--树组件，操作菜单-->
                    <div v-if="node.level !== 1 && menusData.length > 0" :class="node.showTreeMenu?'show':''"
                        class="menu-icon1" @click.stop>
                        <div class="cu-tree-node-popover-menu-icon"
                            @click.prevent.stop="ElTreeLabelContextMenu($event,data,node)">
                            <HcIcon name="apps" ui="text-2xl"/>
                        </div>
                    </div>
                    <!--树组件，操作菜单 END-->
                </div>
            </template>
        </el-tree-v2>
         <!--右键菜单-->
    <HcContextMenu v-if="menusData.length > 0" ref="contextMenuRef" :datas="menusData" @closed="handleMenuClosed" @item-click="handleMenuSelect">
        <template #mark="{item}">
            <HcIcon :fill="treeRefData?.isFirst" :name="item.icon" class="menu-item-icon"/>
            <span class="menu-item-name">{{ treeRefData?.isFirst ? '取消标记为首件' : '标记为首件' }}</span>
        </template>
        <template #sort="{item}">
            <HcIcon :line="false" :name="item.icon" class="menu-item-icon"/>
            <span class="menu-item-name">{{ item.label }}</span>
        </template>
    </HcContextMenu>

</template>

<script setup>
import {ref, watch, nextTick, onMounted, onUnmounted} from "vue";
import {getTreeNodeType} from '~uti/utils';
import { ElTreeV2 } from 'z-element-plus'
import {isNullES} from "js-fast-way";

//参数
const props = defineProps({
    ui: {
        type: String,
        default: ''
    },
    isMark: {
        type: Boolean,
        default: false
    },
    menus: {
        type: Array,
        default: () => ([])
    },
    height: {
        type: [Number, String],
        default: 0
    },
    datas: {
        type: Array,
        default: () => ([])
    },
    submitCounts: {
        type: Boolean,
        default: false
    },
    searchTreeVal: {
        type: String,
        default: ''
    },
    ElTreeLoadNode: {
        type: Boolean,
        default: true
    },
    idPrefix: {
        type: String,
        default: 'tree-data-v2-'
    },
    isColor: {
        type: Boolean,
        default: false
    },
    isAutoKeys: {
        type: Boolean,
        default: true
    },
    isShow: {
        type: Boolean,
        default: false
    },
})

//变量
const ElTreeRef = ref(null)
const ElTreeProps = ref({
    value: 'primaryKeyId',
    label: 'title',
    children: 'children',
})
const treeHeight = ref(0)
const menuMark = ref(props.isMark)
const isSubmitCounts = ref(props.submitCounts);
const searchInfo = ref(props.searchTreeVal)
const idPrefix = ref(props.idPrefix);
const menusData = ref(props.menus)
const isAutoKeys = ref(props.isAutoKeys)
const treeRefData = ref(null)
const isTreeShow = ref(props.isShow)

//监听
watch(() => [
    props.height,
    props.submitCounts,
    props.idPrefix,
    props.menus,
    props.isAutoKeys,
    props.isMark,
    props.isShow,
], ([height, submitCounts,UserIdPrefix,menus,AutoKeys,isMark, isShow]) => {
    treeHeight.value = height
    isSubmitCounts.value = submitCounts
    idPrefix.value = UserIdPrefix
    menusData.value = menus
    isAutoKeys.value = AutoKeys
    menuMark.value = isMark
    isTreeShow.value = isShow
})

watch(() => [
    props.searchTreeVal,
], ([val]) => {
    searchInfo.value = val
    if (val) {
        nextTick(() => {
            ElTreeRef?.value.filter(val)
        })
    } else {
        emit('changeSearch')
    }
})


onMounted(() => {
    getOffsetHeight()
    windowResize()
})

//事件
const emit = defineEmits(['menuTap', 'nodeTap', 'changeSearch', 'changetreelaod'])

//节点被点击
//处理自动展开的节点KEY
const getNodeExpandKeys = async (node, newKeys) => {
    const parent = node?.parent ?? []
    const primaryKeyId = node?.data?.primaryKeyId ?? ''
    if (primaryKeyId) {
        newKeys.push(primaryKeyId)
        await getNodeExpandKeys(parent, newKeys)
    }
}
//节点被点击
const ElTreeClick = async (data, node) => {
    console.log(node)
    if (isAutoKeys.value) {
        let autoKeysArr = []
        await getNodeExpandKeys(node, autoKeysArr)
        const autoKeys = autoKeysArr.reverse()
        emit('nodeTap', {node, data, keys: autoKeys})
    } else {
        emit('nodeTap', {node, data, keys: []})
    }
}

const getReturnNode = (node, _array, value) => {
    let isPass = node.data && node.data.title && node.data.title.indexOf(value) !== -1;
    isPass ? _array.push(isPass) : '';
    if (!isPass && node.level != 1 && node.parent) {
        getReturnNode(node.parent, _array, value);
    }
}
//筛选树节点
const filterMethod = (query,data) => {
    if (!query) {
        return true;
    }
    let _array = [];//这里使用数组存储 只是为了存储值。
    let node=ElTreeRef?.value.getNode(data.primaryKeyId)
    getReturnNode(node, _array, query);
    let result = false;
    _array.forEach((item) => {
        result = result || item;
    });
    setTimeout(() => {
        emit('changetreelaod', false)
    }, 1000)
    return result;

}
//鼠标右键事件
const contextMenuRef = ref(null)
const treeRefNode = ref(null)
const ElTreeLabelContextMenu = (e, data, node) => {
    const rows = menusData.value || [];
    if (node.level !== 1 && rows.length > 0) {
        e.preventDefault();
        treeRefNode.value = node;
        treeRefData.value = data;
        node.showTreeMenu = true
        //展开菜单
        contextMenuRef.value?.showMenu(e)
    }
}
//鼠标右键菜单被点击
const handleMenuSelect = async ({key}) => {
    const node = treeRefNode.value;
    const data = treeRefData.value;
    //如果为标记菜单
    if (key === 'mark' && menuMark.value) {
        if (data.isFirst === true) {
            emit('menuTap', {key: 'cancel_mark', node, data})
        } else {
            emit('menuTap', {key: 'mark', node, data})
        }
    } else {
        // emit('menuTap', {key, node, data})
        if (isAutoKeys.value) {
            console.log(11111);
            let autoKeysArr = []
            await getNodeExpandKeys(node, autoKeysArr)
            const autoKeys = autoKeysArr.reverse()
            emit('menuTap', {key, node, data, keys: autoKeys})
        }
    }
}

const handleMenuClosed = () => {
    const node = treeRefNode.value;
    if (!isNullES(node)) {
        treeRefNode.value['showTreeMenu'] = false
    }
}


//设置树菜单的标记数据
const setElTreeMenuMark = (keys, isFirst) => {
    keys.forEach(item => {
        //根据 data 或者 key 拿到 Tree 组件中的 node
        let node = ElTreeRef.value.getNode(item)
        if (!!node) node.data.isFirst = isFirst;
    })
}
//设置树菜单的标记数据
const removeElTreeNode = (key) => {
    //根据 data 或者 key 拿到 Tree 组件中的 node
    let node = ElTreeRef.value.getNode(key)
    //删除 Tree 中的一个节点，使用此方法必须设置 node-key 属性
    ElTreeRef.value.remove(node)
}

//监听浏览器窗口变化
const windowResize = () => {
    window.addEventListener("resize", resizeEvent);
}

const resizeEvent = () => {
    window.requestAnimationFrame(() => {
        getOffsetHeight()
    })
}

const getOffsetHeight = () => {
    try {
        treeHeight.value = document.getElementById('hc-tree-scrollbar').offsetHeight;
    } catch {
        console.log('hc-tree-scrollbar 元素，不存在，获取高度失败')
    }
}

//被卸载
onUnmounted(() => {
    window.removeEventListener("resize", resizeEvent);
})

// 暴露出去
defineExpose({
    setElTreeMenuMark,
    removeElTreeNode,
    filterMethod
})
</script>

<style lang="scss" scoped>
//@import "../../../styles/app/tree.scss";
.el-radio-group {
    width: 100% !important;
    display: inline-grid;
}
.data-custom-tree-node {
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    .label {
        flex: 1;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .submit-counts {
        position: unset;
        font-size: 14px;
    }
    .menu-icon1 {
        position: relative;
        vertical-align: bottom;
        display: inline-block;
        width: 0;
        right: -45px;
        border-radius: 2px;
        pointer-events: none;
        background: rgba(255, 255, 255, 0.25);
        transition: width 0.2s;
        .cu-tree-node-popover-menu-icon {
            display: flex;
            align-items: center;
            justify-content: center;
        }
    }
    &:hover {
        .menu-icon1 {
            right: 0;
            width: 24px;
            pointer-events: all;
            cursor: context-menu;
        }
    }
    .menu-icon1.show {
        right: 0;
        width: 24px;
        pointer-events: all;
        cursor: context-menu;
    }
}
</style>
<style lang="scss">
.hc-tree-node-v2.el-tree {
    display: none;
    .el-tree-node {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        .el-tree-node_content {
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
    }
    &.is-tree-show {
        display: block;
    }
}
</style>
