<template>
    <section class="card steady-tree-card" :class="{ 'is-collapsed': collapsed }">
        <div v-show="collapsed" class="collapsed-panel">
            <el-tooltip content="展开设备树" placement="right">
                <el-button class="panel-toggle" type="primary" :icon="ArrowRight" circle @click="emit('toggle')" />
            </el-tooltip>
        </div>

        <div v-show="!collapsed" class="expanded-panel">
            <div class="panel-header">
                <span class="panel-title">设备树</span>
                <el-tooltip content="收缩设备树" placement="top">
                    <el-button class="panel-toggle" type="primary" :icon="ArrowLeft" circle @click="emit('toggle')" />
                </el-tooltip>
            </div>

            <div class="tree-search-row">
                <el-input
                    :model-value="keyword"
                    clearable
                    placeholder="搜索工程、项目、设备、监测点"
                    @update:model-value="handleKeywordChange"
                ></el-input>
                <el-button :icon="Refresh" circle :loading="loading" @click="emit('refresh')" />
            </div>

            <el-scrollbar class="tree-scrollbar">
                <el-tree
                    ref="treeRef"
                    class="ledger-tree"
                    :data="treeData"
                    node-key="id"
                    show-checkbox
                    default-expand-all
                    :default-checked-keys="defaultCheckedKeys"
                    :expand-on-click-node="false"
                    :props="{ label: 'name', children: 'children' }"
                    @check="handleCheck"
                >
                    <template #default="{ data }">
                        <div class="tree-node">
                            <span class="node-main">
                                <el-icon :class="['node-icon', `is-level-${normalizeLedgerLevel(data.level)}`]">
                                    <component :is="resolveLedgerIcon(data.level)" />
                                </el-icon>
                                <span class="node-name">{{ data.name }}</span>
                            </span>
                            <span class="node-count">
                                <template v-if="shouldShowLedgerCount(data)">
                                    {{ resolveLedgerCountText(data) }}
                                </template>
                            </span>
                        </div>
                    </template>
                </el-tree>
            </el-scrollbar>
        </div>
    </section>
</template>

<script setup lang="ts">
import { nextTick, ref, watch } from 'vue'
import type { Component } from 'vue'
import { ArrowLeft, ArrowRight, Folder, Location, Monitor, OfficeBuilding, Refresh } from '@element-plus/icons-vue'
import type { TreeInstance } from 'element-plus'
import type { SteadyTrend } from '@/api/steady/steadyTrend/interface'

defineOptions({
    name: 'SteadyLedgerTree'
})

const props = defineProps<{
    treeData: SteadyTrend.SteadyLedgerNode[]
    loading: boolean
    keyword: string
    defaultCheckedKeys: string[]
    collapsed: boolean
}>()

const emit = defineEmits<{
    refresh: []
    search: [value: string]
    change: [nodes: SteadyTrend.SteadyLedgerNode[]]
    toggle: []
}>()

const treeRef = ref<TreeInstance>()
type LedgerLevel = SteadyTrend.SteadyLedgerNode['level']
const ledgerIcons: Record<LedgerLevel, Component> = {
    0: OfficeBuilding,
    1: Folder,
    2: Monitor,
    3: Location
}

const normalizeLedgerLevel = (value: unknown): LedgerLevel => {
    const level = Number(value)
    if (level === 0 || level === 1 || level === 2 || level === 3) {
        return level
    }

    return 0
}

const resolveLedgerIcon = (value: unknown) => {
    return ledgerIcons[normalizeLedgerLevel(value)]
}

const shouldShowLedgerCount = (data: SteadyTrend.SteadyLedgerNode) => {
    return Number(data.level) < 3 && (Number(data.deviceCount) > 0 || Number(data.lineCount) > 0)
}

const resolveLedgerCountText = (data: SteadyTrend.SteadyLedgerNode) => {
    if (normalizeLedgerLevel(data.level) === 2) {
        return String(Number(data.lineCount || 0))
    }

    return `${Number(data.deviceCount || 0)} / ${Number(data.lineCount || 0)}`
}

const handleKeywordChange = (value: string) => {
    emit('search', value)
}

const handleCheck = () => {
    emit('change', (treeRef.value?.getCheckedNodes(false, false) || []) as SteadyTrend.SteadyLedgerNode[])
}

const applyDefaultCheckedKeys = async () => {
    await nextTick()
    treeRef.value?.setCheckedKeys(props.defaultCheckedKeys, false)
}

watch(
    () => [props.treeData, props.defaultCheckedKeys],
    () => {
        applyDefaultCheckedKeys()
    },
    { immediate: true }
)
</script>

<style scoped lang="scss">
.steady-tree-card {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-height: 0;
    padding: 12px;
}

.steady-tree-card:not(.is-collapsed) {
    height: 100%;
}

.steady-tree-card.is-collapsed {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 4;
    align-items: center;
    width: 36px;
    height: 36px;
    min-height: 36px;
    padding: 0;
    overflow: visible;
    background: transparent;
    border: none;
    box-shadow: none;
}

.collapsed-panel,
.expanded-panel {
    min-height: 0;
}

.collapsed-panel {
    display: flex;
    width: 36px;
    height: 36px;
    align-items: center;
    justify-content: center;
}

.expanded-panel {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 10px;
}

.panel-header,
.tree-node {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.panel-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--el-text-color-primary);
}

.panel-toggle {
    flex: none;
}

.tree-search-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.tree-search-row :deep(.el-input) {
    flex: 1 1 0;
    min-width: 0;
}

.tree-scrollbar {
    flex: 1;
    min-height: 0;
}

.tree-node {
    width: 100%;
    min-width: 0;
}

.node-main {
    display: inline-flex;
    min-width: 0;
    align-items: center;
    gap: 6px;
}

.node-icon {
    flex: none;
    font-size: 15px;
    color: var(--el-text-color-secondary);
}

.node-icon.is-level-0 {
    color: var(--el-color-primary);
}

.node-icon.is-level-1 {
    color: var(--el-color-success);
}

.node-icon.is-level-2 {
    color: var(--el-color-warning);
}

.node-icon.is-level-3 {
    color: var(--el-color-info);
}

.node-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.node-count {
    flex: none;
    color: var(--el-text-color-secondary);
    font-size: 12px;
}

.ledger-tree :deep(.el-tree-node__content) {
    min-width: 0;
}
</style>
