using System.Numerics;
using System.Reflection;
using Dalamud.Bindings.ImGui;
using Pictomancy;

namespace LightlessSync.Services.Rendering;

internal static class PctDrawListExtensions
{
    private static readonly FieldInfo? DrawListField = typeof(PctDrawList).GetField("_drawList", BindingFlags.Instance | BindingFlags.NonPublic);

    private static bool TryGetImDrawList(PctDrawList drawList, out ImDrawListPtr ptr)
    {
        ptr = default;
        if (DrawListField == null)
            return false;

        if (DrawListField.GetValue(drawList) is ImDrawListPtr list)
        {
            ptr = list;
            return true;
        }

        return false;
    }

    public static void AddScreenText(this PctDrawList drawList, Vector2 screenPosition, string text, uint color, float fontSize, Vector2? pivot = null, uint? outlineColor = null, ImFontPtr fontOverride = default)
    {
        if (drawList == null || string.IsNullOrEmpty(text))
            return;

        if (!TryGetImDrawList(drawList, out var imDrawList))
            return;

        var font = fontOverride.IsNull ? ImGui.GetFont() : fontOverride;
        if (font.IsNull)
            return;

        var size = MathF.Max(1f, fontSize);
        var pivotValue = pivot ?? new Vector2(0.5f, 0.5f);

        Vector2 measured;
        float calcFontSize;
        if (!fontOverride.IsNull)
        {
            ImGui.PushFont(font);
            measured = ImGui.CalcTextSize(text);
            calcFontSize = ImGui.GetFontSize();
            ImGui.PopFont();
        }
        else
        {
            measured = ImGui.CalcTextSize(text);
            calcFontSize = ImGui.GetFontSize();
        }

        if (calcFontSize > 0f && MathF.Abs(size - calcFontSize) > 0.001f)
        {
            measured *= size / calcFontSize;
        }

        var drawPos = screenPosition - measured * pivotValue;
        if (outlineColor.HasValue)
        {
            var thickness = MathF.Max(1f, size / 24f);
            Span<Vector2> offsets = stackalloc Vector2[4]
            {
                new Vector2(1f, 0f),
                new Vector2(-1f, 0f),
                new Vector2(0f, 1f),
                new Vector2(0f, -1f)
            };

            foreach (var offset in offsets)
            {
                imDrawList.AddText(font, size, drawPos + offset * thickness, outlineColor.Value, text);
            }
        }

        imDrawList.AddText(font, size, drawPos, color, text);
    }
}
