using System.Numerics;
using Voile.Input;
using Voile.Rendering;
using Voile.Resources;

namespace Voile.UI.Widgets;

public class Label : Widget
{
    public override Rect MinimumSize => Rect.Zero;

    public bool WrapText { get; set; } = false;

    public string Text
    {
        get => _text; set
        {
            _text = value;
            MarkDirty();
        }
    }

    public override string? StyleElementName => nameof(Label);

    /// <summary>
    /// <see cref="FontSet"/> to use with this label.
    /// </summary>
    public FontSet FontSet { get; set; } = new();

    public Label(string text, ResourceRef<Font> fontOverride)
    {
        _text = text;

        FontSet.AddFont(fontOverride);

        MarkDirty();
    }

    public Label(string text, FontSet fontSet)
    {
        _text = text;

        FontSet = fontSet;

        MarkDirty();
    }

    protected override void OnInput(UIInputContext action)
    {

    }

    protected override void OnRender(RenderSystem renderer, Style style)
    {
        if (!_font.HasValue)
            return;

        if (renderer is not RaylibRenderSystem rayRenderer) return; // TODO: Do NOT rely on RaylibRenderSystem check here. Very bad.
        renderer.SetTransform(GlobalPosition, Vector2.Zero);
        rayRenderer.DrawText(_font, _layout, style.TextColor ?? Color.Black);
    }

    protected override void OnUpdate(LayoutContext layoutContext)
    {
        ResolveFont();

        if (!_font.HasValue)
            return;

        var width = WrapText ? Size.Width : float.MaxValue;
        _layout = _font.Value.Layout(_text, Vector2.Zero, width);
    }

    private void ResolveFont()
    {
        if (_font.HasValue)
            return;

        var text = _text;

        for (int i = 0; i < text.Length; i++)
        {
            if (FontSet.TryGetFontFor(text[i], out var f))
            {
                _font = f;
                break;
            }
        }
    }

    private ResourceRef<Font> _font = ResourceRef<Font>.Empty();

    private string _text = "Hello, World!";

    private TextLayout _layout = new();
}