import type Phaser from 'phaser'
import { GameManager } from '../GameManager'
import { HUD_HEIGHT, COFFEE_COST, STAMINA_MAX, STAMINA_REGEN } from '../constants'
import { getCellSize } from '../mapRenderer'
import type { EnemyBase } from '../enemies/EnemyBase'

export abstract class TowerBase {
  protected scene: Phaser.Scene
  public gridX: number
  public gridY: number
  protected imageSprite!: Phaser.GameObjects.Image
  protected spriteKey: string
  protected staminaBar!: Phaser.GameObjects.Graphics
  private frozenOverlay!: Phaser.GameObjects.Graphics

  public readonly cost: number
  public readonly attackRange: number
  public readonly attackDamage: number
  public readonly attackSpeed: number
  public readonly maxStamina: number = STAMINA_MAX
  public stamina: number = STAMINA_MAX
  public isFrozen: boolean = false

  protected attackCooldown: number = 0
  protected staminaRegen: number = STAMINA_REGEN
  protected isActive: boolean = true

  // Pixel center position (computed from actual cell size)
  protected px: number
  protected py: number
  protected cellW: number
  protected cellH: number

  constructor(
    scene: Phaser.Scene,
    gridX: number,
    gridY: number,
    cost: number,
    attackRange: number,
    attackDamage: number,
    attackSpeed: number,
    spriteKey: string
  ) {
    this.scene = scene
    this.gridX = gridX
    this.gridY = gridY
    this.cost = cost
    this.attackRange = attackRange
    this.attackDamage = attackDamage
    this.attackSpeed = attackSpeed
    this.spriteKey = spriteKey

    const { cellW, cellH } = getCellSize()
    this.cellW = cellW
    this.cellH = cellH
    this.px = gridX * cellW + cellW / 2
    this.py = HUD_HEIGHT + gridY * cellH + cellH / 2

    // 用 AI 图片作为精灵，精确设为格子尺寸的 85%（留边距）
    const imgSize = cellW * 0.85
    this.imageSprite = scene.add.image(this.px, this.py, spriteKey)
    this.imageSprite.setDisplaySize(imgSize, imgSize)
    this.imageSprite.setDepth(10)

    this.staminaBar = scene.add.graphics()
    this.frozenOverlay = scene.add.graphics()
    this.updateStaminaBar()
  }

  update(delta: number, enemies: EnemyBase[]): void {
    if (this.isFrozen) {
      this.drawFrozenOverlay()
      return
    }
    this.clearFrozenOverlay()
    this.attackCooldown -= delta

    if (this.stamina <= 0) this.isActive = false

    if (!this.isActive) {
      this.stamina = Math.min(this.maxStamina, this.stamina + (this.staminaRegen * delta) / 1000)
      if (this.stamina > 20) this.isActive = true
      this.updateStaminaBar()
      // 摸鱼时图片半透明
      this.imageSprite.setAlpha(0.5)
      return
    }
    this.imageSprite.setAlpha(1)

    const target = this.findTarget(enemies)
    if (target && this.attackCooldown <= 0) {
      this.attack(target)
      this.stamina -= 5
      this.attackCooldown = 1000 / this.attackSpeed
      this.updateStaminaBar()
    } else if (!target) {
      this.stamina = Math.min(this.maxStamina, this.stamina + (this.staminaRegen * delta) / 1000)
      this.updateStaminaBar()
    }
  }

  protected findTarget(enemies: EnemyBase[]): EnemyBase | null {
    // +0.5格容忍量，避免怪物恰好在射程边界时因浮点误差漏判
    const rangePx = (this.attackRange + 0.5) * this.cellW
    let best: EnemyBase | null = null
    let bestProgress = -1
    for (const e of enemies) {
      if (e.isDead) continue
      const dx = e.x - this.px
      const dy = e.y - this.py
      const dist = Math.sqrt(dx * dx + dy * dy)
      if (dist <= rangePx) {
        if (e.pathProgress > bestProgress) {
          bestProgress = e.pathProgress
          best = e
        }
      }
    }
    return best
  }

  protected updateStaminaBar(): void {
    this.staminaBar.clear()
    const bw = this.cellW * 0.7
    const bh = 5
    const bx = this.px - bw / 2
    const by = this.py + this.cellH / 2 - 10
    this.staminaBar.fillStyle(0x1f2937, 1)
    this.staminaBar.fillRect(bx, by, bw, bh)
    const ratio = this.stamina / this.maxStamina
    const color = ratio > 0.5 ? 0xf59e0b : ratio > 0.25 ? 0xfb923c : 0xef4444
    this.staminaBar.fillStyle(color, 1)
    this.staminaBar.fillRect(bx, by, bw * ratio, bh)
    this.staminaBar.setDepth(11)
  }

  buyCoffee(): boolean {
    const manager = GameManager.getInstance()
    if (manager.spendHC(COFFEE_COST)) {
      this.stamina = this.maxStamina
      this.isActive = true
      this.imageSprite.setAlpha(1)
      this.updateStaminaBar()
      return true
    }
    return false
  }

  getPixelCenter(): { x: number; y: number } {
    return { x: this.px, y: this.py }
  }

  protected drawFrozenOverlay(): void {
    this.frozenOverlay.clear()
    const hw = this.cellW / 2
    const hh = this.cellH / 2
    this.frozenOverlay.fillStyle(0x6b7280, 0.55)
    this.frozenOverlay.fillRect(this.px - hw, this.py - hh, this.cellW, this.cellH)
    this.frozenOverlay.setDepth(13)
    this.imageSprite.setTint(0x9ca3af)
  }

  protected clearFrozenOverlay(): void {
    this.frozenOverlay.clear()
    this.imageSprite.clearTint()
  }

  abstract attack(target: EnemyBase): void

  destroy(): void {
    this.imageSprite?.destroy()
    this.staminaBar?.destroy()
    this.frozenOverlay?.destroy()
  }
}
