using System.Net;

namespace Health.WebApi.Middleware;

/// <summary>
/// 全局异常处理中间件——统一返回 {code, data, message} 格式
/// </summary>
public sealed class ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger)
{
    private readonly RequestDelegate _next = next;
    private readonly ILogger<ExceptionMiddleware> _logger = logger;

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Health.Domain.ValidationException vex)
        {
            // 业务输入校验失败：返回 400，message 为我们自己产生的提示，可安全展示
            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
            context.Response.ContentType = "application/json";
            var result = new { code = 40001, data = (object?)null, message = vex.Message };
            await context.Response.WriteAsync(JsonSerializer.Serialize(result));
        }
        catch (Microsoft.AspNetCore.Http.BadHttpRequestException ex)
        {
            // 请求体无法解析（非法 JSON、编码错误、请求体过大等）：返回其携带的状态码（通常 400），而不是 500
            _logger.LogWarning(ex, "请求解析失败: {Path}", context.Request.Path);
            context.Response.StatusCode = ex.StatusCode;
            context.Response.ContentType = "application/json";
            var result = new { code = 40001, data = (object?)null, message = "请求格式不正确" };
            await context.Response.WriteAsync(JsonSerializer.Serialize(result));
        }
        catch (Exception ex)
        {
            // 生产环境不暴露内部异常详情
            _logger.LogError(ex, "未处理的异常: {Path}", context.Request.Path);
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            context.Response.ContentType = "application/json";

            var result = new
            {
                code = 50000,
                data = (object?)null,
                message = "服务器内部错误，请稍后重试"
            };
            await context.Response.WriteAsync(JsonSerializer.Serialize(result));
        }
    }
}
