using MediatR;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using TakeoutSaaS.Application.App.Subscriptions.Commands;
using TakeoutSaaS.Domain.Tenants.Repositories;
using TakeoutSaaS.Module.Scheduler.Options;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.Module.Scheduler.Jobs;

/// <summary>
/// 订阅到期检查任务：到期进入宽限期，宽限期到期自动暂停。
/// </summary>
public sealed class SubscriptionExpiryCheckJob(
    IMediator mediator,
    ITenantRepository tenantRepository,
    ITenantContextAccessor tenantContextAccessor,
    IOptionsMonitor<SubscriptionAutomationOptions> optionsMonitor,
    ILogger<SubscriptionExpiryCheckJob> logger)
{
    /// <summary>
    /// 执行订阅到期检查。
    /// </summary>
    public async Task ExecuteAsync()
    {
        // 1. 读取配置
        var options = optionsMonitor.CurrentValue;

        // 2. (空行后) 获取需要处理的租户列表（排除系统租户）
        var tenants = await tenantRepository.SearchAsync(null, null, CancellationToken.None);
        var targets = tenants.Where(x => x.Id > 0).ToList();

        // 3. (空行后) 按租户逐个执行到期处理
        var enteredGracePeriodCount = 0;
        var suspendedCount = 0;
        var previousContext = tenantContextAccessor.Current;
        try
        {
            foreach (var tenant in targets)
            {
                tenantContextAccessor.Current = new TenantContext(tenant.Id, tenant.Code, "scheduler");
                try
                {
                    var result = await mediator.Send(new ProcessSubscriptionExpiryCommand
                    {
                        GracePeriodDays = options.GracePeriodDays
                    });

                    enteredGracePeriodCount += result.EnteredGracePeriodCount;
                    suspendedCount += result.SuspendedCount;
                }
                catch (Exception ex)
                {
                    logger.LogError(ex, "定时任务：订阅到期检查执行失败 TenantId={TenantId}", tenant.Id);
                }
            }
        }
        finally
        {
            tenantContextAccessor.Current = previousContext;
        }

        // 4. (空行后) 记录执行结果
        logger.LogInformation(
            "定时任务：订阅到期检查完成，处理租户 {TenantCount}，进入宽限期 {EnteredGracePeriodCount}，暂停 {SuspendedCount}",
            targets.Count,
            enteredGracePeriodCount,
            suspendedCount);
    }
}
