using System;
using System.IO;
using Asp.Versioning.ApiExplorer;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace TakeoutSaaS.Shared.Web.Swagger;

/// <summary>
/// Swagger 注册/启用扩展。
/// </summary>
public static class SwaggerExtensions
{
    /// <summary>
    /// 注入统一的 Swagger 服务。
    /// </summary>
    public static IServiceCollection AddSharedSwagger(this IServiceCollection services, Action<SwaggerDocumentSettings>? configure = null)
    {
        // 1. 注册 Swagger 并加载 XML 注释以展示中文文档
        services.AddSwaggerGen(options =>
        {
            var basePath = AppContext.BaseDirectory;
            var xmlFiles = Directory.GetFiles(basePath, "*.xml");
            foreach (var xml in xmlFiles)
            {
                options.IncludeXmlComments(xml, true);
            }
        });
        services.AddSingleton(_ =>
        {
            var settings = new SwaggerDocumentSettings();
            configure?.Invoke(settings);
            return settings;
        });
        services.AddSingleton<IConfigureOptions<SwaggerGenOptions>>(provider =>
            new ConfigureSwaggerOptions(
                provider.GetRequiredService<IApiVersionDescriptionProvider>(),
                Options.Create(provider.GetRequiredService<SwaggerDocumentSettings>())));
        return services;
    }

    /// <summary>
    /// 开发环境启用 Swagger UI（自动注册所有版本）。
    /// </summary>
    public static IApplicationBuilder UseSharedSwagger(this IApplicationBuilder app)
    {
        var provider = app.ApplicationServices.GetRequiredService<IApiVersionDescriptionProvider>();
        var settings = app.ApplicationServices.GetRequiredService<SwaggerDocumentSettings>();
        // 1. 注册 Swagger 中间件
        app.UseSwagger();
        app.UseSwaggerUI(options =>
        {
            foreach (var description in provider.ApiVersionDescriptions)
            {
                // 3. 使用相对路径适配反向代理/网关前缀
                options.SwaggerEndpoint(
                    $"./{description.GroupName}/swagger.json",
                    $"{settings.Title} {description.ApiVersion}");
            }
            // 2. 显示请求耗时
            options.DisplayRequestDuration();
        });
        return app;
    }
}
