using Long.Core.Api;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System.Net;
using System.Text.Json;

namespace Long.Utils.Filter;

public class MvcExceptionFilter : IExceptionFilter, IFilterMetadata
{
    private readonly IModelMetadataProvider _iModelMetadataProvider;
    public MvcExceptionFilter(IModelMetadataProvider modelMetadataProvider)
    {
        this._iModelMetadataProvider = modelMetadataProvider;
    }

    public void OnException(ExceptionContext context)
    {
        var result = new ApiResult();
        result.Success = false;
        switch (context.HttpContext.Response.StatusCode)
        {
            case 401:
                result.StatusCode = (int)HttpStatusCode.Unauthorized;
                result.Message = "未授权：" + context.Exception.Message;
                break;
            case 403:
                result.StatusCode = (int)HttpStatusCode.Forbidden;
                result.Message = "拒绝：" + context.Exception.Message;
                break;
            case 404:
                result.StatusCode = (int)HttpStatusCode.NotFound;
                result.Message = "未找到：" + context.Exception.Message;
                break;
            case 405:
                result.StatusCode = (int)HttpStatusCode.MethodNotAllowed;
                result.Message = "不允许：" + context.Exception.Message;
                break;
            case 500:
                result.StatusCode = (int)HttpStatusCode.InternalServerError;
                result.Message = "服务器内部错误：" + context.Exception.Message;
                result.Message += "\r\n" + context.Exception.StackTrace;
                break;
            default:
                result.StatusCode = context.HttpContext.Response.StatusCode;
                result.Message = context.Exception.Message;
                result.StackTrace = context.Exception.StackTrace ?? "";
                break;
        }
        context.ExceptionHandled = true;

        if (IsAjax(context.HttpContext))
        {
            HttpResponse response = context.HttpContext.Response;
            response.StatusCode = (int)context.HttpContext.Response.StatusCode;
            response.ContentType = "application/json;charset=utf-8";
            string text = JsonSerializer.Serialize(result);
            response.WriteAsync(text);
        }
        else
        {
            var view = new ViewResult()
            {
                ViewName = "~/Views/Shared/Error.cshtml",
                ViewData = new ViewDataDictionary(_iModelMetadataProvider, context.ModelState)
            };
            view.ViewData.Add("Exception", context.Exception);
        }

        context.ExceptionHandled = true;
    }

    public bool IsAjax(HttpContext context)
    {
        return context.Request.Headers["x-requested-with"] == "XMLHttpRequest";
    }
}
