<template>

    <Tree ref="treRef" @check="handleCheck" @check-change="handleCheckChange" :default-checked-keys="defaultCheckedKeys" check-strictly
        :show-checkbox="props.showCheckbox" :data="tree" :height="props.height" @changeDeviceType="changeDeviceType"
        @changeTreeType="loadTree" :engineering="props.engineering" />

</template>



<script lang="ts" setup>

import { ref, nextTick, onMounted } from 'vue'

import Tree from '../device.vue'

import { getLineTree } from '@/api/cs-device-boot/csLedger'

import { useConfig } from '@/stores/config'

import {

    createLineTreeDecorators,

    decorateLineTree,

    type LineTreeLeaves

} from './lineTreeUtils'



defineOptions({

    name: 'govern/analyzeTree'

})



const props = withDefaults(

    defineProps<{

        showCheckbox?: boolean

        defaultCheckedKeys?: any

        height?: number

        engineering?: boolean

    }>(),

    {

        showCheckbox: false,

        defaultCheckedKeys: () => [],

        height: 0,

        engineering: false

    }

)



const emit = defineEmits(['init', 'checkChange', 'check', 'deviceTypeChange'])



const config = useConfig()

const tree = ref<any[]>([])

const treRef = ref<InstanceType<typeof Tree>>()



const decorators = createLineTreeDecorators(() => config.getColorVal('elementUiPrimary'))



const changeDeviceType = (val: any, obj: any) => {

    emit('deviceTypeChange', val, obj)

}



type TreeRefKey = 'treeRef1' | 'treeRef2' | 'treeRef3' | 'treeRef4'



async function waitForTreeRef(refKey: TreeRefKey, maxRetries = 20) {

    for (let i = 0; i < maxRetries; i++) {

        await nextTick()

        if (treRef.value?.[refKey]) return treRef.value[refKey]

        await new Promise(resolve => setTimeout(resolve, 50))

    }

    return null

}



async function selectInitialNode(

    type: string | undefined,

    leaves: LineTreeLeaves

) {

    const candidates: { refKey: TreeRefKey; list: any[]; level: number }[] =

        type === '2'

            ? [{ refKey: 'treeRef4', list: leaves.engineering, level: 3 }]

            : [

                { refKey: 'treeRef1', list: leaves.govern, level: 2 },

                { refKey: 'treeRef2', list: leaves.portable, level: 2 },

                { refKey: 'treeRef3', list: leaves.monitor, level: 2 }

            ]



    for (const { refKey, list, level } of candidates) {

        const node = list[0]

        if (!node) continue



        const treeInstance = await waitForTreeRef(refKey)

        treeInstance?.setCurrentKey(node.id)

        emit('init', { ...node })

        return

    }



    emit('init')

}



const loadTree = (type?: string) => {

    getLineTree({ type: type === '2' ? 'engineering' : '' }).then(res => {

        const leaves = decorateLineTree(res.data, type, decorators)

        tree.value = res.data

        selectInitialNode(type, leaves)

    })

}



onMounted(() => {

    loadTree(props.engineering ? '2' : '1')

})



const handleCheck = (data: any, state: any) => {
    emit('check', data, state)
}

const handleCheckChange = (data: any, checked: any, indeterminate: any) => {
    emit('checkChange', { data, checked, indeterminate })
}



defineExpose({ treRef })

</script>
