import Phaser from "phaser";
import { type EntityId, type ActorType } from "../core/types";
import { TILE_SIZE } from "../core/constants";
import { GAME_CONFIG } from "../core/config/GameConfig";

export class FxRenderer {
  private scene: Phaser.Scene;
  private corpseSprites: Phaser.GameObjects.Sprite[] = [];

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

  clearCorpses() {
    for (const sprite of this.corpseSprites) {
      sprite.destroy();
    }
    this.corpseSprites = [];
  }

  showDamage(x: number, y: number, amount: number, isCrit = false, isBlock = false) {
    const screenX = x * TILE_SIZE + TILE_SIZE / 2;
    const screenY = y * TILE_SIZE;

    let textStr = amount.toString();
    let color = "#ff3333";
    let fontSize = "16px";
    
    if (isCrit) {
        textStr += "!";
        color = "#ffff00";
        fontSize = "22px";
    }

    const text = this.scene.add.text(screenX, screenY, textStr, {
      fontSize,
      color,
      stroke: "#000",
      strokeThickness: 2,
      fontStyle: "bold"
    }).setOrigin(0.5, 1).setDepth(200);

    if (isBlock) {
        const blockText = this.scene.add.text(screenX + 10, screenY - 10, "Blocked", {
            fontSize: "10px",
            color: "#888888",
            fontStyle: "bold"
        }).setOrigin(0, 1).setDepth(200);
        
        this.scene.tweens.add({
            targets: blockText,
            y: screenY - 34,
            alpha: 0,
            duration: 800,
            onComplete: () => blockText.destroy()
        });
    }

    this.scene.tweens.add({
      targets: text,
      y: screenY - 24,
      alpha: 0,
      duration: isCrit ? 1200 : 800,
      ease: isCrit ? "Bounce.out" : "Power1",
      onComplete: () => text.destroy()
    });
  }

  showDodge(x: number, y: number) {
    const screenX = x * TILE_SIZE + TILE_SIZE / 2;
    const screenY = y * TILE_SIZE;

    const text = this.scene.add.text(screenX, screenY, "Dodge", {
      fontSize: "14px",
      color: "#ffffff",
      stroke: "#000",
      strokeThickness: 2,
      fontStyle: "italic"
    }).setOrigin(0.5, 1).setDepth(200);

    this.scene.tweens.add({
      targets: text,
      x: screenX + (Math.random() > 0.5 ? 20 : -20),
      y: screenY - 20,
      alpha: 0,
      duration: 600,
      onComplete: () => text.destroy()
    });
  }

  showHeal(x: number, y: number, amount: number) {
    const screenX = x * TILE_SIZE + TILE_SIZE / 2;
    const screenY = y * TILE_SIZE;

    const text = this.scene.add.text(screenX, screenY, `+${amount}`, {
      fontSize: "16px",
      color: "#33ff33",
      stroke: "#000",
      strokeThickness: 2,
      fontStyle: "bold"
    }).setOrigin(0.5, 1).setDepth(200);

    this.scene.tweens.add({
      targets: text,
      y: screenY - 30,
      alpha: 0,
      duration: 1000,
      onComplete: () => text.destroy()
    });
  }

  spawnCorpse(x: number, y: number, type: ActorType) {
    const textureKey = type === "player" ? "warrior" : type;

    const corpse = this.scene.add.sprite(
      x * TILE_SIZE + TILE_SIZE / 2,
      y * TILE_SIZE + TILE_SIZE / 2,
      textureKey,
      0
    );
    corpse.setDepth(50);
    corpse.play(`${textureKey}-die`);
    this.corpseSprites.push(corpse);
  }

  showWait(x: number, y: number) {
    const screenX = x * TILE_SIZE + TILE_SIZE / 2;
    const screenY = y * TILE_SIZE;

    const text = this.scene.add.text(screenX, screenY, "zZz", {
      fontSize: "14px",
      color: "#aaaaff",
      stroke: "#000",
      strokeThickness: 2,
      fontStyle: "bold"
    }).setOrigin(0.5, 1).setDepth(200);

    this.scene.tweens.add({
      targets: text,
      y: screenY - 20,
      alpha: 0,
      duration: 600,
      ease: "Power1",
      onComplete: () => text.destroy()
    });
  }

  collectOrb(_actorId: EntityId, amount: number, x: number, y: number) {
    const screenX = x * TILE_SIZE + TILE_SIZE / 2;
    const screenY = y * TILE_SIZE;

    const text = this.scene.add.text(screenX, screenY, `+${amount} EXP`, {
      fontSize: "14px",
      color: "#" + GAME_CONFIG.rendering.expTextColor.toString(16),
      stroke: "#000",
      strokeThickness: 2,
      fontStyle: "bold"
    }).setOrigin(0.5, 1).setDepth(200);

    this.scene.tweens.add({
      targets: text,
      y: screenY - 32,
      alpha: 0,
      duration: 1000,
      ease: "Power1",
      onComplete: () => text.destroy()
    });
  }

  showLevelUp(x: number, y: number) {
    const screenX = x * TILE_SIZE + TILE_SIZE / 2;
    const screenY = y * TILE_SIZE;

    const text = this.scene.add.text(screenX, screenY - 16, "+1 LVL", {
      fontSize: "20px",
      color: "#" + GAME_CONFIG.rendering.levelUpColor.toString(16),
      stroke: "#000",
      strokeThickness: 3,
      fontStyle: "bold"
    }).setOrigin(0.5, 1).setDepth(210);

    this.scene.tweens.add({
      targets: text,
      y: screenY - 60,
      alpha: 0,
      duration: 1500,
      ease: "Cubic.out",
      onComplete: () => text.destroy()
    });
  }

  showAlert(x: number, y: number) {
    const screenX = x * TILE_SIZE + TILE_SIZE / 2;
    const screenY = y * TILE_SIZE - 8;

    const text = this.scene.add.text(screenX, screenY, "!", {
      fontSize: "24px",
      color: "#ffaa00",
      stroke: "#000",
      strokeThickness: 3,
      fontStyle: "bold"
    }).setOrigin(0.5, 1).setDepth(210);

    // Exclamation mark stays visible for alert duration
    this.scene.tweens.add({
      targets: text,
      y: screenY - 8,
      duration: 200,
      yoyo: true,
      repeat: 3, // Bounce a few times
      ease: "Sine.inOut"
    });

    this.scene.tweens.add({
      targets: text,
      alpha: 0,
      delay: 900, // Start fading out near end of alert period
      duration: 300,
      onComplete: () => text.destroy()
    });
  }
}
