<template>
  <a-input-group>
    <a-select
      v-model="selectedDatacenterId"
      :placeholder="placeholders.datacenter"
      :loading="datacenterListLoading"
      :disabled="disabled"
      style="width: 33.33%"
      allow-search
      @search="handleDatacenterSearch"
      @change="handleDatacenterChange"
    >
      <a-option v-for="datacenter in datacenterList" :key="datacenter.value" :value="datacenter.value">
        {{ datacenter.label }}
      </a-option>
    </a-select>
    <a-select
      v-model="selectedFloorId"
      :placeholder="placeholders.floor"
      :loading="floorListLoading"
      :disabled="disabled || !selectedDatacenterId"
      style="width: 33.33%"
      allow-search
      @search="handleFloorSearch"
      @change="handleFloorChange"
    >
      <a-option v-for="floor in floorList" :key="floor.value" :value="floor.value">
        {{ floor.label }}
      </a-option>
    </a-select>
    <a-select
      v-model="selectedRackId"
      :placeholder="placeholders.rack"
      :loading="rackListLoading"
      :disabled="disabled || !selectedFloorId"
      style="width: 33.33%"
      allow-search
      @search="handleRackSearch"
      @change="handleRackChange"
    >
      <a-option v-for="rack in rackList" :key="rack.id" :value="rack.id">{{ rack.name }} ({{ rack.code }})</a-option>
    </a-select>
  </a-input-group>
</template>

<script lang="ts" setup>
import { ref, watch, onMounted } from 'vue'
import { Message } from '@arco-design/web-vue'
import { fetchDatacenterList, fetchRackListByFloor } from '@/api/ops/rack'
import { fetchFloorListByDatacenter } from '@/api/ops/floor'

interface Props {
  datacenterId?: number
  floorId?: number
  rackId?: number
  disabled?: boolean
  placeholders?: {
    datacenter: string
    floor: string
    rack: string
  }
}

const props = withDefaults(defineProps<Props>(), {
  datacenterId: undefined,
  floorId: undefined,
  rackId: undefined,
  disabled: false,
  placeholders: () => ({
    datacenter: '请选择数据中心',
    floor: '请选择楼层',
    rack: '请选择机柜',
  }),
})

const emit = defineEmits<{
  'update:datacenterId': [value: number | undefined]
  'update:floorId': [value: number | undefined]
  'update:rackId': [value: number | undefined]
  change: [value: { datacenterId?: number; floorId?: number; rackId?: number }]
}>()

// 三级联动相关状态
const datacenterListLoading = ref(false)
const floorListLoading = ref(false)
const rackListLoading = ref(false)
const datacenterList = ref<{ label: string; value: number }[]>([])
const floorList = ref<{ label: string; value: number }[]>([])
const rackList = ref<any[]>([])

// 内部选中的值
const selectedDatacenterId = ref<number | undefined>(props.datacenterId)
const selectedFloorId = ref<number | undefined>(props.floorId)
const selectedRackId = ref<number | undefined>(props.rackId)

let datacenterSearchTimer: number | undefined
let floorSearchTimer: number | undefined
let rackSearchTimer: number | undefined

// 获取数据中心列表
const fetchDatacenters = async (keyword?: string) => {
  datacenterListLoading.value = true
  try {
    const res: any = await fetchDatacenterList({ keyword })
    const rows = res.details
    datacenterList.value = rows.map((d: any) => ({
      label: d.name || d.code || String(d.id),
      value: d.id,
    }))
  } catch (error) {
    console.error('获取数据中心列表失败:', error)
    Message.error('获取数据中心列表失败')
    datacenterList.value = []
  } finally {
    datacenterListLoading.value = false
  }
}

// 获取楼层列表
const fetchFloors = async (keyword?: string) => {
  if (!selectedDatacenterId.value) {
    floorList.value = []
    return
  }
  floorListLoading.value = true
  try {
    const res: any = await fetchFloorListByDatacenter(selectedDatacenterId.value, {
      name: keyword || undefined,
    })
    const rows = res.details
    floorList.value = rows.map((floor: any) => ({
      label: floor.name || floor.code || String(floor.id),
      value: floor.id,
    }))
  } catch (error) {
    console.error('获取楼层列表失败:', error)
    Message.error('获取楼层列表失败')
    floorList.value = []
  } finally {
    floorListLoading.value = false
  }
}

// 获取机柜列表
const fetchRacks = async (keyword?: string) => {
  if (!selectedFloorId.value) {
    rackList.value = []
    return
  }
  rackListLoading.value = true
  try {
    const res: any = await fetchRackListByFloor(selectedFloorId.value, { keyword })
    rackList.value = res.details.data
  } catch (error) {
    console.error('获取机柜列表失败:', error)
    Message.error('获取机柜列表失败')
    rackList.value = []
  } finally {
    rackListLoading.value = false
  }
}

// 数据中心搜索
const handleDatacenterSearch = (keyword: string) => {
  if (datacenterSearchTimer) {
    window.clearTimeout(datacenterSearchTimer)
  }
  datacenterSearchTimer = window.setTimeout(() => {
    fetchDatacenters(keyword?.trim() || undefined)
  }, 300)
}

// 楼层搜索
const handleFloorSearch = (keyword: string) => {
  if (!selectedDatacenterId.value) return
  if (floorSearchTimer) {
    window.clearTimeout(floorSearchTimer)
  }
  floorSearchTimer = window.setTimeout(() => {
    fetchFloors(keyword?.trim() || undefined)
  }, 300)
}

// 机柜搜索
const handleRackSearch = (keyword: string) => {
  if (!selectedFloorId.value) return
  if (rackSearchTimer) {
    window.clearTimeout(rackSearchTimer)
  }
  rackSearchTimer = window.setTimeout(() => {
    fetchRacks(keyword?.trim() || undefined)
  }, 300)
}

// 数据中心变化
const handleDatacenterChange = async (datacenterId?: number | string) => {
  if (datacenterId !== undefined && datacenterId !== null && datacenterId !== '') {
    selectedDatacenterId.value = Number(datacenterId)
  } else {
    selectedDatacenterId.value = undefined
  }
  selectedFloorId.value = undefined
  selectedRackId.value = undefined
  rackList.value = []
  floorList.value = []

  emit('update:datacenterId', selectedDatacenterId.value)
  emit('update:floorId', undefined)
  emit('update:rackId', undefined)
  emit('change', {
    datacenterId: selectedDatacenterId.value,
    floorId: undefined,
    rackId: undefined,
  })

  await fetchFloors()
}

// 楼层变化
const handleFloorChange = async (floorId?: number | string) => {
  if (floorId !== undefined && floorId !== null && floorId !== '') {
    selectedFloorId.value = Number(floorId)
  } else {
    selectedFloorId.value = undefined
  }
  selectedRackId.value = undefined
  rackList.value = []

  emit('update:floorId', selectedFloorId.value)
  emit('update:rackId', undefined)
  emit('change', {
    datacenterId: selectedDatacenterId.value,
    floorId: selectedFloorId.value,
    rackId: undefined,
  })

  await fetchRacks()
}

// 机柜变化
const handleRackChange = (rackId?: number | string) => {
  if (rackId !== undefined && rackId !== null && rackId !== '') {
    selectedRackId.value = Number(rackId)
  } else {
    selectedRackId.value = undefined
  }

  emit('update:rackId', selectedRackId.value)
  emit('change', {
    datacenterId: selectedDatacenterId.value,
    floorId: selectedFloorId.value,
    rackId: selectedRackId.value,
  })
}

// 重置方法
const reset = () => {
  selectedDatacenterId.value = undefined
  selectedFloorId.value = undefined
  selectedRackId.value = undefined
  floorList.value = []
  rackList.value = []
}

// 初始化加载
const initLoad = async () => {
  await fetchDatacenters()

  // 如果有初始值，加载对应的下级列表
  if (props.datacenterId) {
    selectedDatacenterId.value = props.datacenterId
    await fetchFloors()
  }
  if (props.floorId) {
    selectedFloorId.value = props.floorId
    await fetchRacks()
  }
  if (props.rackId) {
    selectedRackId.value = props.rackId
  }
}

// 监听外部传入的值变化
watch(
  () => props.datacenterId,
  (val) => {
    if (val !== selectedDatacenterId.value) {
      selectedDatacenterId.value = val
      if (val) {
        fetchFloors()
      } else {
        floorList.value = []
        rackList.value = []
      }
    }
  }
)

watch(
  () => props.floorId,
  (val) => {
    if (val !== selectedFloorId.value) {
      selectedFloorId.value = val
      if (val) {
        fetchRacks()
      } else {
        rackList.value = []
      }
    }
  }
)

watch(
  () => props.rackId,
  (val) => {
    selectedRackId.value = val
  }
)

// 暴露方法给父组件
defineExpose({
  reset,
  initLoad,
  fetchDatacenters,
  fetchFloors,
  fetchRacks,
})

onMounted(() => {
  initLoad()
})
</script>
