import type { UploadCustomRequestOptions } from 'naive-ui'
import { exportToExcel, readExcel } from '@sa/utils'
import { ref, watch } from 'vue'

export interface HardwareGroup {
  groupId: string
  pens: Array<{ label: string, sn: string, online: boolean }>
}

export function useHardwareBinding(props: any) {
  const hardwareGroups = ref<HardwareGroup[]>([])

  // 生成硬件分组
  function generateHardwareGroups() {
    if (!props.config)
      return

    const { groupCount, teamCount } = props.config
    if (!groupCount || groupCount <= 0)
      return

    const totalGroups = groupCount
    // 仅在初始化或配置完全改变时重新生成，避免覆盖用户已输入的数据
    if (hardwareGroups.value.length === totalGroups && hardwareGroups.value[0]?.pens.length === teamCount) {
      return
    }

    const newGroups: HardwareGroup[] = []

    for (let i = 1; i <= totalGroups; i++) {
      const idStr = String(i).padStart(2, '0')
      const currentTeamCount = teamCount

      const pens = []
      for (let j = 1; j <= currentTeamCount; j++) {
        pens.push({
          label: `T${j}`,
          sn: '',
          online: true, // 模拟初始状态
        })
      }

      newGroups.push({
        groupId: idStr,
        pens,
      })
    }
    hardwareGroups.value = newGroups
  }

  watch(() => props.config, generateHardwareGroups, { deep: true, immediate: true })

  // 校验硬件绑定是否符合要求
  function validate() {
    // 1. 校验每个分组是否都有队伍绑定
    for (const group of hardwareGroups.value) {
      if (group.pens.some(pen => !pen.sn)) {
        window.$message?.error(`分组 ${group.groupId} 存在未绑定的队伍`)
        return false
      }
    }

    // 2. 校验重复 SN
    const snMap = new Map<string, string[]>()
    let hasDuplicate = false

    hardwareGroups.value.forEach((group) => {
      group.pens.forEach((pen, teamIndex) => {
        const sn = pen.sn.trim()
        if (!sn)
          return

        const location = `第${group.groupId}组-T${teamIndex + 1}`
        if (snMap.has(sn)) {
          snMap.get(sn)?.push(location)
          hasDuplicate = true
        }
        else {
          snMap.set(sn, [location])
        }
      })
    })

    if (hasDuplicate) {
      const duplicates: string[] = []
      snMap.forEach((locations, sn) => {
        if (locations.length > 1) {
          duplicates.push(`SN "${sn}" 重复于: ${locations.join(', ')}`)
        }
      })
      const msg = duplicates.slice(0, 3).join('; ') + (duplicates.length > 3 ? ' 等...' : '')
      window.$message?.error(`发现重复 SN：${msg}`)
      return false
    }

    return true
  }

  function reset() {
    // 强制重新生成
    if (props.config) {
      hardwareGroups.value = [] // 清空以触发重新生成
      generateHardwareGroups()
    }
  }

  return {
    hardwareGroups,
    generateHardwareGroups,
    validate,
    reset,
  }
}

export function useHardwareExcel(props: any, hardwareGroups: any) {
  // 下载模板
  function handleDownloadTemplate() {
    if (!props.config)
      return

    const { groupCount, teamCount } = props.config
    const data = []

    for (let i = 1; i <= groupCount; i++) {
      for (let j = 1; j <= teamCount; j++) {
        data.push({
          分组名称: `第 ${i} 组`,
          队伍编号: j,
          点阵笔SN: '',
        })
      }
    }

    exportToExcel(data, '硬件绑定模板', '硬件绑定')
  }

  // 导入 Excel
  async function handleUpload({ file }: UploadCustomRequestOptions) {
    try {
      if (!file.file)
        return
      const data = await readExcel(file.file)

      if (!data || data.length === 0) {
        window.$message?.warning('Excel 文件内容为空')
        return
      }

      // 1. 识别表头映射 (兼容多种表头格式)
      const firstRow = data[0] as any
      const keys = Object.keys(firstRow)

      const groupKey = keys.find(k => k.includes('分组') || k.includes('Group'))
      const teamKey = keys.find(k => k.includes('队伍') || k.includes('Team') || k.includes('点阵笔号'))
      const snKey = keys.find(k => k.includes('SN') || k.includes('SN') || k.includes('sn') || k.includes('点阵笔'))

      if (!groupKey || !teamKey || !snKey) {
        window.$message?.error('Excel 模板格式错误，未找到“分组”、“队伍”或“SN”相关列')
        return
      }

      // 2. 校验导入数据中的重复项
      const snMap = new Map<string, string[]>()
      const importDuplicates: string[] = []

      data.forEach((row: any) => {
        const sn = row[snKey] ? String(row[snKey]).trim() : ''
        if (!sn)
          return

        const groupNum = row[groupKey]
        const teamNum = row[teamKey]
        const location = `第${groupNum}组-T${teamNum}`

        if (!snMap.has(sn)) {
          snMap.set(sn, [])
        }
        snMap.get(sn)?.push(location)
      })

      snMap.forEach((locations, sn) => {
        if (locations.length > 1) {
          importDuplicates.push(`SN "${sn}" 重复于: ${locations.join(', ')}`)
        }
      })

      if (importDuplicates.length > 0) {
        const msg = importDuplicates.slice(0, 3).join('; ') + (importDuplicates.length > 3 ? ' 等...' : '')
        window.$message?.error(`导入文件中存在重复 SN，请检查：${msg}`, { duration: 5000 })
        return
      }

      // 3. 解析数据并填充
      let successCount = 0
      const newGroups = [...hardwareGroups.value] // 创建浅拷贝以触发响应式更新

      // 辅助函数：解析索引
      const parseIndex = (val: any) => {
        if (typeof val === 'number')
          return val
        if (typeof val === 'string') {
          const match = val.match(/\d+/)
          return match ? Number(match[0]) : Number.NaN
        }
        return Number.NaN
      }

      data.forEach((row: any) => {
        const groupIdx = parseIndex(row[groupKey]) - 1
        const teamIdx = parseIndex(row[teamKey]) - 1
        const sn = row[snKey] ? String(row[snKey]).trim() : ''

        if (
          !Number.isNaN(groupIdx) && groupIdx >= 0 && groupIdx < newGroups.length
          && newGroups[groupIdx]
          && !Number.isNaN(teamIdx) && teamIdx >= 0 && teamIdx < newGroups[groupIdx].pens.length
        ) {
          // 直接修改对象属性
          newGroups[groupIdx].pens[teamIdx].sn = `${sn}号笔`
          successCount++
        }
      })

      // 强制触发更新
      hardwareGroups.value = newGroups

      if (successCount > 0) {
        window.$message?.success(`成功导入 ${successCount} 条数据`)
      }
      else {
        console.warn('导入数据匹配失败', data)
        window.$message?.warning('未匹配到任何有效数据，请检查分组/队伍编号是否正确')
      }
    }
    catch (error) {
      console.error(error)
      window.$message?.error('导入失败，请检查文件格式')
    }
  }

  return {
    handleDownloadTemplate,
    handleUpload,
  }
}

export function useQuickGenerate(props: any, hardwareGroups: any) {
  // 快速生成笔号
  function quickGenerate(type: 'order' | 'random' = 'order') {
    if (!props.config)
      return

    // 1. 收集所有笔的引用
    const allPens: any[] = []
    hardwareGroups.value.forEach((group: HardwareGroup) => {
      group.pens.forEach((pen) => {
        allPens.push(pen)
      })
    })

    if (allPens.length === 0)
      return

    // 2. 生成序号数组
    const numbers = Array.from({ length: allPens.length }, (_, i) => i + 1)

    // 3. 如果是随机模式，打乱数组 (Fisher-Yates shuffle)
    if (type === 'random') {
      for (let i = numbers.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [numbers[i], numbers[j]] = [numbers[j], numbers[i]]
      }
    }

    // 4. 依次赋值
    allPens.forEach((pen, index) => {
      pen.sn = `${numbers[index]}号笔`
    })

    window.$message?.success(type === 'random' ? '已随机生成笔号' : '已顺序生成笔号')
  }

  return {
    quickGenerate,
  }
}
