using Engine.Scene;
using Engine.Scene.Component.BuiltIn;

namespace EngineTests.Scene;

public class GameObjectTests
{
  private GameObject _gameObject;

  [SetUp]
  public void Setup()
  {
    _gameObject = new GameObject();
  }

  [Test]
  public void Constructor_ShouldInitializeWithTransformComponent()
  {
    Assert.Multiple(() =>
    {
      Assert.That(_gameObject.Transform, Is.Not.Null);
      Assert.That(_gameObject.HasComponent<Transform>(), Is.True);
    });
  }

  [Test]
  public void AddComponent_ShouldThrowIfComponentAlreadyExists()
  {
    _gameObject.AddComponent<Transform>();

    Assert.Throws<ArgumentException>(() => _gameObject.ProcessChanges());
  }

  [Test]
  public void AddComponent_ShouldAddComponentToGameObject()
  {
    _gameObject.AddComponent<OrthographicCamera>();
    _gameObject.ProcessChanges();

    Assert.Multiple(() =>
    {
      Assert.That(_gameObject.GetComponent<OrthographicCamera>(), Is.Not.Null);
      Assert.That(_gameObject.HasComponent<OrthographicCamera>(), Is.True);
    });
  }

  [Test]
  public void AddComponent_ShouldAddComponentToGameObjectWithArgs()
  {
    _gameObject.AddComponent<PerspectiveCamera>(99, 0.2f, 1001f);
    _gameObject.ProcessChanges();

    var camera = _gameObject.GetComponent<PerspectiveCamera>()!;

    Assert.Multiple(() =>
    {
      Assert.That(camera.FieldOfView, Is.EqualTo(99));
      Assert.That(camera.NearPlane, Is.EqualTo(0.2f));
      Assert.That(camera.FarPlane, Is.EqualTo(1001f));
    });
  }

  [Test]
  public void AddComponent_ShouldThrowIfComponentBaseTypeAlreadyExists()
  {
    _gameObject.AddComponent<OrthographicCamera>();
    _gameObject.AddComponent<PerspectiveCamera>();

    Assert.Throws<ArgumentException>(() => _gameObject.ProcessChanges());
  }
}