using Hangfire;
using Hangfire.PostgreSql;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using TakeoutSaaS.Module.Scheduler.Abstractions;
using TakeoutSaaS.Module.Scheduler.HostedServices;
using TakeoutSaaS.Module.Scheduler.Jobs;
using TakeoutSaaS.Module.Scheduler.Options;
using TakeoutSaaS.Module.Scheduler.Services;

namespace TakeoutSaaS.Module.Scheduler.Extensions;

/// <summary>
/// 调度模块注册扩展（默认 Hangfire）。
/// </summary>
public static class SchedulerServiceCollectionExtensions
{
    /// <summary>
    /// 注册调度模块。
    /// </summary>
    public static IServiceCollection AddSchedulerModule(this IServiceCollection services, IConfiguration configuration)
    {
        services.AddOptions<SchedulerOptions>()
            .Bind(configuration.GetSection("Scheduler"))
            .ValidateDataAnnotations()
            .ValidateOnStart();

        services.AddOptions<SubscriptionAutomationOptions>()
            .Bind(configuration.GetSection("Scheduler:SubscriptionAutomation"))
            .ValidateDataAnnotations()
            .ValidateOnStart();

        services.AddOptions<BillingAutomationOptions>()
            .Bind(configuration.GetSection("Scheduler:BillingAutomation"))
            .ValidateDataAnnotations()
            .ValidateOnStart();

        services.AddOptions<OrderTimeoutOptions>()
            .Bind(configuration.GetSection("Scheduler:OrderTimeout"))
            .ValidateDataAnnotations()
            .ValidateOnStart();

        services.AddHangfire((serviceProvider, config) =>
        {
            var options = serviceProvider.GetRequiredService<IOptionsMonitor<SchedulerOptions>>().CurrentValue;
            config
                .UseSimpleAssemblyNameTypeSerializer()
                .UseRecommendedSerializerSettings()
                .UsePostgreSqlStorage(storage =>
                {
                    storage.UseNpgsqlConnection(options.ConnectionString);
                });
        });

        services.AddHangfireServer((serviceProvider, options) =>
        {
            var scheduler = serviceProvider.GetRequiredService<IOptionsMonitor<SchedulerOptions>>().CurrentValue;
            options.WorkerCount = scheduler.WorkerCount ?? options.WorkerCount;
        });

        services.AddSingleton<IRecurringJobRegistrar, RecurringJobRegistrar>();
        services.AddHostedService<RecurringJobHostedService>();

        services.AddScoped<OrderTimeoutJob>();
        services.AddScoped<OrderEscalationJob>();
        services.AddScoped<CouponExpireJob>();
        services.AddScoped<LogCleanupJob>();
        services.AddScoped<SubscriptionRenewalReminderJob>();
        services.AddScoped<SubscriptionExpiryCheckJob>();
        services.AddScoped<SubscriptionAutoRenewalJob>();
        services.AddScoped<BillingOverdueProcessJob>();
        services.AddScoped<FinanceBusinessReportRefreshJob>();

        return services;
    }

    /// <summary>
    /// 启用 Hangfire Dashboard（默认关闭，可通过配置开启）。
    /// </summary>
    public static IApplicationBuilder UseSchedulerDashboard(this IApplicationBuilder app, IConfiguration configuration)
    {
        var options = configuration.GetSection("Scheduler").Get<SchedulerOptions>();
        if (options is { DashboardEnabled: true })
        {
            app.UseHangfireDashboard(options.DashboardPath);
        }

        return app;
    }
}
