import Phaser from "phaser";
import type { World, CombatantActor, Item, Vec2, EntityId } from "../../core/types";
import { TILE_SIZE } from "../../core/constants";
import { GAME_CONFIG } from "../../core/config/GameConfig";
import { traceProjectile, getClosestVisibleEnemy } from "../../engine/gameplay/CombatLogic";
import type { EntityManager } from "../../engine/EntityManager";

/**
 * Manages targeting mode for thrown items.
 * Extracted from GameScene to isolate targeting logic and reduce complexity.
 */
export class TargetingSystem {
  private graphics: Phaser.GameObjects.Graphics;
  private active: boolean = false;
  private targetingItemId: string | null = null;
  private cursor: Vec2 | null = null;

  constructor(graphics: Phaser.GameObjects.Graphics) {
    this.graphics = graphics;
  }

  /**
   * Start targeting mode for a throwable item
   */
  startTargeting(
    itemId: string,
    playerPos: Vec2,
    world: World,
    seenArray: Uint8Array,
    worldWidth: number
  ): void {
    this.targetingItemId = itemId;
    this.active = true;

    // Auto-target closest visible enemy
    const closest = getClosestVisibleEnemy(world, playerPos, seenArray, worldWidth);

    if (closest) {
      this.cursor = closest;
    } else {
      this.cursor = null;
    }

    this.drawLine(playerPos);
    console.log("Targeting Mode: ON");
  }

  /**
   * Update the targeting cursor position
   */
  updateCursor(worldPos: Vec2, playerPos: Vec2): void {
    if (!this.active) return;

    this.cursor = { x: worldPos.x, y: worldPos.y };
    this.drawLine(playerPos);
  }

  /**
   * Execute the throw action
   */
  executeThrow(
    world: World,
    playerId: EntityId,
    entityManager: EntityManager,
    onProjectileComplete: (blockedPos: Vec2, hitActorId: EntityId | undefined, item: Item) => void
  ): boolean {
    if (!this.active || !this.targetingItemId || !this.cursor) {
      return false;
    }

    const player = world.actors.get(playerId) as CombatantActor;
    if (!player || !player.inventory) return false;

    const itemIdx = player.inventory.items.findIndex(it => it.id === this.targetingItemId);
    if (itemIdx === -1) {
      console.log("Item not found!");
      this.cancel();
      return false;
    }

    const item = player.inventory.items[itemIdx];
    // Remove item from inventory before throw
    player.inventory.items.splice(itemIdx, 1);

    const start = player.pos;
    const end = { x: this.cursor.x, y: this.cursor.y };

    const result = traceProjectile(world, start, end, entityManager, playerId);
    const { blockedPos, hitActorId } = result;

    // Call the callback with throw results
    onProjectileComplete(blockedPos, hitActorId, item);

    return true;
  }

  /**
   * Cancel targeting mode
   */
  cancel(): void {
    this.active = false;
    this.targetingItemId = null;
    this.cursor = null;
    this.graphics.clear();
    console.log("Targeting cancelled");
  }

  /**
   * Check if targeting is currently active
   */
  get isActive(): boolean {
    return this.active;
  }

  /**
   * Get the ID of the item being targeted
   */
  get itemId(): string | null {
    return this.targetingItemId;
  }

  /**
   * Get the current cursor position
   */
  get cursorPos(): Vec2 | null {
    return this.cursor;
  }

  /**
   * Draw targeting line from player to cursor
   */
  private drawLine(playerPos: Vec2): void {
    if (!this.cursor) {
      this.graphics.clear();
      return;
    }

    this.graphics.clear();

    const startX = playerPos.x * TILE_SIZE + TILE_SIZE / 2;
    const startY = playerPos.y * TILE_SIZE + TILE_SIZE / 2;

    const endX = this.cursor.x * TILE_SIZE + TILE_SIZE / 2;
    const endY = this.cursor.y * TILE_SIZE + TILE_SIZE / 2;

    this.graphics.lineStyle(
      GAME_CONFIG.ui.targetingLineWidth,
      GAME_CONFIG.ui.targetingLineColor,
      GAME_CONFIG.ui.targetingLineAlpha
    );
    this.graphics.lineBetween(startX, startY, endX, endY);

    this.graphics.strokeRect(
      this.cursor.x * TILE_SIZE,
      this.cursor.y * TILE_SIZE,
      TILE_SIZE,
      TILE_SIZE
    );
  }
}
