import { useMemo } from 'react'
import type { MilitarySituation } from '@/data/mockData'
import { useSituationStore } from '@/store/situationStore'
import { usePlaybackStore } from '@/store/playbackStore'

/** 将系列时间映射到回放日 (2026-03-01) 以便按当天时刻插值 */
function toReplayDay(iso: string, baseDay: string): string {
  const d = new Date(iso)
  const [y, m, day] = baseDay.slice(0, 10).split('-').map(Number)
  return new Date(y, (m || 1) - 1, day || 1, d.getUTCHours(), d.getUTCMinutes(), 0, 0).toISOString()
}

function interpolateAt(
  series: { time: string; value: number }[],
  at: string,
  baseDay = '2026-03-01'
): number {
  if (series.length === 0) return 0
  const t = new Date(at).getTime()
  const mapped = series.map((p) => ({
    time: toReplayDay(p.time, baseDay),
    value: p.value,
  }))
  const sorted = [...mapped].sort((a, b) => new Date(a.time).getTime() - new Date(b.time).getTime())
  const before = sorted.filter((p) => new Date(p.time).getTime() <= t)
  const after = sorted.filter((p) => new Date(p.time).getTime() > t)
  if (before.length === 0) return sorted[0].value
  if (after.length === 0) return sorted[sorted.length - 1].value
  const a = before[before.length - 1]
  const b = after[0]
  const ta = new Date(a.time).getTime()
  const tb = new Date(b.time).getTime()
  const f = tb === ta ? 1 : (t - ta) / (tb - ta)
  return a.value + f * (b.value - a.value)
}

function linearProgress(start: string, end: string, at: string): number {
  const ts = new Date(start).getTime()
  const te = new Date(end).getTime()
  const ta = new Date(at).getTime()
  if (ta <= ts) return 0
  if (ta >= te) return 1
  return (ta - ts) / (te - ts)
}

/** 根据回放时刻派生态势数据 */
export function useReplaySituation(): MilitarySituation {
  const situation = useSituationStore((s) => s.situation)
  const { isReplayMode, playbackTime } = usePlaybackStore()

  return useMemo(() => {
    if (!isReplayMode) return situation

    const progress = linearProgress('2026-03-01T02:00:00.000Z', '2026-03-01T11:45:00.000Z', playbackTime)

    // 华尔街趋势、反击情绪：按时间插值
    const wsValue = interpolateAt(situation.usForces.wallStreetInvestmentTrend, playbackTime)
    const retValue = interpolateAt(situation.iranForces.retaliationSentimentHistory, playbackTime)

    // 战斗损失：从 0 线性增长到当前值
    const lerp = (a: number, b: number) => Math.round(a + progress * (b - a))
    const usLoss = situation.usForces.combatLosses
    const irLoss = situation.iranForces.combatLosses
    const civTotal = situation.civilianCasualtiesTotal ?? { killed: 0, wounded: 0 }
    const usLossesAt = {
      bases: {
        destroyed: lerp(0, usLoss.bases.destroyed),
        damaged: lerp(0, usLoss.bases.damaged),
      },
      personnelCasualties: {
        killed: lerp(0, usLoss.personnelCasualties.killed),
        wounded: lerp(0, usLoss.personnelCasualties.wounded),
      },
      civilianCasualties: { killed: 0, wounded: 0 },
      aircraft: lerp(0, usLoss.aircraft),
      warships: lerp(0, usLoss.warships),
      armor: lerp(0, usLoss.armor),
      vehicles: lerp(0, usLoss.vehicles),
      drones: lerp(0, usLoss.drones ?? 0),
      missiles: lerp(0, usLoss.missiles ?? 0),
      helicopters: lerp(0, usLoss.helicopters ?? 0),
      submarines: lerp(0, usLoss.submarines ?? 0),
      tanks: lerp(0, usLoss.tanks ?? 0),
      civilianShips: lerp(0, usLoss.civilianShips ?? 0),
      airportPort: lerp(0, usLoss.airportPort ?? 0),
    }
    const irLossesAt = {
      bases: {
        destroyed: lerp(0, irLoss.bases.destroyed),
        damaged: lerp(0, irLoss.bases.damaged),
      },
      personnelCasualties: {
        killed: lerp(0, irLoss.personnelCasualties.killed),
        wounded: lerp(0, irLoss.personnelCasualties.wounded),
      },
      civilianCasualties: { killed: 0, wounded: 0 },
      aircraft: lerp(0, irLoss.aircraft),
      warships: lerp(0, irLoss.warships),
      armor: lerp(0, irLoss.armor),
      vehicles: lerp(0, irLoss.vehicles),
      drones: lerp(0, irLoss.drones ?? 0),
      missiles: lerp(0, irLoss.missiles ?? 0),
      helicopters: lerp(0, irLoss.helicopters ?? 0),
      submarines: lerp(0, irLoss.submarines ?? 0),
      tanks: lerp(0, irLoss.tanks ?? 0),
      civilianShips: lerp(0, irLoss.civilianShips ?? 0),
      airportPort: lerp(0, irLoss.airportPort ?? 0),
    }

    // 被袭基地：按 damage_level 排序，高损毁先出现；根据 progress 决定显示哪些为 attacked
    const usLocs = situation.usForces.keyLocations || []
    const attackedBases = usLocs
      .filter((loc) => loc.status === 'attacked')
      .sort((a, b) => (b.damage_level ?? 0) - (a.damage_level ?? 0))
    const totalAttacked = attackedBases.length
    const shownAttackedCount = Math.round(progress * totalAttacked)
    const attackedNames = new Set(
      attackedBases.slice(0, shownAttackedCount).map((l) => l.name)
    )

    const usLocsAt = usLocs.map((loc) => {
      if (loc.status === 'attacked' && !attackedNames.has(loc.name)) {
        return { ...loc, status: 'operational' as const }
      }
      return { ...loc }
    })

    return {
      ...situation,
      lastUpdated: playbackTime,
      civilianCasualtiesTotal: {
        killed: lerp(0, civTotal.killed),
        wounded: lerp(0, civTotal.wounded),
      },
      usForces: {
        ...situation.usForces,
        keyLocations: usLocsAt,
        combatLosses: usLossesAt,
        wallStreetInvestmentTrend: [
          ...situation.usForces.wallStreetInvestmentTrend.filter((p) => new Date(p.time).getTime() <= new Date(playbackTime).getTime()),
          { time: playbackTime, value: wsValue },
        ].slice(-20),
      },
      iranForces: {
        ...situation.iranForces,
        combatLosses: irLossesAt,
        retaliationSentiment: retValue,
        retaliationSentimentHistory: [
          ...situation.iranForces.retaliationSentimentHistory.filter((p) => new Date(p.time).getTime() <= new Date(playbackTime).getTime()),
          { time: playbackTime, value: retValue },
        ].slice(-20),
      },
      recentUpdates: (situation.recentUpdates || []).filter(
        (u) => new Date(u.timestamp).getTime() <= new Date(playbackTime).getTime()
      ),
      conflictEvents: situation.conflictEvents || [],
      conflictStats: situation.conflictStats || { total_events: 0, high_impact_events: 0, estimated_casualties: 0, estimated_strike_count: 0 },
    }
  }, [situation, isReplayMode, playbackTime])
}
