using Microsoft.Extensions.Options;
using Pgo.Backend.Config;
using Pgo.Backend.Interfaces;

namespace Pgo.Backend.Services;

public class HostedService(IServiceProvider services, ILogger<HostedService> logger, IOptions<PgoConfig> pgoConfig) : BackgroundService
{
    private IServiceProvider Services { get; } = services;
    private readonly ILogger<HostedService> _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    private readonly PgoConfig _pgoConfig = pgoConfig?.Value ?? throw new ArgumentNullException(nameof(pgoConfig));

    protected override async Task ExecuteAsync(CancellationToken cancellationToken)
    {
        _logger.LogDebug("Hosted Service running.");
        await DoWorkAsync(cancellationToken);
    }

    private async Task DoWorkAsync(CancellationToken cancellationToken)
    {
        using var scope = Services.CreateScope();
        await UpdateStelselnodeListsAsync(scope, cancellationToken);
    }

    private async Task UpdateStelselnodeListsAsync(IServiceScope scope, CancellationToken cancellationToken)
    {
        var stelselnodeService = scope.ServiceProvider.GetRequiredService<IStelselNodeService>();

        while (!cancellationToken.IsCancellationRequested)
        {
            _logger.LogInformation("Start Update Stelselnode Lists.");
            try
            {
                await stelselnodeService.UpdateStelselNodeListsAsync(cancellationToken);
            }
            catch (Exception ex)
            {
                _logger.LogError("ScraperService Failed. Exception Message={Message}", ex.Message);
            }
            _logger.LogInformation("End Update Stelselnode Lists. And Wait for {minutes} minutes until next update.", _pgoConfig.UpdateStelselNodeIntervalMinutes);
            await Task.Delay(TimeSpan.FromMinutes(_pgoConfig.UpdateStelselNodeIntervalMinutes), cancellationToken);
        }
    }

    public override async Task StopAsync(CancellationToken stoppingToken)
    {
        _logger.LogDebug("Hosted Service is stopping.");
        await Task.CompletedTask;
    }
}

