import type Phaser from 'phaser'
import { EnemyBase, buildFullPath, type PathPoint } from './EnemyBase'
import { FreshGraduate } from './FreshGraduate'
import { OldEmployee } from './OldEmployee'
import { TroubleMaker } from './TroubleMaker'
import { BossVP } from './BossVP'
import type { WaveConfigEntry, DifficultyLevel } from '../data/mapConfigs'
import { DIFFICULTY_MULTIPLIER } from '../data/mapConfigs'

type EnemyType = 'FreshGraduate' | 'OldEmployee' | 'TroubleMaker' | 'BossVP'

interface WaveCallbacks {
  onWaveComplete: () => void
  onAllWavesComplete: () => void
  onDestroyRandomTower: () => void
}

export class WaveManager {
  private scene: Phaser.Scene
  private activeEnemies: EnemyBase[] = []
  private pathPoints: PathPoint[]
  private currentWave: number = 0
  private isSpawning: boolean = false
  private waveConfigs: WaveConfigEntry[]
  private difficulty: DifficultyLevel
  private callbacks: WaveCallbacks
  private waveCompleteFired: boolean = false
  private allCompleteGuard: boolean = false

  constructor(
    scene: Phaser.Scene,
    waveConfigs: WaveConfigEntry[],
    difficulty: DifficultyLevel,
    callbacks: WaveCallbacks,
    waypoints?: readonly { x: number; y: number }[]
  ) {
    this.scene = scene
    this.waveConfigs = waveConfigs
    this.difficulty = difficulty
    this.callbacks = callbacks
    this.pathPoints = buildFullPath(waypoints)
  }

  get totalWaves(): number {
    return this.waveConfigs.length
  }

  startNextWave(): void {
    if (this.isSpawning || this.currentWave >= this.waveConfigs.length) return
    const config = this.waveConfigs[this.currentWave]
    this.currentWave++
    this.isSpawning = true
    this.spawnWave(config)
  }

  private spawnWave(config: WaveConfigEntry): void {
    const multiplier = DIFFICULTY_MULTIPLIER[this.difficulty]
    const spawnQueue: { type: EnemyType; delay: number }[] = []

    for (const group of config.enemies) {
      const count = Math.ceil(group.count * multiplier.enemyCount)
      for (let i = 0; i < count; i++) {
        spawnQueue.push({ type: group.type, delay: group.interval * i })
      }
    }
    spawnQueue.sort((a, b) => a.delay - b.delay)

    let completed = 0
    for (const item of spawnQueue) {
      this.scene.time.delayedCall(item.delay, () => {
        this.spawnEnemy(item.type)
        completed++
        if (completed === spawnQueue.length) {
          this.isSpawning = false
        }
      })
    }

    if (spawnQueue.length === 0) this.isSpawning = false
  }

  private spawnEnemy(type: EnemyType): EnemyBase {
    const multiplier = DIFFICULTY_MULTIPLIER[this.difficulty]
    const pts = [...this.pathPoints]
    let enemy: EnemyBase

    const speedMult = multiplier.enemySpeed
    const hpMult = type === 'BossVP' ? multiplier.bossHp : 1.0

    switch (type) {
      case 'OldEmployee':
        enemy = new OldEmployee(this.scene, pts, speedMult, hpMult)
        break
      case 'TroubleMaker':
        enemy = new TroubleMaker(this.scene, pts, speedMult, hpMult)
        break
      case 'BossVP':
        enemy = new BossVP(this.scene, pts, this.callbacks.onDestroyRandomTower, speedMult, hpMult)
        break
      default:
        enemy = new FreshGraduate(this.scene, pts, speedMult, hpMult)
    }

    this.scene.time.delayedCall(1000 + Math.random() * 2000, () => {
      if (!enemy.isDead) enemy.showQuote()
    })

    this.activeEnemies.push(enemy)
    return enemy
  }

  update(delta: number): void {
    for (let i = this.activeEnemies.length - 1; i >= 0; i--) {
      const e = this.activeEnemies[i]
      if (e.isDead) {
        this.activeEnemies.splice(i, 1)
        continue
      }
      e.update(delta)
    }

    // 中途波次完成回调（用于触发周报等）
    if (
      this.currentWave === 3 &&
      !this.isSpawning &&
      this.activeEnemies.length === 0 &&
      !this.waveCompleteFired
    ) {
      this.waveCompleteFired = true
      this.callbacks.onWaveComplete()
    }

    // 全部波次完成
    if (
      this.currentWave >= this.waveConfigs.length &&
      !this.isSpawning &&
      this.activeEnemies.length === 0 &&
      !this.allCompleteGuard
    ) {
      this.allCompleteGuard = true
      this.callbacks.onAllWavesComplete()
    }
  }

  getAllActiveEnemies(): EnemyBase[] {
    return this.activeEnemies
  }

  hasMoreWaves(): boolean {
    return this.currentWave < this.waveConfigs.length
  }

  getCurrentWaveNumber(): number {
    return this.currentWave
  }

  /** 清除所有活跃怪物（切图时调用） */
  clearAllEnemies(): void {
    for (const e of this.activeEnemies) {
      if (!e.isDead) e.destroy()
    }
    this.activeEnemies = []
  }
}
