<template>

          <el-radio-group v-model="radioKeys" @change="treeRadioChange">
            <ElTree class="hc-tree-node tree-line  el-radio-group" :class="ui" ref="ElTreeRef" :props="ElTreeProps" :load="ElTreeLoadNode" lazy highlight-current accordion node-key="id"
                    :default-expanded-keys="defaultExpandedCids" @node-click="ElTreeClick" @node-contextmenu="ElTreeLabelContextMenu2" :indent="0" >
                <template #default="{ node, data }">
                    <div class="data-custom-tree-node" :id="`${idPrefix}${data['id']}`">
                        <!--树组件，节点名称-->
                        <div class="label level-name" v-if="node.level === 1" >
                           <span> {{ node.label }}</span>
                        </div>
                        <div class="label" v-else>
                            <el-radio class="size-xl" :label="data['id']" @click.stop="clickRadio(data)" v-if="isRadio && showRadioFun(data)">{{ node.label }}</el-radio>
                            <span v-else>{{ node.label }}</span>
                        </div>
                         <div class="text-blue submit-counts" v-if="false">【{{ data.submitCounts ?? 0 }}】</div>
                        <!--没有传入菜单使用默认的-->
                        <div class="menu-icon1" :class="node.showTreeMenu?'show':''" v-if="isShowMenu">
                            <div class="cu-tree-node-popover-menu-icon" @click.prevent.stop="ElTreeLabelContextMenu2($event,data,node)">
                                <HcIcon name="apps" ui="text-2xl"/>
                            </div>
                        </div>
               
                    </div>
                </template>
            </ElTree>
          </el-radio-group>




    <!--右键菜单-->
    <HcContextMenu ref="contextMenuRef" :datas="menusData" @item-click="handleMenuSelect" v-if="menusData.length > 0" @closed="handleMenuClosed">
        <template #sort="{item}">
            <HcIcon :name="item.icon" :line="false" class="menu-item-icon"/>
            <span class="menu-item-name">{{item.label}}</span>
        </template>
    </HcContextMenu>

    <!--没有传入菜单使用默认的-->
    <HcContextMenu ref="contextMenuRef2" :datas="ElTreeMenu" @item-click="ElTreeMenuClick" v-if="menusData.length < 1" @closed="handleMenuClosed">
        <template #sort="{item}">
            <HcIcon :name="item.icon" :line="false" class="menu-item-icon"/>
            <span class="menu-item-name">{{item.label}}</span>
        </template>
    </HcContextMenu>

    <EditNodeDialog :projectId="projectId" :node="nodeItemInfo" :show="editDialogShow" :type="editDialogType" @hide="dialogHide"></EditNodeDialog>

    <SortNodeDialog :node="nodeItemInfo" :show="sortDialogShow" @hide="sortDialogHide"></SortNodeDialog>
</template>

<script setup>
import {ref,nextTick,watch} from "vue";
import {remove,syncProjectTree} from "~api/other";
import {getArchiveTreeLazyTree,initTree} from '~api/other';
import {isArrItem, getArrValue, getObjValue, isNullES} from "js-fast-way"
import EditNodeDialog from "~src/components/dialog/EditNodeDialog.vue"
import SortNodeDialog from "~src/components/dialog/SortNodeDialog.vue"
import {delMessage} from "~uti/tools";

//参数
const props = defineProps({
    ui: {
        type: String,
        default: ''
    },
    menus: {
        type: Array,
        default: () => ([])
    },
    projectId: {
        type: [String,Number],
        default: ''
    },
    contractId: {
        type: [String,Number],
        default: ''
    },
    autoExpandKeys: {
        type: Array,
        default: () => ([])
    },
    idPrefix: {
        type: String,
        default: 'hc-tree-'
    },
    isAutoKeys: {
        type: Boolean,
        default: true
    },
    isAutoClick: {
        type: Boolean,
        default: true
    },
    isRadio: {
        type: Boolean,
        default: false
    },
    radioKey: {
        type: String,
        default: ''
    },
    showRadioFun:{
        type:Function,
        default() {
            return true;
        }
    },
    isShowMenu:{
        type:Boolean,
        default:true//是否显示默认菜单
    },
  
})

//变量
const ElTreeRef = ref(null)
const treeRefNode = ref(null)
const treeRefData = ref(null)
const ElTreeProps = ref({
    label: 'title',
    children: 'children',
    isLeaf: 'isLeaf'
})
const menusData = ref(props.menus)
const isAutoKeys = ref(props.isAutoKeys)
const TreeExpandKey = ref(props.autoExpandKeys)
const projectId = ref(props.projectId);
const contractId = ref(props.contractId);
const idPrefix = ref(props.idPrefix);
const radioKeys = ref(Number(props.radioKey));

//监听
watch(() => [
    props.menus,
    props.isAutoKeys,
    props.autoExpandKeys,
    props.projectId,
    props.contractId,
    props.idPrefix,
    props.radioKey,
    
], ([menus, AutoKeys, expandKeys, UserProjectId, UserContractId, UserIdPrefix, radioKey]) => {
    menusData.value = menus
    isAutoKeys.value = AutoKeys
    TreeExpandKey.value = expandKeys
    projectId.value = UserProjectId
    contractId.value = UserContractId
    idPrefix.value = UserIdPrefix
    radioKeys.value = Number(radioKey)
})

//事件
const emit = defineEmits(['menuTap','nodeTap', 'nodeLoading', 'radioChange','noderadio'])

//单选框事件
const treeRadioChange = (val) => {
    emit('radioChange', val)
}

//树形结构异步加载数据
const defaultExpandedCids = ref([])
const ElTreeLoadNode = async (node, resolve) => {
    let parentId = 0;
    if (node.level !== 0) {
        const nodeData = getObjValue(node?.data);
        parentId = nodeData?.id || ''
    }
    //获取数据
    const {error, code, data} = await getArchiveTreeLazyTree({
        parentId,
        projectId:projectId.value,
        contractId:contractId.value
    })
    //处理数据
    if (!error && code === 200) {
        let clickKey = '', defaultExpandedArr = [];
        const keys = TreeExpandKey.value || []
        let resData = getArrValue(data)

        //如果是加载第一层，而且返回为空，先初始化树
        if(parentId === 0 && resData.length === 0){
            const {error:error2, code:code2, data:data2} = await initTree({
                projectId:projectId.value,
            })
            if (!error2 && code2 === 200) {
                resData = getArrValue(data2)
            }
        }

        for (let i = 0; i < resData.length; i++) {
            const item = resData[i];
            resData[i].isLeaf = !item.hasChildren
        }
        if (keys.length > 0) {
            let lastKey = keys[keys.length-1];
            for (const item of resData) {
                //自动展开
                if (isArrItem(keys,item?.id)) {
                    defaultExpandedArr.push(item?.id)
                }
                //最后一个，选中点击
                if (item?.id === lastKey) {
                    clickKey = item?.id
                }
            }
        } else if (node.level === 0) {
            defaultExpandedArr.push(resData[0]?.id)
        }
        //自动展开
        defaultExpandedCids.value = defaultExpandedArr
        if (node.level === 0) {
            emit('nodeLoading')
        }
        resolve(resData)
        //最后一个，执行点击
        if (props.isAutoClick && clickKey) {
            await nextTick(() => {
                document.getElementById(`${idPrefix.value}${clickKey}`)?.click()
            })
        }
    } else {
        if (node.level === 0) {
            emit('nodeLoading')
        }
        resolve([])
    }
}

//节点被点击
const ElTreeClick = async (data,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: []})
    }
}

//处理自动展开的节点KEY
const getNodeExpandKeys = async (node, newKeys) => {
    const parent = node?.parent ?? []
    const keyId = node?.data?.id ?? ''
    if (keyId) {
        newKeys.push(keyId)
        await getNodeExpandKeys(parent, newKeys)
    }
}

//鼠标右键事件
const contextMenuRef = 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 clickRadio=(data)=>{
    console.log(data,'data111');
    
    emit('noderadio', {data})
}
//鼠标右键菜单被点击
const handleMenuSelect = ({key}) => {
    const node = treeRefNode.value;
    const data = treeRefData.value;
    emit('menuTap', {key, node, data})
}

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

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


//鼠标右键事件2
const contextMenuRef2 = ref(null)
const ElTreeLabelContextMenu2 = (e,data,node) => {

    let rows = ElTreeMenu.value || [];
    if(node.level==1){
        rows=ElTreeMenu.value.filter((item)=>{
            if(item.key!=='sort'){
                return rows
            }
        })
        ElTreeMenu.value=rows
        console.log(rows,'row');
    }else{
        ElTreeMenu.value=[
            {icon: 'add-circle', label: '新增', key: "add"},
            {icon: 'draft', label: '编辑', key: "edit"},
            {icon: 'delete-bin', label: '删除', key: "del"},
            {icon: 'refresh', label: '同步', key: "sync"},
            {icon: 'sort-asc', label: '排序', key: "sort"}
        ]
    }
    
    if (rows.length > 0) {
        e.preventDefault();
        treeRefNode.value = node;
        treeRefData.value = data;
        node.showTreeMenu = true
        //展开菜单
        contextMenuRef2.value?.showMenu(e)
    }
}

//设置树菜单数据
const ElTreeMenu = ref([
    {icon: 'add-circle', label: '新增', key: "add"},
    {icon: 'draft', label: '编辑', key: "edit"},
    {icon: 'delete-bin', label: '删除', key: "del"},
    {icon: 'refresh', label: '同步', key: "sync"},
    {icon: 'sort-asc', label: '排序', key: "sort"}
])

//树菜单被点击
const nodeItemInfo = ref();
const ElTreeMenuClick = async ({key}) => {
    const node = treeRefNode.value;
    const data = treeRefData.value;
    nodeItemInfo.value = node
    // nodeDataInfo.value = data
    setTreeMenuDataClick({key,node,data})
}
//处理菜单被点击数据
const setTreeMenuDataClick = ({key,node,data}) => {
    //console.log(node)
    switch (key) {
        case 'add':
            addNode(node);
            break;
        case 'edit':
            editNodeModal(node);
            break;
        case 'del':
            delNodeMoadl(node);
            break;
        case 'sync':
            syncNodeMoadl(node);
            break;
        case 'sort':
            sortNodeMoadl(node,data);
            break;
    }
}

//新增编辑弹窗
const editDialogShow = ref(false);
const editDialogType = ref('add');
const addNode = ()=>{
    editDialogType.value = 'add';
    editDialogShow.value = true;
}
const editNodeModal = ()=>{
    editDialogType.value = 'edit';
    editDialogShow.value = true;
}
const dialogHide = ()=>{
    editDialogShow.value = false;
}

//排序弹窗
const sortDialogShow = ref(false);
const sortNodeMoadl = (node,data)=>{
    if(data?.isStorageNode===1){
        sortDialogShow.value = true;
    }else{
        window.$message.warning('非存储节点不允许排序')
    }
    
}
const sortDialogHide = ()=>{
    sortDialogShow.value = false;
}


//删除节点
const delNodeMoadl = (node)=>{
    delMessage(async() => {
        const {code } = await remove({
            id:node.data.id
        })
        if (code == 200) {
            window.$message?.success('删除成功')
            ElTreeRef.value.remove(node)
        }
    })
}

//同步节点
const syncNodeMoadl = (node)=>{
    window?.$messageBox?.alert('是否同步该节点？', '提示', {
        showCancelButton: true,
        confirmButtonText: '确认同步',
        cancelButtonText: '取消',
        callback: async(action) => {
            if (action === 'confirm') {
                const {code } = await syncProjectTree({
                    id:node.data.id
                })
                if (code == 200) {
                    window.$message?.success('同步成功')
                    window?.location?.reload()  //刷新页面
                }
            }
        }
    })
}

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

<style lang="scss" scoped>


@import "../../styles/app/tree.scss";
.el-radio-group {
    width: 100%;
}
.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 {
        background: hsla(0,0%,100%,.25);
        border-radius: 2px;
        display: inline-block;
        pointer-events: none;
        position: relative;
        right: -45px;
        transition: width .2s;
        vertical-align: bottom;
        width: 0;

        .cu-tree-node-popover-menu-icon {
            display: flex;
            align-items: center;
            justify-content: center;
        }
    }
    &:hover {
        .menu-icon1 {
            cursor: context-menu;
            pointer-events: all;
            right: 0;
            width: 24px;
        }
    }
    .menu-icon1.show {
        cursor: context-menu;
        pointer-events: all;
        right: 0;
        width: 24px;
    }
}
</style>
<style lang="scss">

.el-tree.hc-tree-node .el-tree-node {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    .el-tree-node_content {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
}
</style>