import Phaser from 'phaser';
import { PHYSICS } from '@/config/physics.config';
import { EnemyState } from '@/types';

export abstract class BaseEnemy extends Phaser.Physics.Arcade.Sprite {
  protected enemyState: EnemyState = 'active';
  protected stunTimer = 0;
  protected stunDuration: number = PHYSICS.stun.duration;
  protected stunIndicator?: Phaser.GameObjects.Graphics;

  constructor(scene: Phaser.Scene, x: number, y: number, texture: string) {
    super(scene, x, y, texture);

    scene.add.existing(this as Phaser.GameObjects.GameObject);
    scene.physics.add.existing(this as Phaser.GameObjects.GameObject);

    const body = this.body as Phaser.Physics.Arcade.Body;
    body.setSize(28, 28);
    body.setOffset(2, 4);
    body.setCollideWorldBounds(true);

    // Create stun indicator
    this.stunIndicator = scene.add.graphics();
    this.stunIndicator.setVisible(false);
  }

  update(_time: number, delta: number): void {
    if (this.enemyState === 'stunned') {
      this.updateStunned(delta);
      return;
    }

    this.updateBehavior(_time, delta);
  }

  // Override this in subclasses for specific behavior
  protected abstract updateBehavior(time: number, delta: number): void;

  protected updateStunned(delta: number): void {
    this.stunTimer -= delta;
    this.updateStunIndicator();

    if (this.stunTimer <= 0) {
      this.recover();
    }
  }

  protected updateStunIndicator(): void {
    if (!this.stunIndicator) return;

    this.stunIndicator.clear();
    this.stunIndicator.setPosition(this.x, this.y - 30);

    const progress = this.stunTimer / this.stunDuration;
    const radius = 10;

    // Background circle
    this.stunIndicator.lineStyle(3, 0x444444);
    this.stunIndicator.strokeCircle(0, 0, radius);

    // Progress arc
    this.stunIndicator.lineStyle(3, 0xffff00);
    this.stunIndicator.beginPath();
    this.stunIndicator.arc(
      0,
      0,
      radius,
      -Math.PI / 2,
      -Math.PI / 2 + progress * Math.PI * 2,
      false
    );
    this.stunIndicator.strokePath();
  }

  public stun(duration?: number): void {
    this.stunDuration = duration ?? PHYSICS.stun.duration;

    if (this.enemyState === 'stunned') {
      this.stunTimer = this.stunDuration;
      return;
    }

    this.enemyState = 'stunned';
    this.stunTimer = this.stunDuration;

    // Visual feedback
    this.setTexture('enemy_stunned');

    // Stop movement
    const body = this.body as Phaser.Physics.Arcade.Body;
    body.setVelocity(0);

    // Squash effect
    this.setScale(1.3, 0.7);
    this.scene.tweens.add({
      targets: this,
      scaleX: 1,
      scaleY: 1,
      duration: 200,
      ease: 'Bounce.out',
    });

    if (this.stunIndicator) {
      this.stunIndicator.setVisible(true);
    }
  }

  protected recover(): void {
    this.enemyState = 'active';
    this.setTexture('enemy');

    this.scene.tweens.add({
      targets: this,
      alpha: 0.5,
      yoyo: true,
      repeat: 2,
      duration: 100,
    });

    if (this.stunIndicator) {
      this.stunIndicator.setVisible(false);
    }
  }

  public isActive(): boolean {
    return this.enemyState === 'active';
  }

  public getEnemyState(): EnemyState {
    return this.enemyState;
  }

  destroy(fromScene?: boolean): void {
    this.stunIndicator?.destroy();
    super.destroy(fromScene);
  }
}
