using DoomDeathmatch.Component.MVC;
using DoomDeathmatch.Component.MVC.Enemy;
using DoomDeathmatch.Component.MVC.Health;
using DoomDeathmatch.Component.Physics;
using DoomDeathmatch.Component.Physics.Collision;
using DoomDeathmatch.Component.UI;
using DoomDeathmatch.Component.Util;
using DoomDeathmatch.Script.Collision;
using DoomDeathmatch.Script.Model.Enemy;
using DoomDeathmatch.Script.UI;
using Engine.Graphics.Texture;
using Engine.Scene;
using Engine.Scene.Component.BuiltIn;
using Engine.Scene.Component.BuiltIn.Renderer;
using Engine.Util;
using OpenTK.Mathematics;

namespace DoomDeathmatch.Scene.Play.Prefab;

public static class EnemyPrefab
{
  public static GameObject Create(Engine.Scene.Scene parScene, EnemyData parEnemyData)
  {
    var enemyHealthTextRenderer = new TextRenderer { Font = UiUtil.GetDoomFont(), Text = "Здоровье: 000" };
    var enemyBox2DRenderer = new Box2DRenderer();

    var enemyObject = GameObjectUtil.CreateGameObject(parScene,
    [
      new EnemyController(parEnemyData),
      new EnemyView(enemyBox2DRenderer),

      new HealthController(parEnemyData.BaseHealth),
      new EnemyHealthView(enemyHealthTextRenderer),

      new MovementController(),
      new RigidbodyComponent(),
      new DragComponent { Drag = 5f, Multiplier = new Vector3(1, 1, 0) },

      new AABBColliderComponent
      {
        Collider = new AABBCollider { Size = new Vector3(1, 1, 2) },
        Offset = new Vector3(0, 0f, 1f),
        ColliderGroups = { "enemy" },
        ExcludeColliderCollideGroups = { "fireball" }
      },
      new ColliderForceFieldComponent()
    ]);
    var enemyHealthContainer = GameObjectUtil.CreateGameObject(parScene,
      new Transform { Translation = new Vector3(0, 1.25f, 0f), Scale = new Vector3(0.2f) }
    );

    var enemyHealthObject = GameObjectUtil.CreateGameObject(parScene, [
        enemyHealthTextRenderer,
        new TextAlignComponent { Alignment = Align.Center }
      ]
    );
    var enemyVisualObject = GameObjectUtil.CreateGameObject(parScene,
      new Transform { Translation = new Vector3(0, 0f, 1f), Size = new Vector3(1, 2, 1) }, [
        enemyBox2DRenderer,
        new BillboardComponent(),
      ]
    );

    parScene.AddChild(enemyObject, enemyVisualObject);
    parScene.AddChild(enemyVisualObject, enemyHealthContainer);
    parScene.AddChild(enemyHealthContainer, enemyHealthObject);

    return enemyObject;
  }

  public static GameObject CreateFireball(Engine.Scene.Scene parScene, Vector3 parPosition,
    Vector3 parVelocity, float parDamage, Transform? parBillboardTarget = null)
  {
    var rigidbodyComponent = new RigidbodyComponent();
    rigidbodyComponent.AddVelocity(parVelocity);

    var fireballObject = GameObjectUtil.CreateGameObject(parScene,
      new Transform { Translation = parPosition, Size = new Vector3(0.5f) },
      [
        rigidbodyComponent,
        new Box2DRenderer { Texture = EngineUtil.AssetResourceManager.Load<Texture>("texture/fireball.png") },
        new BillboardComponent { Target = parBillboardTarget },
        new FireballComponent { Damage = parDamage },
        new AABBColliderComponent
        {
          Collider = new AABBCollider { Size = new Vector3(0.25f) },
          ColliderGroups = { "fireball" },
          ExcludeColliderCollideGroups = { "enemy", "fireball", "consumable" }
        }
      ]
    );

    return fireballObject;
  }
}