using System.Net.Http.Json;
using Microsoft.Extensions.Logging;

namespace Inspectron.Epson.PrintServer.Telemetry;

public sealed class LoopbackInsinTelemetry : IInsinTelemetry
{
    private const string Endpoint = "http://127.0.0.1:47823/events";
    private static readonly TimeSpan RequestTimeout = TimeSpan.FromSeconds(2);
    private static readonly long WarnIntervalTicks = TimeSpan.FromMinutes(5).Ticks / TimeSpan.TicksPerMillisecond;

    private readonly HttpClient _http;
    private readonly ILogger _logger;
    private long _lastWarnMs = -WarnIntervalTicks;

    public LoopbackInsinTelemetry(HttpClient http, ILogger logger)
    {
        _http = http;
        _logger = logger;
    }

    public void Emit(string kind, string message)
    {
        var payload = new
        {
            kind,
            message,
            at = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
        };
        _ = Task.Run(() => SendAsync(payload));
    }

    private async Task SendAsync(object payload)
    {
        try
        {
            using var cts = new CancellationTokenSource(RequestTimeout);
            using var resp = await _http.PostAsJsonAsync(Endpoint, payload, cts.Token);
            if (!resp.IsSuccessStatusCode)
                MaybeWarn($"insin loopback returned {(int)resp.StatusCode}");
        }
        catch (Exception ex)
        {
            MaybeWarn($"insin loopback unreachable at 127.0.0.1:47823 ({ex.GetType().Name}), dropping events");
        }
    }

    private void MaybeWarn(string message)
    {
        var now = Environment.TickCount64;
        var last = Interlocked.Read(ref _lastWarnMs);
        if (now - last < WarnIntervalTicks) return;
        if (Interlocked.CompareExchange(ref _lastWarnMs, now, last) != last) return;
        _logger.LogWarning("{Message}", message);
    }
}
