namespace TaxBaik.Web.Services;

using Microsoft.Extensions.Hosting;
using TaxBaik.Application.Services;

public class TelegramReportBackgroundService(
    IServiceScopeFactory scopeFactory,
    ILogger<TelegramReportBackgroundService> logger) : BackgroundService
{
    private static readonly TimeZoneInfo KoreaTimeZone = GetKoreaTimeZone();
    private DateOnly? _lastDailyReportDate;
    private DateOnly? _lastWeeklyReportWeekStart;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        using var timer = new PeriodicTimer(TimeSpan.FromMinutes(30));

        try
        {
            while (await timer.WaitForNextTickAsync(stoppingToken))
            {
                try
                {
                    var now = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, KoreaTimeZone);
                    await TrySendReportsAsync(now, stoppingToken);
                }
                catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
                {
                    break;
                }
                catch (Exception ex)
                {
                    logger.LogError(ex, "Telegram report background loop failed");
                }
            }
        }
        catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
        {
            // Normal shutdown path.
        }
    }

    private async Task TrySendReportsAsync(DateTimeOffset nowKst, CancellationToken ct)
    {
        if (nowKst.Hour is 9 or 10)
            await SendDailyIfNeededAsync(DateOnly.FromDateTime(nowKst.DateTime), ct);

        if (nowKst.DayOfWeek == DayOfWeek.Monday && nowKst.Hour is 9 or 10)
            await SendWeeklyIfNeededAsync(DateOnly.FromDateTime(nowKst.DateTime).AddDays(-7), ct);
    }

    private async Task SendDailyIfNeededAsync(DateOnly date, CancellationToken ct)
    {
        if (_lastDailyReportDate == date)
            return;

        using var scope = scopeFactory.CreateScope();
        var reportService = scope.ServiceProvider.GetRequiredService<TelegramReportService>();
        var telegram = scope.ServiceProvider.GetRequiredService<ITelegramNotificationService>();

        var report = await reportService.BuildDailyReportAsync(date, ct);
        await telegram.SendReportAsync("일간 세무/상담 현황 리포트", TelegramReportService.FormatDailyMessage(report), ct);
        _lastDailyReportDate = date;
        logger.LogInformation("Daily telegram report sent for {Date}", date);
    }

    private async Task SendWeeklyIfNeededAsync(DateOnly weekStart, CancellationToken ct)
    {
        if (_lastWeeklyReportWeekStart == weekStart)
            return;

        using var scope = scopeFactory.CreateScope();
        var reportService = scope.ServiceProvider.GetRequiredService<TelegramReportService>();
        var telegram = scope.ServiceProvider.GetRequiredService<ITelegramNotificationService>();

        var report = await reportService.BuildWeeklyReportAsync(weekStart, ct);
        await telegram.SendReportAsync("주간 세무/매출 종합 리포트", TelegramReportService.FormatWeeklyMessage(report), ct);
        _lastWeeklyReportWeekStart = weekStart;
        logger.LogInformation("Weekly telegram report sent for {WeekStart}", weekStart);
    }

    private static TimeZoneInfo GetKoreaTimeZone()
    {
        try
        {
            return TimeZoneInfo.FindSystemTimeZoneById("Korea Standard Time");
        }
        catch (TimeZoneNotFoundException)
        {
            return TimeZoneInfo.FindSystemTimeZoneById("Asia/Seoul");
        }
    }
}
