using Microsoft.AspNetCore.Mvc;
using Microsoft.OpenApi;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace KArtSell.Host.OpenApi;

/// <summary>
/// Documents the error family produced by the Host's ProblemDetails,
/// authentication, authorization, routing, and conflict boundaries.
/// </summary>
public sealed class ProblemDetailsOperationFilter : IOperationFilter
{
    private static readonly IReadOnlyDictionary<string, string> Responses =
        new Dictionary<string, string>
        {
            ["400"] = "Invalid request",
            ["401"] = "Authentication required",
            ["403"] = "Permission denied",
            ["404"] = "Resource not found",
            ["409"] = "Concurrency or business conflict",
            ["500"] = "Unexpected server error"
        };

    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        var schema = context.SchemaGenerator.GenerateSchema(
            typeof(ProblemDetails), context.SchemaRepository);
        operation.Responses ??= new OpenApiResponses();
        operation.Description = string.Join(
            Environment.NewLine,
            operation.Description,
            "ProblemDetails types: validation, business-rule, conflict, permission, not-found, integration, system.",
            "Correlation: X-Correlation-Id.");

        foreach (var (status, description) in Responses)
        {
            if (operation.Responses.ContainsKey(status))
            {
                continue;
            }

            operation.Responses[status] = new OpenApiResponse
            {
                Description = description,
                Content = new Dictionary<string, OpenApiMediaType>
                {
                    ["application/problem+json"] = new() { Schema = schema }
                }
            };
        }
    }
}
