import Phaser from "phaser";
import { TILE_SIZE } from "../../core/constants";
import { GAME_CONFIG } from "../../core/config/GameConfig";

/**
 * Manages camera controls including zoom, panning, and follow mode.
 * Extracted from GameScene to reduce complexity and improve testability.
 */
export class CameraController {
  private camera: Phaser.Cameras.Scene2D.Camera;
  private followMode: boolean = true;

  constructor(camera: Phaser.Cameras.Scene2D.Camera) {
    this.camera = camera;
  }

  /**
   * Enable follow mode - camera will track the target entity
   */
  enableFollowMode(): void {
    this.followMode = true;
  }

  /**
   * Disable follow mode - camera stays at current position
   */
  disableFollowMode(): void {
    this.followMode = false;
  }

  /**
   * Check if camera is in follow mode
   */
  get isFollowing(): boolean {
    return this.followMode;
  }

  /**
   * Center camera on a specific world position (in pixels)
   */
  centerOn(worldX: number, worldY: number): void {
    this.camera.centerOn(worldX, worldY);
  }

  /**
   * Center camera on a tile position
   */
  centerOnTile(tileX: number, tileY: number): void {
    const worldX = tileX * TILE_SIZE + TILE_SIZE / 2;
    const worldY = tileY * TILE_SIZE + TILE_SIZE / 2;
    this.camera.centerOn(worldX, worldY);
  }

  /**
   * Handle mouse wheel zoom
   * @param deltaY - Wheel delta (positive = zoom out, negative = zoom in)
   */
  handleWheel(deltaY: number): void {
    const zoomDir = deltaY > 0 ? -1 : 1;
    const newZoom = Phaser.Math.Clamp(
      this.camera.zoom + zoomDir * GAME_CONFIG.rendering.zoomStep,
      GAME_CONFIG.rendering.minZoom,
      GAME_CONFIG.rendering.maxZoom
    );
    this.camera.setZoom(newZoom);
  }

  /**
   * Handle camera panning via drag
   * @param dx - Change in x position
   * @param dy - Change in y position
   */
  handlePan(dx: number, dy: number): void {
    this.camera.scrollX -= dx;
    this.camera.scrollY -= dy;
    this.disableFollowMode();
  }

  /**
   * Set camera bounds (usually to match world size)
   */
  setBounds(x: number, y: number, width: number, height: number): void {
    this.camera.setBounds(x, y, width, height);
  }
}
