using Engine.Input;
using OpenTK.Mathematics;

namespace DoomDeathmatch.Component.UI;

public class UiComponent : Engine.Scene.Component.Component
{
  public UiContainerComponent? Container { get; set; }
  public Anchor Anchor { get; set; } = Anchor.Center;
  public Vector2 Offset { get; set; } = Vector2.Zero;
  public Vector2 Center { get; set; } = Vector2.Zero;

  public event Action<UiComponent>? OnClick;
  public event Action<UiComponent>? OnMouseOver;

  private readonly IInputHandler _inputHandler = Engine.Engine.Instance.InputHandler!;

  public override void Update(double parDeltaTime)
  {
    if (Container == null)
    {
      return;
    }

    GameObject.Transform.Translation.Xy = GetAnchorPosition(Container.GameObject.Transform.Size.Xy) + Offset;
    var transformMatrix = GameObject.Transform.FullTransformMatrix;
    var translation = transformMatrix.ExtractTranslation();
    var scale = transformMatrix.ExtractScale();

    var relativeMousePosition = Container.MousePosition.Xy -
                                (translation.Xy);

    var objectSize = scale.Xy;

    if (Math.Abs(relativeMousePosition.X) <= objectSize.X / 2 && Math.Abs(relativeMousePosition.Y) <= objectSize.Y / 2)
    {
      OnMouseOver?.Invoke(this);

      if (_inputHandler.IsMouseButtonJustPressed(MouseButtonCode.Left))
      {
        OnClick?.Invoke(this);
      }
    }
  }

  public void InvokeClick()
  {
    OnClick?.Invoke(this);
  }

  private Vector2 GetAnchorPosition(Vector2 parSize)
  {
    return parSize * GetAnchorRatio();
  }

  private Vector2 GetAnchorRatio()
  {
    return Anchor switch
    {
      Anchor.TopLeft => new Vector2(-0.5f, 0.5f),
      Anchor.TopCenter => new Vector2(0, 0.5f),
      Anchor.TopRight => new Vector2(0.5f, 0.5f),
      Anchor.CenterLeft => new Vector2(-0.5f, 0),
      Anchor.Center => new Vector2(0, 0),
      Anchor.CenterRight => new Vector2(0.5f, 0),
      Anchor.BottomLeft => new Vector2(-0.5f, -0.5f),
      Anchor.BottomCenter => new Vector2(0, -0.5f),
      Anchor.BottomRight => new Vector2(0.5f, -0.5f),
      _ => throw new ArgumentOutOfRangeException(nameof(Anchor), Anchor, null)
    };
  }
}