namespace Health.WebApi.BackgroundServices;

/// <summary>
/// 用药提醒定时扫描服务（每分钟检查一次）
/// </summary>
public sealed class MedicationReminderService(IServiceScopeFactory scopeFactory, ILogger<MedicationReminderService> logger) : BackgroundService
{
    private readonly IServiceScopeFactory _scopeFactory = scopeFactory;
    private readonly ILogger<MedicationReminderService> _logger = logger;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("用药提醒服务已启动");

        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                await ProcessReminders(stoppingToken);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "用药提醒扫描异常");
            }

            await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
        }
    }

    private async Task ProcessReminders(CancellationToken ct)
    {
        using var scope = _scopeFactory.CreateScope();
        var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
        // 使用北京时间（UTC+8）
        var beijingNow = DateTime.UtcNow.AddHours(8);
        var beijingTime = TimeOnly.FromDateTime(beijingNow);
        var today = DateOnly.FromDateTime(beijingNow);

        // 查询：启用的用药计划 AND 服药时间在当前时间前后5分钟窗口内（防止服务重启错过提醒）
        var windowStart = beijingTime.AddMinutes(-5);
        var medications = await db.Medications
            .Where(m => m.IsActive)
            .Where(m => m.TimeOfDay.Any(t => t >= windowStart && t <= beijingTime))
            .ToListAsync(ct);

        foreach (var med in medications)
        {
            // 检查今天是否已打卡
            var alreadyLogged = await db.MedicationLogs
                .AnyAsync(l => l.MedicationId == med.Id
                    && l.CreatedAt.Date == beijingNow.Date
                    && l.Status == MedicationLogStatus.Taken, ct);

            if (alreadyLogged) continue;

            // TODO: 调用极光推送发送用药提醒
            _logger.LogInformation("用药提醒: 用户 {UserId} 药品 {Name} {Dosage} 时间 {Time}",
                med.UserId, med.Name, med.Dosage, beijingTime);
        }
    }
}
