import type Phaser from 'phaser'
import { GameManager } from '../GameManager'
import { HUD_HEIGHT } from '../constants'
import { getCellSize } from '../mapRenderer'
import { AudioEngine } from '../AudioEngine'
import { ALL_MAPS } from '../data/mapConfigs'

export interface PathPoint { x: number; y: number }

function gridToPixel(gx: number, gy: number, cellW: number, cellH: number): PathPoint {
  return {
    x: gx * cellW + cellW / 2,
    y: gy * cellH + cellH / 2 + HUD_HEIGHT,
  }
}

/**
 * 将地图路径折线坐标转换为像素路径点序列
 * @param waypoints 折线关键坐标点（默认使用地图1）
 */
export function buildFullPath(
  waypoints?: readonly { x: number; y: number }[]
): PathPoint[] {
  const { cellW, cellH } = getCellSize()
  const pts = waypoints ?? ALL_MAPS[0].waypoints
  const points: PathPoint[] = []
  for (let i = 0; i < pts.length - 1; i++) {
    const from = gridToPixel(pts[i].x, pts[i].y, cellW, cellH)
    const to = gridToPixel(pts[i + 1].x, pts[i + 1].y, cellW, cellH)
    points.push(from)
    points.push(to)
  }
  return points.filter(
    (p, i, arr) => i === 0 || p.x !== arr[i - 1].x || p.y !== arr[i - 1].y
  )
}

export interface DotEffect { damage: number; duration: number; timer: number }

export abstract class EnemyBase {
  protected scene: Phaser.Scene
  protected imageSprite!: Phaser.GameObjects.Image
  public x: number = 0
  public y: number = 0
  protected healthBar!: Phaser.GameObjects.Graphics
  protected quoteText!: Phaser.GameObjects.Text

  public maxHp: number
  public hp: number
  public speed: number
  public readonly kpiDamage: number
  public readonly hcReward: number
  protected spriteKey: string

  protected pathPoints: PathPoint[]
  protected currentPathIndex: number = 0

  public isDead: boolean = false
  public isActive: boolean = true

  get pathProgress(): number { return this.currentPathIndex }

  public dotEffects: DotEffect[] = []
  public slowEffect: number = 0
  public slowTimer: number = 0
  public shieldCount: number = 0
  public hcRewardBonus: boolean = false  // 运营专员「增长黑客」双倍HC标记

  protected cellW: number
  protected cellH: number

  constructor(
    scene: Phaser.Scene,
    pathPoints: PathPoint[],
    maxHp: number,
    speed: number,
    kpiDamage: number,
    hcReward: number,
    spriteKey: string,
    speedMultiplier: number = 1.0,
    hpMultiplier: number = 1.0
  ) {
    this.scene = scene
    this.pathPoints = pathPoints
    this.maxHp = Math.ceil(maxHp * hpMultiplier)
    this.hp = this.maxHp
    this.speed = speed * speedMultiplier
    this.kpiDamage = kpiDamage
    this.hcReward = hcReward
    this.spriteKey = spriteKey

    const { cellW, cellH } = getCellSize()
    this.cellW = cellW
    this.cellH = cellH

    if (pathPoints.length > 0) {
      this.x = pathPoints[0].x
      this.y = pathPoints[0].y
    }

    const enemySize = cellW * 0.75
    this.imageSprite = scene.add.image(this.x, this.y, spriteKey)
    this.imageSprite.setDisplaySize(enemySize, enemySize)
    this.imageSprite.setDepth(10)

    this.healthBar = scene.add.graphics()

    this.quoteText = scene.add
      .text(this.x, this.y - 30, this.getQuote(), {
        fontFamily: 'VT323, monospace',
        fontSize: '13px',
        color: '#FFFFFF',
        backgroundColor: 'rgba(0,0,0,0.7)',
        padding: { x: 4, y: 2 },
      })
      .setOrigin(0.5, 1)
      .setDepth(15)
      .setAlpha(0)

    this.drawHealthBar()
    scene.time.delayedCall(500, () => { if (!this.isDead) this.showQuote() })
  }

  update(delta: number): void {
    if (this.isDead || !this.isActive) return
    this.processDOT(delta)
    if (this.slowTimer > 0) {
      this.slowTimer -= delta
      if (this.slowTimer <= 0) this.slowEffect = 0
    }
    this.moveAlongPath(delta)
    this.imageSprite.setPosition(this.x, this.y)
    this.drawHealthBar()
    if (this.quoteText?.alpha > 0) {
      this.quoteText.setPosition(this.x, this.y - (this.cellH * 0.45))
    }
  }

  protected processDOT(delta: number): void {
    for (let i = this.dotEffects.length - 1; i >= 0; i--) {
      const dot = this.dotEffects[i]
      dot.timer -= delta
      this.hp -= (dot.damage / 1000) * delta
      if (this.hp <= 0) { this.die(); return }
      if (dot.timer <= 0) this.dotEffects.splice(i, 1)
    }
  }

  protected moveAlongPath(delta: number): void {
    if (this.currentPathIndex >= this.pathPoints.length - 1) {
      this.reachEnd(); return
    }
    const target = this.pathPoints[this.currentPathIndex + 1]
    const currentSpeed = this.speed * (1 - this.slowEffect)
    const distance = (currentSpeed * delta) / 1000
    const dx = target.x - this.x
    const dy = target.y - this.y
    const dist = Math.sqrt(dx * dx + dy * dy)
    if (dist <= distance) {
      this.x = target.x; this.y = target.y
      this.currentPathIndex++
    } else {
      this.x += (dx / dist) * distance
      this.y += (dy / dist) * distance
    }
    if (this.slowEffect > 0) {
      this.imageSprite.setTint(0x93c5fd)
    } else {
      this.imageSprite.clearTint()
    }
  }

  protected drawHealthBar(): void {
    this.healthBar.clear()
    const bw = this.cellW * 0.5
    const bh = 5
    const bx = this.x - bw / 2
    const by = this.y - this.cellH * 0.45
    const ratio = Math.max(0, this.hp / this.maxHp)
    const color = ratio > 0.5 ? 0x22c55e : ratio > 0.25 ? 0xf59e0b : 0xef4444
    this.healthBar.fillStyle(0x1f2937, 1)
    this.healthBar.fillRect(bx, by, bw, bh)
    this.healthBar.fillStyle(color, 1)
    this.healthBar.fillRect(bx, by, bw * ratio, bh)
    this.healthBar.setDepth(14)
  }

  takeDamage(damage: number): void {
    if (this.isDead) return
    if (this.shieldCount > 0) {
      this.shieldCount--
      this.showShieldBlock()
      return
    }
    this.hp -= damage
    this.drawHealthBar()
    if (this.hp <= 0) this.die()
  }

  private showShieldBlock(): void {
    const txt = this.scene.add
      .text(this.x, this.y - 35, '护盾!', {
        fontFamily: 'VT323, monospace', fontSize: '14px', color: '#93C5FD',
      }).setOrigin(0.5, 1).setDepth(20)
    this.scene.tweens.add({
      targets: txt, y: this.y - 55, alpha: 0, duration: 800,
      onComplete: () => txt.destroy(),
    })
  }

  addDOT(damage: number, duration: number): void {
    this.dotEffects.push({ damage, duration, timer: duration })
  }

  addSlow(percent: number, duration: number): void {
    this.slowEffect = Math.max(this.slowEffect, percent)
    this.slowTimer = Math.max(this.slowTimer, duration)
  }

  /** 需求变更：将路径进度回退 n 个节点（PM 特殊技能） */
  rewindPath(steps: number): void {
    this.currentPathIndex = Math.max(0, this.currentPathIndex - steps)
    const target = this.pathPoints[this.currentPathIndex]
    if (target) { this.x = target.x; this.y = target.y }
  }

  protected die(): void {
    if (this.isDead) return
    this.isDead = true
    const reward = this.hcRewardBonus ? this.hcReward * 2 : this.hcReward
    GameManager.getInstance().addHC(reward)
    // 怪物死亡音效（碎纸机）
    AudioEngine.getInstance().playEnemyDeath()
    this.onDeath()
    this.destroy()
  }

  protected reachEnd(): void {
    if (this.isDead) return
    GameManager.getInstance().reduceKPI(this.kpiDamage)
    this.isDead = true
    this.destroy()
  }

  protected onDeath(): void {}

  showQuote(): void {
    if (this.isDead || !this.quoteText) return
    this.quoteText.setText(this.getQuote())
    this.quoteText.setPosition(this.x, this.y - this.cellH * 0.45)
    this.quoteText.setAlpha(1)
    this.scene.tweens.add({
      targets: this.quoteText, alpha: 0,
      duration: 800, delay: 2200, ease: 'Linear',
    })
  }

  abstract getQuote(): string

  destroy(): void {
    this.imageSprite?.destroy()
    this.healthBar?.destroy()
    this.quoteText?.destroy()
  }
}
