using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;

public sealed class GatewayHeartbeatService : BackgroundService
{
    private readonly IServiceScopeFactory _scopes;
    private readonly IHttpClientFactory _http;
    private readonly CentralReachabilityService _reachability;
    private readonly GatewayOptions _gateway;
    private readonly IConfiguration _config;
    private readonly ILogger<GatewayHeartbeatService> _logger;

    public GatewayHeartbeatService(
        IServiceScopeFactory scopes,
        IHttpClientFactory http,
        CentralReachabilityService reachability,
        IOptions<GatewayOptions> gateway,
        IConfiguration config,
        ILogger<GatewayHeartbeatService> logger)
    {
        _scopes = scopes;
        _http = http;
        _reachability = reachability;
        _gateway = gateway.Value;
        _config = config;
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken ct)
    {
        using var timer = new PeriodicTimer(TimeSpan.FromSeconds(_gateway.HeartbeatIntervalSeconds));
        while (await timer.WaitForNextTickAsync(ct))
            await SendHeartbeatAsync(ct);
    }

    private async Task SendHeartbeatAsync(CancellationToken ct)
    {
        await using var scope = _scopes.CreateAsyncScope();
        var db = scope.ServiceProvider.GetRequiredService<GatewayDbContext>();
        var bufferDepth = await db.BufferedSyncItems.CountAsync(b => !b.Synced, ct);

        var status = _reachability.IsCentralReachable ? "ONLINE" : "DEGRADED";
        var req = new GatewayHeartbeatRequest(status, bufferDepth, DateTimeOffset.UtcNow);

        try
        {
            var client = _http.CreateClient("central");
            client.BaseAddress = new Uri(
                scope.ServiceProvider.GetRequiredService<IOptions<CentralApiOptions>>().Value.BaseUrl);
            client.DefaultRequestHeaders.Remove("X-Api-Key");
            client.DefaultRequestHeaders.Remove("X-Gateway-Id");
            client.DefaultRequestHeaders.Add("X-Api-Key", _config["ApiKey:Gateway"]);
            client.DefaultRequestHeaders.Add("X-Gateway-Id", _gateway.GatewayId.ToString());

            var resp = await client.PatchAsJsonAsync(
                $"/api/v1/gateways/{_gateway.GatewayId}/heartbeat", req, ct);
            if (!resp.IsSuccessStatusCode)
                _logger.LogWarning("Heartbeat failed: {Status}", resp.StatusCode);
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "Heartbeat to central failed — gateway continues in DEGRADED mode");
        }
    }
}