using System.Text.Json;
using FlatRender.StudioSvc.Models.Responses;

namespace FlatRender.StudioSvc.Middleware;

public class ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger)
{
    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
    };

    public async Task InvokeAsync(HttpContext ctx)
    {
        try { await next(ctx); }
        catch (Exception ex)
        {
            logger.LogError(ex, "Unhandled exception");
            var (status, code) = ex switch
            {
                KeyNotFoundException => (404, "not_found"),
                UnauthorizedAccessException => (401, "unauthorized"),
                InvalidOperationException => (400, "invalid_operation"),
                ArgumentException => (400, "bad_request"),
                _ => (500, "internal_error")
            };
            ctx.Response.StatusCode = status;
            ctx.Response.ContentType = "application/json";
            var body = new { error = new ApiError(code, ex.Message, ctx.TraceIdentifier) };
            await ctx.Response.WriteAsync(JsonSerializer.Serialize(body, JsonOptions));
        }
    }
}
