import type Phaser from 'phaser'
import { MAP_COLS, MAP_ROWS, HUD_HEIGHT, GAME_HEIGHT, GAME_WIDTH } from './constants'
import { GameManager } from './GameManager'
import {
  buildPathTiles,
  getCellSize,
  drawAllTiles,
  renderMapLabels,
  renderMapBackground,
  renderDecorations,
  renderHUD,
  updateKPIBar,
  BAR_X, BAR_Y, BAR_W, BAR_H,
} from './mapRenderer'
import { TowerManager, type TowerType } from './towers/TowerManager'
import { WaveManager } from './enemies/WaveManager'
import { HUD } from './ui/HUD'
import { WeeklyReportModal } from './ui/WeeklyReportModal'
import { MapTransitionModal } from './ui/MapTransitionModal'
import { ALL_MAPS, type MapConfig } from './data/mapConfigs'
import { AudioEngine } from './AudioEngine'

void MAP_ROWS; void GAME_HEIGHT; void GAME_WIDTH; void BAR_X; void BAR_Y; void BAR_W; void BAR_H

/** 所有游戏精灵的 key → public path 映射 */
const SPRITE_ASSETS: Record<string, string> = {
  'tower-intern':     '/game-assets/tower-intern.png',
  'tower-senior':     '/game-assets/tower-senior.png',
  'tower-ppt':        '/game-assets/tower-ppt.png',
  'tower-hrbp':       '/game-assets/tower-hrbp.png',
  'tower-pm':         '/game-assets/tower-pm.png',
  'tower-ops':        '/game-assets/tower-ops.png',
  'tower-outsource':  '/game-assets/tower-outsource.png',
  'enemy-fresh':      '/game-assets/enemy-fresh.png',
  'enemy-old':        '/game-assets/enemy-old.png',
  'enemy-trouble':    '/game-assets/enemy-trouble.png',
  'enemy-boss':       '/game-assets/enemy-boss.png',
  'deco-coffee':      '/game-assets/deco-coffee.png',
  'deco-monitor':     '/game-assets/deco-monitor.png',
  'deco-desk':        '/game-assets/deco-desk.png',
}

export function createGameScene(PhaserLib: typeof Phaser): typeof Phaser.Scene {
  class GameScene extends PhaserLib.Scene {
    private manager!: GameManager
    private kpiBar!: Phaser.GameObjects.Graphics
    private kpiText!: Phaser.GameObjects.Text
    private hcText!: Phaser.GameObjects.Text
    private hoveredTile: { col: number; row: number } | null = null
    private tileGraphics!: Phaser.GameObjects.Graphics
    private towerManager!: TowerManager
    private waveManager!: WaveManager
    private hud!: HUD
    private weeklyModal!: WeeklyReportModal
    private mapTransitionModal!: MapTransitionModal
    private selectedTowerType: TowerType | null = null
    private buildModeGraphics!: Phaser.GameObjects.Graphics
    private isWaveRunning: boolean = false

    // 多地图状态
    private currentPathTiles: Set<string> = new Set()
    private decorationObjects: Phaser.GameObjects.Image[] = []
    private labelObjects: Phaser.GameObjects.Text[] = []
    private bgObject: Phaser.GameObjects.Image | null = null
    private mapInTransition: boolean = false

    // 暂停遮罩
    private pauseOverlay: Phaser.GameObjects.Graphics | null = null
    private pauseText: Phaser.GameObjects.Text | null = null

    constructor() { super({ key: 'GameScene' }) }

    preload(): void {
      for (const [key, path] of Object.entries(SPRITE_ASSETS)) {
        this.load.image(key, path)
      }
      // 预加载所有地图背景
      for (const map of ALL_MAPS) {
        if (!this.textures.exists(map.bgKey)) {
          this.load.image(map.bgKey, map.bgPath)
        }
      }
    }

    create(): void {
      this.manager = GameManager.getInstance()
      this.manager.reset()

      // 读取难度
      if (typeof window !== 'undefined') {
        const diff = (window as any).__gameDifficulty
        if (diff === 'easy' || diff === 'normal' || diff === 'hard') {
          this.manager.setDifficulty(diff)
        }
      }

      this.manager.gameState = 'playing'

      this.tileGraphics = this.add.graphics()
      this.buildModeGraphics = this.add.graphics().setDepth(5)
      const hudObjs = renderHUD(this)
      this.kpiBar = hudObjs.kpiBar
      this.kpiText = hudObjs.kpiText
      this.hcText = hudObjs.hcText

      this.towerManager = new TowerManager(this)
      this.weeklyModal = new WeeklyReportModal({
        onBossInspection: () => this.freezeAllTowers(3000),
        onFullStamina:    () => this.refillAllStamina(),
      })
      this.mapTransitionModal = new MapTransitionModal()

      this.hud = new HUD(this)
      this.hud.createWaveButton(() => this.onWaveButtonClick())
      this.loadMap(ALL_MAPS[0])

      if (typeof window !== 'undefined') {
        ;(window as any).__gameSelectTower = (type: TowerType | null) => {
          this.selectedTowerType = type
          if (!type) this.buildModeGraphics.clear()
        }
      }

      // 初始化音效引擎（首次点击后激活 AudioContext，默认开启）
      const audio = AudioEngine.getInstance()
      this.input.once('pointerdown', () => {
        audio.init()
        audio.startBGM()
      })

      // 注册 PUA buff 接口 + HC 查询/扣除接口 + 暂停/恢复接口
      if (typeof window !== 'undefined') {
        ;(window as any).__gamePuaBuff = (
          effect: string, score: number, title: string
        ) => { this.applyPuaBuff(effect, score, title) }

        ;(window as any).__gameGetHC = () => this.manager.hc
        ;(window as any).__gameSpendHC = (amount: number): boolean =>
          this.manager.spendHC(amount)

        ;(window as any).__gamePause = (): boolean => {
          if (!this.manager.pause()) return false
          this.showPauseOverlay()
          // 暂停 Phaser 物理与 Tween
          this.physics.pause()
          this.tweens.pauseAll()
          return true
        }

        ;(window as any).__gameResume = (): boolean => {
          if (!this.manager.resume()) return false
          this.hidePauseOverlay()
          this.physics.resume()
          this.tweens.resumeAll()
          return true
        }

        ;(window as any).__gameIsPaused = (): boolean => this.manager.isPaused
      }

      this.setupInteraction()
      this.setupManagerCallbacks()
      if (typeof window !== 'undefined') { ;(window as any).__gameReady?.() }
    }

    private createMuteButton(_audio: AudioEngine): void {
      void _audio
    }

    private showPauseOverlay(): void {
      const { width, height } = this.scale
      // 半透明深色遮罩
      this.pauseOverlay = this.add.graphics().setDepth(90)
      this.pauseOverlay.fillStyle(0x000000, 0.6)
      this.pauseOverlay.fillRect(0, 0, width, height)

      // "开会中" 提示卡片
      this.pauseText = this.add.text(width / 2, height / 2, '📋  开会中...\n游戏已暂停', {
        fontFamily: 'VT323, monospace',
        fontSize: '32px',
        color: '#FCD34D',
        backgroundColor: '#1e3a5f',
        padding: { x: 32, y: 18 },
        align: 'center',
      }).setOrigin(0.5, 0.5).setDepth(91)
    }

    private hidePauseOverlay(): void {
      this.pauseOverlay?.destroy()
      this.pauseOverlay = null
      this.pauseText?.destroy()
      this.pauseText = null
    }

    /**
     * 应用 PUA buff 效果到游戏
     * effect: attack_boost | speed_boost | money_rain | rage_mode | backfire
     */
    private applyPuaBuff(effect: string, score: number, title: string): void {
      const towers = this.towerManager.getAllTowers()
      const audio = AudioEngine.getInstance()

      // 全屏效果提示横幅
      const colors: Record<string, string> = {
        rage_mode:    '#FF4E00',
        speed_boost:  '#FBBF24',
        attack_boost: '#22C55E',
        money_rain:   '#A78BFA',
        backfire:     '#6B7280',
      }
      const color = colors[effect] ?? '#E2E8F0'
      this.showPuaBanner(title, score, color)

      const dur = Math.max(8000, score * 1500) // buff 持续时间（ms）

      switch (effect) {
        case 'rage_mode': {
          // 9-10分：全场狂暴 — 攻速×2，全图红色相机震动
          audio.playBossAppear()
          this.cameras.main.flash(600, 255, 60, 0, false)
          this.cameras.main.shake(400, 0.008)
          towers.forEach(t => { t['_puaSpeedMult'] = 2.0 })
          this.manager.addHC(score * 15)
          this.time.delayedCall(dur, () => {
            towers.forEach(t => { t['_puaSpeedMult'] = 1.0 })
          })
          break
        }
        case 'speed_boost': {
          // 7-8分：攻速 ×1.5
          audio.playWaveStart()
          towers.forEach(t => { t['_puaSpeedMult'] = 1.5 })
          this.time.delayedCall(dur, () => {
            towers.forEach(t => { t['_puaSpeedMult'] = 1.0 })
          })
          break
        }
        case 'attack_boost': {
          // 4-6分：伤害 ×(1 + score*0.08)
          audio.playDingTalk()
          const mult = 1 + score * 0.08
          towers.forEach(t => { t['_puaDmgMult'] = mult })
          this.time.delayedCall(dur, () => {
            towers.forEach(t => { t['_puaDmgMult'] = 1.0 })
          })
          break
        }
        case 'money_rain': {
          // 5-7分：立即获得 HC，屏幕绿色雨
          const hcBonus = score * 20
          this.manager.addHC(hcBonus)
          audio.playOpsAttack()
          this.showMoneyRain(hcBonus)
          break
        }
        case 'backfire': {
          // 1-2分：废话反效果 — 全场塔禁锢 2 秒
          audio.playEnemyDeath()
          this.cameras.main.shake(300, 0.005)
          this.freezeAllTowers(2000)
          break
        }
      }
    }

    /** 显示 PUA buff 横幅 */
    private showPuaBanner(title: string, score: number, color: string): void {
      const stars = '★'.repeat(Math.min(score, 10))
      const banner = this.add.text(
        GAME_WIDTH / 2, HUD_HEIGHT + 80,
        `${title}  ${stars}`,
        {
          fontFamily: 'VT323, monospace',
          fontSize: '28px',
          color,
          stroke: '#000000',
          strokeThickness: 4,
          shadow: { offsetX: 0, offsetY: 0, color, blur: 16, stroke: true, fill: true },
        }
      ).setOrigin(0.5, 0.5).setDepth(60).setAlpha(0)

      this.tweens.add({
        targets: banner,
        alpha: 1,
        y: HUD_HEIGHT + 60,
        duration: 300,
        yoyo: false,
        onComplete: () => {
          this.time.delayedCall(2000, () => {
            this.tweens.add({
              targets: banner, alpha: 0, y: HUD_HEIGHT + 40,
              duration: 400, onComplete: () => banner.destroy(),
            })
          })
        },
      })
    }

    /** 金币雨效果（money_rain） */
    private showMoneyRain(amount: number): void {
      for (let i = 0; i < 12; i++) {
        const x = Math.random() * GAME_WIDTH
        const coin = this.add.text(x, HUD_HEIGHT + 20, `+${Math.floor(amount / 12)}HC`, {
          fontFamily: 'VT323, monospace',
          fontSize: '16px',
          color: '#A78BFA',
          stroke: '#000',
          strokeThickness: 2,
        }).setOrigin(0.5, 0).setDepth(55).setAlpha(0.9)
        this.tweens.add({
          targets: coin,
          y: coin.y + 120 + Math.random() * 80,
          alpha: 0,
          delay: i * 80,
          duration: 900,
          onComplete: () => coin.destroy(),
        })
      }
    }

    private setupManagerCallbacks(): void {
      this.manager.onHCChange.push((hc: number) => {
        this.hcText.setText(`HC: ${hc}`)
        if (typeof window !== 'undefined') { ;(window as any).__gameOnHCChange?.(hc) }
      })
      this.manager.onKPIChange.push((kpi: number) => {
        updateKPIBar(this.kpiBar, kpi)
        this.kpiText.setText(`${kpi}%`)
        // KPI 危险时播放警告音（每次低于 30% 时触发一次）
        if (kpi <= 30 && kpi > 0) {
          AudioEngine.getInstance().playKPIWarning()
        }
      })
      this.manager.onGameOver.push(() => { this.hud.showGameOver() })
      this.manager.onVictory.push(() => { this.hud.showVictory() })
    }

    /**
     * 加载指定地图：渲染背景、路径、装饰物，重置 WaveManager
     */
    private loadMap(mapConfig: MapConfig): void {
      this.currentPathTiles = buildPathTiles(mapConfig.waypoints)
      // 同步路径格给 TowerManager，用于建塔合法性判断
      this.towerManager.setCurrentPathTiles(this.currentPathTiles)
      this.bgObject?.destroy()
      this.bgObject = renderMapBackground(this, mapConfig.bgKey)
      drawAllTiles(this.tileGraphics, null, this.currentPathTiles, mapConfig)
      this.labelObjects.forEach(l => l.destroy())
      this.labelObjects = renderMapLabels(this, mapConfig.labels)
      this.decorationObjects.forEach(d => d.destroy())
      this.decorationObjects = renderDecorations(this, mapConfig.decorations, this.currentPathTiles)
      this.waveManager = new WaveManager(
        this, mapConfig.waves, this.manager.difficulty,
        {
          onWaveComplete:       () => this.onWeeklyReport(),
          onAllWavesComplete:   () => this.onMapCleared(),
          onDestroyRandomTower: () => this.towerManager.removeRandomTower(),
        },
        mapConfig.waypoints
      )
      this.mapInTransition = false
      this.isWaveRunning = false
    }

    // 自动下一波倒计时（ms），-1 表示未激活
    private autoNextWaveTimer: number = -1
    private readonly AUTO_WAVE_DELAY = 2000  // 自动开始等待：3s→2s，缩短喘息时间

    update(_time: number, delta: number): void {
      if (this.manager.gameState === 'paused') return   // 暂停时完全跳过
      if (this.manager.gameState !== 'playing' && this.manager.gameState !== 'idle') return
      if (this.mapInTransition) return

      this.towerManager.update(delta, this.waveManager.getAllActiveEnemies())
      this.waveManager.update(delta)

      // 当前波次怪物全灭且还有下一波时，启动自动倒计时
      if (
        this.isWaveRunning &&
        this.waveManager.getAllActiveEnemies().length === 0 &&
        this.waveManager.hasMoreWaves()
      ) {
        this.isWaveRunning = false
        if (this.autoNextWaveTimer < 0) {
          this.autoNextWaveTimer = this.AUTO_WAVE_DELAY
          this.hud.setWaveButtonText('3s 后自动开始...')
          this.hud.enableWaveButton()
        }
      }

      // 自动倒计时
      if (this.autoNextWaveTimer > 0) {
        this.autoNextWaveTimer -= delta
        const sec = Math.ceil(this.autoNextWaveTimer / 1000)
        this.hud.setWaveButtonText(`${sec}s 后自动开始...`)
        if (this.autoNextWaveTimer <= 0) {
          this.autoNextWaveTimer = -1
          this.onWaveButtonClick()
        }
      }
    }

    private onWaveButtonClick(): void {
      if (!this.waveManager.hasMoreWaves() || this.isWaveRunning || this.mapInTransition) return
      this.autoNextWaveTimer = -1
      this.isWaveRunning = true
      this.hud.disableWaveButton()
      this.hud.setWaveButtonText('波次进行中...')
      this.waveManager.startNextWave()
      const waveNum = this.waveManager.getCurrentWaveNumber()
      this.hud.showWaveBanner(waveNum, this.waveManager.totalWaves)
      AudioEngine.getInstance().playWaveStart()
      // 通知 React 层：战斗已开始，允许发起激励
      if (typeof window !== 'undefined') {
        ;(window as any).__gameWaveStarted = true
      }
    }

    private onWeeklyReport(): void {
      this.hud.showWeeklyReportAlert()
      this.time.delayedCall(600, () => { this.weeklyModal.show() })
    }

    private onMapCleared(): void {
      // 若游戏已失败，不触发地图切换
      if (this.manager.gameState === 'defeat') return

      this.mapInTransition = true
      this.autoNextWaveTimer = -1
      this.isWaveRunning = false
      this.hud.disableWaveButton()
      this.hud.setWaveButtonText('关卡完成！')
      const currentMap = ALL_MAPS[this.manager.currentMapIndex]
      const nextIndex = this.manager.currentMapIndex + 1
      if (nextIndex >= ALL_MAPS.length) {
        this.manager.totalWaveCleared += currentMap.waveCount
        this.mapTransitionModal.show(currentMap, () => { this.manager.triggerVictory() })
        return
      }
      this.mapTransitionModal.show(currentMap, () => {
        this.manager.totalWaveCleared += currentMap.waveCount
        this.manager.currentMapIndex = nextIndex
        this.waveManager.clearAllEnemies()
        // 清除上一关所有防御塔
        this.towerManager.clearAllTowers()
        // 重置 HC：每关重新开始，不带入上关余量
        this.manager.resetHC()
        this.loadMap(ALL_MAPS[nextIndex])
        this.hud.enableWaveButton()
        this.hud.setWaveButtonText('▶ 召唤下一波')
      })
    }

    freezeAllTowers(duration: number = 3000): void {
      this.towerManager.getAllTowers().forEach(tower => {
        tower.isFrozen = true
        setTimeout(() => { tower.isFrozen = false }, duration)
      })
    }

    refillAllStamina(): void {
      this.towerManager.getAllTowers().forEach(tower => {
        tower.stamina = tower.maxStamina
        tower['isActive'] = true
      })
    }

    private setupInteraction(): void {
      const { cellW, cellH } = getCellSize()
      this.input.on('pointermove', (pointer: Phaser.Input.Pointer) => {
        const col = Math.floor(pointer.x / cellW)
        const row = Math.floor((pointer.y - HUD_HEIGHT) / cellH)
        const inBounds = col >= 0 && col < MAP_COLS && row >= 0 && row < MAP_ROWS
        if (inBounds && !this.currentPathTiles.has(`${col},${row}`)) {
          if (!this.hoveredTile || this.hoveredTile.col !== col || this.hoveredTile.row !== row) {
            this.hoveredTile = { col, row }
            drawAllTiles(this.tileGraphics, this.hoveredTile, this.currentPathTiles, ALL_MAPS[this.manager.currentMapIndex])
          }
          if (this.selectedTowerType) this.drawBuildPreview(col, row, cellW, cellH)
          return
        }
        if (this.hoveredTile !== null) {
          this.hoveredTile = null
          drawAllTiles(this.tileGraphics, null, this.currentPathTiles, ALL_MAPS[this.manager.currentMapIndex])
          this.buildModeGraphics.clear()
        }
      })
      this.input.on('pointerdown', (pointer: Phaser.Input.Pointer) => {
        const col = Math.floor(pointer.x / cellW)
        const row = Math.floor((pointer.y - HUD_HEIGHT) / cellH)
        if (col >= 0 && col < MAP_COLS && row >= 0 && row < MAP_ROWS) {
          this.handleTileClick(col, row, cellW, cellH)
        }
      })
    }

    private drawBuildPreview(col: number, row: number, cellW: number, cellH: number): void {
      this.buildModeGraphics.clear()
      if (!this.towerManager.canPlace(col, row)) return
      const x = col * cellW
      const y = HUD_HEIGHT + row * cellH
      this.buildModeGraphics.lineStyle(2, 0xa78bfa, 0.9)
      this.buildModeGraphics.strokeRect(x + 2, y + 2, cellW - 4, cellH - 4)
      this.buildModeGraphics.fillStyle(0xa78bfa, 0.15)
      this.buildModeGraphics.fillRect(x + 2, y + 2, cellW - 4, cellH - 4)
    }

    private handleTileClick(col: number, row: number, cellW: number, cellH: number): void {
      if (this.selectedTowerType) {
        if (this.currentPathTiles.has(`${col},${row}`)) return
        const placed = this.towerManager.placeTower(col, row, this.selectedTowerType)
        if (placed) {
          this.buildModeGraphics.clear()
          this.selectedTowerType = null
          if (typeof window !== 'undefined') { ;(window as any).__gameOnTowerDeselect?.() }
        } else {
          this.showTip(col, row, cellW, cellH, 'HC不足或格子已占用', '#EF4444')
        }
        return
      }
      const hasTower = this.towerManager.handleTileClick(col, row)
      if (!hasTower && !this.currentPathTiles.has(`${col},${row}`)) {
        this.showTip(col, row, cellW, cellH, '请先从底部选择塔', '#A78BFA')
      }
    }

    private showTip(col: number, row: number, cellW: number, cellH: number, msg: string, color: string): void {
      const x = col * cellW + cellW / 2
      const y = HUD_HEIGHT + row * cellH + cellH / 2
      const tip = this.add.text(x, y - 20, msg, {
        fontFamily: 'VT323, monospace', fontSize: '16px',
        color, backgroundColor: '#0a1628', padding: { x: 8, y: 4 },
      }).setOrigin(0.5, 1).setDepth(20)
      this.time.delayedCall(1200, () => tip.destroy())
    }
  }

  return GameScene
}
