using Asp.Versioning.ApiExplorer;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace TakeoutSaaS.Shared.Web.Swagger;

/// <summary>
/// 根据 API 版本动态注册 Swagger 文档。
/// </summary>
internal sealed class ConfigureSwaggerOptions(
    IApiVersionDescriptionProvider provider,
    IOptions<SwaggerDocumentSettings> settings) : IConfigureOptions<SwaggerGenOptions>
{
    private readonly SwaggerDocumentSettings _settings = settings.Value;

    /// <summary>
    /// 根据 API 版本生成 Swagger 文档配置。
    /// </summary>
    public void Configure(SwaggerGenOptions options)
    {
        // 1. 为每个 API 版本注册文档
        foreach (var description in provider.ApiVersionDescriptions)
        {
            var info = new OpenApiInfo
            {
                Title = $"{_settings.Title} {description.ApiVersion}",
                Version = description.ApiVersion.ToString(),
                Description = description.IsDeprecated
                    ? $"{_settings.Description}（该版本已弃用）"
                    : _settings.Description
            };
            options.SwaggerGeneratorOptions.SwaggerDocs[description.GroupName] = info;
        }

        // 2. 配置 JWT 授权信息
        if (_settings.EnableAuthorization)
        {
            const string bearerSchemeName = "Bearer";
            var scheme = new OpenApiSecurityScheme
            {
                Name = "Authorization",
                Description = "在下方输入Bearer Token，格式：Bearer {token}",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.Http,
                Scheme = "bearer",
                BearerFormat = "JWT"
            };
            options.AddSecurityDefinition(bearerSchemeName, scheme);
            options.AddSecurityRequirement(document =>
            {
                var requirement = new OpenApiSecurityRequirement
                {
                    { new OpenApiSecuritySchemeReference(bearerSchemeName, document, null), new List<string>() }
                };
                return requirement;
            });
        }
    }
}
