using System.Collections.Concurrent;
using System.Security.Cryptography;
using System.Text;

namespace TaxBaik.Web.Services;

internal static class TelegramAlertGate
{
    private sealed record GateEntry(DateTimeOffset WindowStart, int Count);

    private static readonly ConcurrentDictionary<string, GateEntry> Gates = new();

    public static bool ShouldSend(string category, string content, TimeSpan window, int maxPerWindow = 1)
    {
        if (string.IsNullOrWhiteSpace(category))
            return false;

        var now = DateTimeOffset.UtcNow;
        var key = $"{category}:{Fingerprint(content)}";

        while (true)
        {
            if (!Gates.TryGetValue(key, out var current))
            {
                var initial = new GateEntry(now, 1);
                if (Gates.TryAdd(key, initial))
                    return true;
                continue;
            }

            if (now - current.WindowStart >= window)
            {
                var reset = new GateEntry(now, 1);
                if (Gates.TryUpdate(key, reset, current))
                    return true;
                continue;
            }

            if (current.Count >= maxPerWindow)
                return false;

            var incremented = current with { Count = current.Count + 1 };
            if (Gates.TryUpdate(key, incremented, current))
                return true;
        }
    }

    private static string Fingerprint(string content)
    {
        if (string.IsNullOrEmpty(content))
            return "empty";

        var normalized = content.Length > 1500 ? content[..1500] : content;
        var bytes = SHA256.HashData(Encoding.UTF8.GetBytes(normalized));
        return Convert.ToHexString(bytes);
    }
}
