<template>
  <!-- 纯数据组件 -->
  <div style="display:none"></div>
</template>

<script setup lang="ts">
/**
 * Fan 悬浮信息 + 设置项上下文菜单
 */

/* ============================== Imports ============================== */
import { defineEmits, defineProps, onMounted, watch, ref, reactive } from 'vue'
import { traduction } from '@/utils/language'
import { getThermals, intelligentUpdate } from '@/pages/System/Info/service/system.service'
import { getIntelSpeedAdjustInfo, initializingIntelSpeedAdjustInfo } from '@/pages/System/Fans/utils/fan.utils'

import { MenuItem, CtxAction } from '../shared/types'

/** ====== 类型 / 常量 ====== */
type FanItem = {
  Name?: string
  FanId?: number
  Model?: string
  Speed?: number
  SpeedRatio?: number
  ExpectedSpeedRatio?: number
  PartNumber?: string
  Presence?: number
  DutyCycle?: number
}

const MODES = [
  'EnergySaving',
  'LowNoise',
  'HighPerformance',
  // 'LiquidCooling',
  // 'Custom',
] as const

type ModeId = typeof MODES[number]
type RunMode = 'Auto' | 'Manual'
const MODE_ORDER: readonly ModeId[] = MODES
const MODE_I18N_KEY = {
  EnergySaving: 'FAN_MODEL_TITLE1',
  LowNoise: 'FAN_MODEL_TITLE2',
  HighPerformance: 'FAN_MODEL_TITLE3',
  // LiquidCooling: 'FAN_LIQUID_COOLING',
  // Custom: 'FAN_MODEL_TITLE4',
} as const satisfies Record<ModeId, string>

const props = defineProps<{ fans?: FanItem[] }>()
const emit = defineEmits<{ (e: 'fan-list', names: string[]): void }>()

const norm = (name: string) => {
  const raw = (name || '').toUpperCase().replace(/[\s_-]/g, '')
  const m = raw.match(/FAN(\d+)/) || raw.match(/(\d+)$/)
  const id = m ? m[1] : ''
  return id ? `FAN${id}` : raw || 'FAN'
}
const i18nSmartMode = (id: ModeId) => traduction(MODE_I18N_KEY[id] || MODE_I18N_KEY.EnergySaving)

/** ====== 数据缓存 / 全局状态 ====== */
const fanMap = ref<Record<string, FanItem>>({})
const name2Id = ref<Record<string, number>>({})

const state = reactive({
  fanMode: 'Auto' as RunMode,
  fanSmartCoolingMode: 'EnergySaving' as ModeId,
  manualLevel: 20,
  levelPercentRange: [20, 100] as [number, number],
  modelPredictiveControlEnabled: false,
  coolingMedium: 'AirCooled' as 'AirCooled' | 'LiquidCooled' | string,
  customConfig: {} as Record<string, any>,
})

function setMapFromArray(arr: FanItem[]) {
  const map: Record<string, FanItem> = {}
  const n2i: Record<string, number> = {}
    ; (arr || []).forEach((f, i) => {
      const key = norm(f?.Name || `Fan${f?.FanId ?? i + 1}`)
      map[key] = f
      if (f?.FanId != null) n2i[key] = f.FanId
    })
  fanMap.value = map
  name2Id.value = n2i
  emit('fan-list', Object.keys(map))
}
function getFanIdByName(name: string) { return name2Id.value[norm(name)] }

async function pullThermal() {
  const res: any = await getThermals()
  const data = res?.data ?? {}

  const rawFans: any[] = Array.isArray(data?.Fans) ? data.Fans : []
  const flat: FanItem[] = rawFans.flatMap((g: any) => Array.isArray(g) ? g : []).filter(Boolean)
  if (flat.length) setMapFromArray(flat)

  const info = getIntelSpeedAdjustInfo(data)
  initializingIntelSpeedAdjustInfo(info)

  state.fanMode = (data.FanCtrlMode as RunMode) || 'Auto'
  state.manualLevel = data.ManualLevel ?? 20
  state.levelPercentRange = Array.isArray(data.LevelPercentRange) ? data.LevelPercentRange : [20, 100]
  state.modelPredictiveControlEnabled = !!info.modelPredictiveControlEnabled
  state.fanSmartCoolingMode = (info.fanSmartCoolingMode || 'EnergySaving') as ModeId
  state.coolingMedium = info.coolingMedium || 'AirCooled'

  const custom = (info as any)?.SmartCooling?.CustomConfig || data?.SmartCooling?.CustomConfig || {}
  state.customConfig = { ...custom }
}
async function refresh() { await pullThermal() }

/** ====== 悬浮卡片 ====== */
async function buildPairs(name: string) {
  const f = fanMap.value[norm(name)]
  if (!f) return []
  return [
    { k: traduction('COMMON_NAME'), v: f.Name || name },
    { k: traduction('FAN_HEAT_TYPE'), v: f.Model ?? '-' },
    { k: traduction('FAN_HEAT_ROTATIONAL_SPEED'), v: (f.Speed != null) ? String(f.Speed) : '--' },
    { k: traduction('FAN_HEAT_RATE_TAUX'), v: (f.ExpectedSpeedRatio != null) ? String(f.ExpectedSpeedRatio) : '--' },
    { k: traduction('FAN_HEAT_RATE'), v: (f.SpeedRatio != null) ? String(f.SpeedRatio) : '--' },
    { k: traduction('OTHER_PART_NUMBER'), v: f.PartNumber ?? '-' },
    { k: traduction('FAN_RATE'), v: (f.DutyCycle != null) ? String(f.DutyCycle) : '--' },
  ]
}

function getBasicText(name: string) {
  const f = fanMap.value[norm(name)]
  if (!f) return name
  const rpm = (f.Speed != null) ? `${f.Speed}` : '—'
  const ratio = (f.SpeedRatio != null) ? `${f.SpeedRatio}%` : '—'
  return `${f.Name || name} · ${rpm}（${ratio}）`
}

function getNames(): string[] {
  return Object.values(fanMap.value).map(f => f?.Name as string)
}

/** ====== 设置动作（内部实现） ====== */
async function setRunMode(mode: RunMode) {
  const r: any = await intelligentUpdate({ FanCtrlMode: mode })
  if (r?.data?.error) return false
  await refresh()
  return true
}
async function setSmartCoolingMPC(enabled: boolean) {
  const r: any = await intelligentUpdate({ ModelPredictiveControlEnabled: !!enabled })
  if (r?.data?.error) return false
  await refresh()
  return true
}
async function setSmartCoolingMode(mode: unknown, customConfig?: Record<string, any>) {
  const MODES = ['EnergySaving', 'LowNoise', 'HighPerformance'] as const
  if (!(MODES as readonly string[]).includes(String(mode))) return false
  const modeId = mode as typeof MODES[number]
  const payload: any = { SmartCooling: { Mode: modeId } }
  if (modeId === 'Custom' && customConfig && Object.keys(customConfig).length) {
    payload.SmartCooling.CustomConfig = customConfig
  }
  const r: any = await intelligentUpdate(payload)
  if (r?.data?.error) return false
  await refresh()
  return true
}
async function setManualLevel(percent: number) {
  const v = Number(percent)
  if (Number.isNaN(v)) return false
  const r: any = await intelligentUpdate({ ManualLevel: v })
  if (r?.data?.error) return false
  await refresh()
  return true
}
async function setFanExpectedRatio(fanName: string, percent: number) {
  const id = getFanIdByName(fanName); if (id == null) return false
  const v = Number(percent); if (Number.isNaN(v)) return false
  const r: any = await intelligentUpdate({ FanId: Number(id), ExpectedSpeedRatio: v })
  if (r?.data?.error) return false
  await refresh()
  return true
}

async function getContextMenu(name: string): Promise<{ title: string; items: MenuItem[] }> {
  const items: MenuItem[] = []

  const curRunMode = state.fanMode
  const curMPC = !!state.modelPredictiveControlEnabled
  const curSmart = state.fanSmartCoolingMode as any
  const curGlobalPct = Number(state.manualLevel ?? 20)

  // 1) 运行模式
  items.push({
    key: 'fan.runmode',
    label: traduction('FAN_MODE'),
    hint: curRunMode === 'Auto' ? traduction('FAN_MODE_AUTO') : traduction('FAN_MODE_CUSTEM'),
    children: [
      {
        key: 'fan.runmode.auto',
        label: traduction('FAN_MODE_AUTO'),
        active: curRunMode === 'Auto',
        action: { op: 'setRunMode', params: { mode: 'Auto' } }
      },
      {
        key: 'fan.runmode.manual',
        label: traduction('FAN_MODE_CUSTEM'),
        active: curRunMode === 'Manual',
        action: { op: 'setRunMode', params: { mode: 'Manual' } }
      },
    ],
  })

  if (curRunMode === 'Auto') {
    // 2) MPC 开关
    items.push({
      key: 'fan.mpc',
      label: traduction('POWER_MPC'),
      hint: curMPC ? traduction('FDM_ENABLED') : traduction('FDM_DISABLED'),
      children: [
        { key: 'fan.mpc.on', label: traduction('FDM_ENABLED'), active: curMPC === true, action: { op: 'setSmartCoolingMPC', params: { enabled: true } } },
        { key: 'fan.mpc.off', label: traduction('FDM_DISABLED'), active: curMPC === false, action: { op: 'setSmartCoolingMPC', params: { enabled: false } } },
      ],
    })

    // 3) 智能模式
    const MODE_ORDER = ['EnergySaving', 'LowNoise', 'HighPerformance'] as const
    items.push({
      key: 'fan.smart',
      label: traduction('POWER_SELECT_MODE'),
      hint: traduction(curSmart === 'EnergySaving' ? 'FAN_MODEL_TITLE1' : curSmart === 'LowNoise' ? 'FAN_MODEL_TITLE2' : 'FAN_MODEL_TITLE3'),
      children: MODE_ORDER.map(id => ({
        key: `fan.smart.${id}`,
        label: traduction(id === 'EnergySaving' ? 'FAN_MODEL_TITLE1' : id === 'LowNoise' ? 'FAN_MODEL_TITLE2' : 'FAN_MODEL_TITLE3'),
        active: id === curSmart,
        action: { op: 'setSmartCoolingMode', params: { mode: id } },
      })),
    })
  } else {
    // 4) 手动：全局百分比 —— 输入 + 确定
    const [minP = 20, maxP = 100] = state.levelPercentRange || [20, 100]
    items.push({
      key: 'fan.manual.global',
      label: `${traduction('FAN_HEAT_RATE_TAUX')}`,
      hint: `${curGlobalPct}%`,
      children: [
        {
          key: 'fan.manual.global.input',
          label: `${traduction('FAN_HEAT_RATE_TAUX')}(%)`,
          input: { type: 'number', min: minP, max: maxP, step: 1, default: curGlobalPct },
          action: { op: 'setManualLevel', params: { level: '__INPUT__' } },
        }
      ],
    })
  }

  // 5) 刷新
  items.push({ key: 'fan.refresh', label: traduction('COMMON_REFRESH'), action: { op: 'refresh' } })
  return { title: 'Fans', items }
}

/** ====== 右键动作 ====== */
async function execContextAction(action: CtxAction) {
  const { op, params = {} } = action || {}
  if (!op) return
  switch (op) {
    case 'setRunMode': await setRunMode(params.mode); break
    case 'setSmartCoolingMPC': await setSmartCoolingMPC(!!params.enabled); break
    case 'setSmartCoolingMode': await setSmartCoolingMode(params.mode, params.customConfig); break
    case 'setManualLevel': await setManualLevel(params.level); break
    case 'setFanExpectedRatio': await setFanExpectedRatio(params.name, params.level); break
    case 'refresh': await refresh(); break
    default: break
  }
}

/** ====== 对外暴露 ====== */
defineExpose({
  buildPairs,
  getBasicText,
  getContextMenu,
  execContextAction,
  refresh,
  getNames,
})

onMounted(refresh)
watch(() => props.fans, arr => { if (arr?.length) setMapFromArray(arr) }, { deep: true })
</script>
