<template>
  <el-tree-select
    v-model="selectedValue"
    :data="agentTreeData"
    :props="treeProps"
    :placeholder="placeholder"
    :clearable="clearable"
    :disabled="disabled"
    :filterable="filterable"
    :check-strictly="checkStrictly"
    :multiple="multiple"
    :size="size"
    :render-after-expand="false"
    @change="handleChange"
    @visible-change="handleVisibleChange"
  >
    <template #default="{ data }">
      <div class="agent-node">
        <span class="agent-name">{{ data.name }}</span>
        <span v-if="data.level" class="agent-level">{{ data.level }}</span>
      </div>
    </template>
  </el-tree-select>
</template>

<script setup lang="ts">
  import { ref, computed, onMounted } from 'vue'
  import type { Agent } from '@/types/api'

  interface Props {
    modelValue?: string | number | (string | number)[]
    placeholder?: string
    clearable?: boolean
    disabled?: boolean
    filterable?: boolean
    checkStrictly?: boolean
    multiple?: boolean
    size?: 'large' | 'default' | 'small'
    // 预加载的代理商树数据
    agents?: Agent[]
    // 远程获取方法
    fetchMethod?: () => Promise<Agent[]>
  }

  interface Emits {
    (e: 'update:modelValue', value: string | number | (string | number)[] | undefined): void
    (e: 'change', value: string | number | (string | number)[] | undefined): void
  }

  const props = withDefaults(defineProps<Props>(), {
    placeholder: '请选择代理商',
    clearable: true,
    disabled: false,
    filterable: true,
    checkStrictly: false,
    multiple: false,
    size: 'default'
  })

  const emit = defineEmits<Emits>()

  const loading = ref(false)
  const agentTreeData = ref<Agent[]>([])

  const treeProps = {
    value: 'id',
    label: 'name',
    children: 'children'
  }

  const selectedValue = computed({
    get: () => props.modelValue,
    set: (val) => {
      emit('update:modelValue', val)
    }
  })

  const handleChange = (value: string | number | (string | number)[] | undefined) => {
    emit('change', value)
  }

  const handleVisibleChange = (visible: boolean) => {
    if (visible && agentTreeData.value.length === 0) {
      loadAgents()
    }
  }

  const loadAgents = async () => {
    if (props.agents) {
      agentTreeData.value = props.agents
    } else if (props.fetchMethod) {
      loading.value = true
      try {
        agentTreeData.value = await props.fetchMethod()
      } finally {
        loading.value = false
      }
    }
  }

  onMounted(() => {
    if (props.agents) {
      agentTreeData.value = props.agents
    }
  })
</script>

<style scoped lang="scss">
  .agent-node {
    display: flex;
    gap: 8px;
    align-items: center;

    .agent-name {
      font-weight: 500;
      color: var(--el-text-color-primary);
    }

    .agent-level {
      padding: 2px 8px;
      font-size: 12px;
      color: var(--el-color-primary);
      background-color: var(--el-color-primary-light-9);
      border-radius: 4px;
    }
  }
</style>
