using Engine.Input;

namespace DoomDeathmatch.Component.UI;

public class SelectorComponent : Engine.Scene.Component.Component
{
  public List<UiComponent> Children => _children;
  public KeyboardButtonCode SelectKey { get; set; } = KeyboardButtonCode.Space;
  public KeyboardButtonCode NextKey { get; set; } = KeyboardButtonCode.Down;
  public KeyboardButtonCode PrevKey { get; set; } = KeyboardButtonCode.Up;

  public event Action<UiComponent>? OnSelect;

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

  private readonly List<UiComponent> _children = [];

  private int _selectedIndex = 0;

  public override void Start()
  {
    foreach (var child in Children)
    {
      child.OnMouseOver += Select;
    }

    SelectionChanged();
  }

  public override void Update(double parDeltaTime)
  {
    if (_inputHandler.IsKeyJustPressed(SelectKey))
      _children[_selectedIndex].InvokeClick();

    if (_inputHandler.IsKeyJustPressed(NextKey))
    {
      _selectedIndex++;
      if (_selectedIndex >= Children.Count)
        _selectedIndex = 0;

      SelectionChanged();
    }

    if (_inputHandler.IsKeyJustPressed(PrevKey))
    {
      _selectedIndex--;
      if (_selectedIndex < 0)
        _selectedIndex = Children.Count - 1;

      SelectionChanged();
    }

    UpdatePosition();
  }

  private void SelectionChanged()
  {
    OnSelect?.Invoke(Children[_selectedIndex]);
  }

  private void UpdatePosition()
  {
    var child = Children[_selectedIndex];

    var transformMatrix = child.GameObject.Transform.FullTransformMatrix;
    var translation = transformMatrix.ExtractTranslation();
    var scale = transformMatrix.ExtractScale();

    GameObject.Transform.Translation = translation;
    GameObject.Transform.Translation.X -= scale.X / 2;

    GameObject.Transform.Size.Y = scale.Y;
  }

  private void Select(UiComponent parComponent)
  {
    var index = Children.IndexOf(parComponent);
    if (index < 0)
      index = 0;

    if (index == _selectedIndex)
      return;

    _selectedIndex = index;

    SelectionChanged();
  }
}