using System.Collections.Concurrent;
using RioJoy.Core.Overlay;
using SkiaSharp;

namespace RioJoy.Overlay;

/// <summary>
/// <see cref="ITextMeasurer"/> backed by SkiaSharp — the real metrics the
/// <see cref="SkiaOverlayRenderer"/> draws with, so measured layout and rendered
/// output agree. Width is the glyph advance; height is the logical line height
/// (descent − ascent), which keeps vertical centering stable across labels
/// regardless of which glyphs each one happens to contain.
/// </summary>
public sealed class SkiaTextMeasurer : ITextMeasurer
{
    private readonly ConcurrentDictionary<string, SKTypeface> _typefaces = new();

    internal SKTypeface Typeface(string fontFamily) =>
        _typefaces.GetOrAdd(fontFamily, f => SKTypeface.FromFamilyName(f) ?? SKTypeface.Default);

    public TextExtent Measure(string text, string fontFamily, double fontSizePx)
    {
        using var paint = new SKPaint
        {
            Typeface = Typeface(fontFamily),
            TextSize = (float)fontSizePx,
            IsAntialias = true,
        };

        double width = paint.MeasureText(text);
        SKFontMetrics m = paint.FontMetrics;
        double height = m.Descent - m.Ascent; // ascent is negative
        return new TextExtent(width, height);
    }
}
