using MailPrint.Services;
using Microsoft.Extensions.Options;

namespace MailPrint;

public class MailPrintWorker : BackgroundService
{
    private readonly ILogger<MailPrintWorker> _logger;
    private readonly MailFetchService _mailService;
    private readonly PrintService _printService;
    private readonly FolderWatcherService _folderService;
    private readonly MailPrintOptions _options;

    public MailPrintWorker(
        ILogger<MailPrintWorker> logger,
        MailFetchService mailService,
        PrintService printService,
        FolderWatcherService folderService,
        IOptions<MailPrintOptions> options)
    {
        _logger = logger;
        _mailService = mailService;
        _printService = printService;
        _folderService = folderService;
        _options = options.Value;
    }

    protected override async Task ExecuteAsync(CancellationToken ct)
    {
        // Ordner-Überwachung starten (event-basiert, läuft dauerhaft)
        _folderService.Start();

        if (_options.Accounts.Count == 0)
        {
            _logger.LogWarning("Keine Postfächer konfiguriert – Mail-Polling deaktiviert.");
            await Task.Delay(Timeout.Infinite, ct).ConfigureAwait(false);
            return;
        }

        _logger.LogInformation("{Count} Postfach/Postfächer konfiguriert, Intervall: {Interval}s",
            _options.Accounts.Count, _options.PollIntervalSeconds);

        var tasks = _options.Accounts.Select(account => PollAccountAsync(account, ct));
        await Task.WhenAll(tasks);
    }

    private async Task PollAccountAsync(MailAccount account, CancellationToken ct)
    {
        _logger.LogInformation("Starte Polling für [{Account}] ({Protocol}://{Host})",
            account.Name, account.Protocol, account.Host);

        while (!ct.IsCancellationRequested)
        {
            try
            {
                var jobs = await _mailService.FetchJobsForAccountAsync(account, ct);
                foreach (var job in jobs)
                {
                    if (ct.IsCancellationRequested) break;
                    try { _printService.PrintPdf(job); }
                    catch (Exception ex) { _logger.LogError(ex, "[{Account}] Druckfehler", account.Name); }
                }
            }
            catch (OperationCanceledException) { break; }
            catch (Exception ex) { _logger.LogError(ex, "[{Account}] Fehler beim Mail-Abruf", account.Name); }

            await Task.Delay(TimeSpan.FromSeconds(_options.PollIntervalSeconds), ct);
        }
    }
}
