using DoomDeathmatch.Component.MVC.Model.Enemy.Attack;
using DoomDeathmatch.Component.MVC.Model.Enemy.Movement;
using DoomDeathmatch.Scene.Play;
using OpenTK.Mathematics;

namespace DoomDeathmatch.Component.MVC.Model.Enemy;

public class EnemyData
{
  public static EnemyData Demon =>
    new()
    {
      Id = "demon",
      Name = "Демон",
      Texture = "texture/demon.png",
      BaseHealth = 150,
      BaseScore = 50,
      BaseSpeed = 8,
      MovementBehavior = new FollowPlayerMovementBehavior(1.5f),
      AttackBehaviorCreator = new FuncAttackBehaviorCreator(
        (parEnemyController, parHealthController) =>
          new CloseCooldownAttackBehavior(parEnemyController, parHealthController, 1.75f, 2.5f, 10)
      )
    };

  public static EnemyData Imp =>
    new()
    {
      Id = "imp",
      Name = "Имп",
      Texture = "texture/imp.png",
      BaseHealth = 300,
      BaseScore = 200,
      BaseSpeed = 7,
      MovementBehavior = new FollowPlayerMovementBehavior(10f),
      AttackBehaviorCreator = new FuncAttackBehaviorCreator(
        (parEnemyController, parHealthController) =>
          new CompositeAttackBehavior(parEnemyController, parHealthController,
            [
              new CloseContinuousAttackBehavior(parEnemyController, parHealthController, 1.75f, 10f),
              new ObjectSpawnAttackBehavior(parEnemyController, parHealthController, 4f,
                (parEnemyController, parHealthController) =>
                {
                  var direction =
                    (parHealthController.GameObject.Transform.Translation -
                     parEnemyController.GameObject.Transform.Translation).Normalized();

                  var fireballObject = EnemyObject.CreateImpFireball(parEnemyController.GameObject.Scene!,
                    parEnemyController.GameObject.Transform.Translation + new Vector3(0, 0f, 1.75f),
                    direction * 25,
                    35,
                    parHealthController.GameObject.Transform
                  );

                  return fireballObject;
                }
              )
            ]
          )
      )
    };

  public string Id { get; private init; } = "";
  public string Name { get; private init; } = "";
  public string Texture { get; private init; } = "";
  public float BaseHealth { get; private init; }
  public int BaseScore { get; private init; }
  public float BaseSpeed { get; private init; }
  public IMovementBehavior MovementBehavior { get; private init; }
  public IAttackBehaviorCreator AttackBehaviorCreator { get; private init; }

  private EnemyData() { }

  public override bool Equals(object? parObj)
  {
    return parObj is EnemyData enemyData && Id == enemyData.Id;
  }

  public override int GetHashCode()
  {
    return HashCode.Combine(Id);
  }
}