import type Phaser from 'phaser'
import { GameManager } from '../GameManager'
import { TILE_SIZE, HUD_HEIGHT, COFFEE_COST } from '../constants'
import { PATH_TILES } from '../mapRenderer'
import type { EnemyBase } from '../enemies/EnemyBase'
import { TowerBase } from './TowerBase'
import { InternTower } from './InternTower'
import { SeniorDevTower } from './SeniorDevTower'
import { PPTMasterTower } from './PPTMasterTower'
import { HRBPTower } from './HRBPTower'

export type TowerType = 'intern' | 'senior' | 'ppt' | 'hrbp'

export const TOWER_COSTS: Record<TowerType, number> = {
  intern: 50,
  senior: 120,
  ppt: 100,
  hrbp: 80,
}

export class TowerManager {
  private scene: Phaser.Scene
  private towers: TowerBase[] = []
  private occupiedCells: Set<string> = new Set()
  private infoLabel: Phaser.GameObjects.Text | null = null

  constructor(scene: Phaser.Scene) {
    this.scene = scene
  }

  canPlace(gridX: number, gridY: number): boolean {
    const key = `${gridX},${gridY}`
    return !PATH_TILES.has(key) && !this.occupiedCells.has(key)
  }

  placeTower(gridX: number, gridY: number, type: TowerType): boolean {
    if (!this.canPlace(gridX, gridY)) return false

    const cost = TOWER_COSTS[type]
    const manager = GameManager.getInstance()
    if (!manager.spendHC(cost)) return false

    const tower = this.createTower(type, gridX, gridY)
    this.towers.push(tower)
    this.occupiedCells.add(`${gridX},${gridY}`)

    // 监听实习生自毁事件
    if (tower instanceof InternTower) {
      tower.onSelfDestroy = (t) => this.removeTower(t)
    }

    return true
  }

  private createTower(type: TowerType, gridX: number, gridY: number): TowerBase {
    switch (type) {
      case 'senior':
        return new SeniorDevTower(this.scene, gridX, gridY)
      case 'ppt':
        return new PPTMasterTower(this.scene, gridX, gridY)
      case 'hrbp':
        return new HRBPTower(this.scene, gridX, gridY)
      default:
        return new InternTower(this.scene, gridX, gridY)
    }
  }

  update(delta: number, enemies: EnemyBase[]): void {
    // 更新 HRBP 的周围塔列表
    for (const tower of this.towers) {
      if (tower instanceof HRBPTower) {
        const nearby = this.getTowersNear(tower.gridX, tower.gridY, 1, tower)
        tower.setNearbyTowers(nearby)
      }
    }

    for (const tower of this.towers) {
      if (tower instanceof PPTMasterTower) {
        // PPT 大师特殊更新：如果可以攻击就 AOE
        this.updatePPTTower(tower, delta, enemies)
      } else {
        tower.update(delta, enemies)
      }
    }
  }

  private updatePPTTower(
    tower: PPTMasterTower,
    delta: number,
    enemies: EnemyBase[]
  ): void {
    // 直接调用 super 逻辑（手动处理冷却）
    tower['attackCooldown'] -= delta

    if (tower['stamina'] <= 0) tower['isActive'] = false

    if (!tower['isActive']) {
      tower['stamina'] = Math.min(
        tower.maxStamina,
        tower['stamina'] + (tower['staminaRegen'] * delta) / 1000
      )
      if (tower['stamina'] > 20) tower['isActive'] = true
      tower['updateStaminaBar']()
      return
    }

    const hasTarget = enemies.some((e) => {
      if (e.isDead) return false
      const dx = e.sprite.x - tower['px']
      const dy = e.sprite.y - tower['py']
      return Math.sqrt(dx * dx + dy * dy) <= tower.attackRange * TILE_SIZE
    })

    if (hasTarget && tower['attackCooldown'] <= 0) {
      tower.attackAoe(enemies)
      tower['stamina'] -= 5
      tower['attackCooldown'] = 1000 / tower.attackSpeed
      tower['updateStaminaBar']()
    } else if (!hasTarget) {
      tower['stamina'] = Math.min(
        tower.maxStamina,
        tower['stamina'] + (tower['staminaRegen'] * delta) / 1000
      )
      tower['updateStaminaBar']()
    }
  }

  private getTowersNear(
    gx: number,
    gy: number,
    range: number,
    exclude: TowerBase
  ): TowerBase[] {
    return this.towers.filter(
      (t) =>
        t !== exclude &&
        Math.abs(t.gridX - gx) <= range &&
        Math.abs(t.gridY - gy) <= range
    )
  }

  /** 点击格子时检查是否有塔，显示信息 */
  handleTileClick(gridX: number, gridY: number): boolean {
    const tower = this.getTowerAt(gridX, gridY)
    if (!tower) return false
    this.showTowerInfo(tower)
    return true
  }

  private showTowerInfo(tower: TowerBase): void {
    this.infoLabel?.destroy()

    const px = tower.gridX * TILE_SIZE + TILE_SIZE / 2
    const py = tower.gridY * TILE_SIZE + TILE_SIZE / 2 + HUD_HEIGHT

    const label = this.scene.add
      .text(
        px,
        py - 40,
        `精力: ${Math.floor(tower.stamina)}%  [点击购买咖啡 ${COFFEE_COST}HC]`,
        {
          fontFamily: 'VT323, monospace',
          fontSize: '14px',
          color: '#F59E0B',
          backgroundColor: '#0A1628',
          padding: { x: 6, y: 3 },
        }
      )
      .setOrigin(0.5, 1)
      .setDepth(30)
      .setInteractive()

    label.on('pointerdown', () => {
      const ok = tower.buyCoffee()
      if (ok) {
        label.setText(`☕ 喝了咖啡！精力满了！`)
        this.scene.time.delayedCall(1000, () => label.destroy())
      } else {
        label.setText('HC 不足！')
        this.scene.time.delayedCall(800, () => label.destroy())
      }
    })

    this.infoLabel = label
    this.scene.time.delayedCall(3000, () => {
      if (this.infoLabel === label) this.infoLabel = null
      label.destroy()
    })
  }

  getTowerAt(gridX: number, gridY: number): TowerBase | null {
    return (
      this.towers.find((t) => t.gridX === gridX && t.gridY === gridY) ?? null
    )
  }

  removeTower(tower: TowerBase): void {
    const idx = this.towers.indexOf(tower)
    if (idx !== -1) {
      this.towers.splice(idx, 1)
      this.occupiedCells.delete(`${tower.gridX},${tower.gridY}`)
    }
  }

  removeRandomTower(): void {
    if (this.towers.length === 0) return
    const idx = Math.floor(Math.random() * this.towers.length)
    const tower = this.towers[idx]
    this.showDestroyEffect(tower)
    tower.destroy()
    this.removeTower(tower)
  }

  private showDestroyEffect(tower: TowerBase): void {
    const { x, y } = tower.getPixelCenter()
    const txt = this.scene.add
      .text(x, y - 20, '☠ 组织架构调整！被裁了！', {
        fontFamily: 'VT323, monospace',
        fontSize: '16px',
        color: '#EF4444',
        backgroundColor: '#7F1D1D',
        padding: { x: 6, y: 3 },
      })
      .setOrigin(0.5, 1)
      .setDepth(30)
    this.scene.tweens.add({
      targets: txt,
      y: y - 60,
      alpha: 0,
      duration: 2000,
      onComplete: () => txt.destroy(),
    })
  }

  getAllTowers(): TowerBase[] {
    return this.towers
  }

  hasTowerAt(gridX: number, gridY: number): boolean {
    return this.occupiedCells.has(`${gridX},${gridY}`)
  }

  getOccupiedCells(): Set<string> {
    return this.occupiedCells
  }
}
