using Fw.Utility.UnifyResponse;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using XF.Domain.Exceptions;

namespace XF.Domain.Filters
{
    public class UserFriendlyExceptionFilter : IExceptionFilter
    {
        private readonly ILogger<UserFriendlyExceptionFilter> _logger;

        public UserFriendlyExceptionFilter(ILogger<UserFriendlyExceptionFilter> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// Called after an action has thrown an <see cref="T:System.Exception" />.
        /// </summary>
        /// <param name="context">The <see cref="T:Microsoft.AspNetCore.Mvc.Filters.ExceptionContext" />.</param>
        public void OnException(ExceptionContext context)
        {
            string action;
            int code = 500;
            string message = "请求失败！";//前端展示
            string error = context.Exception.Message;
            int statusCode = 500;
            if (context.ActionDescriptor is ControllerActionDescriptor controller)
            {
                action = $"{controller.ControllerName}.{controller.ActionName}";
            }
            else
            {
                action = context.HttpContext.Request.GetDisplayUrl();
            }

            if (context.Exception is UserFriendlyException ex)
            {
                code = ex.Code;
                statusCode = ex.Code;
                if (!string.IsNullOrEmpty(ex.FriendlyMessage))
                    message = ex.FriendlyMessage;
            }

            if (code >= 400)
            {
                _logger.LogError(context.Exception, action);
            }

            context.ExceptionHandled = true;

            if (context.Filters.OfType<ApiControllerAttribute>().Any())
            {
                context.Result = new JsonResult(new ApiResponse(code, message, error))
                {
                    StatusCode = statusCode
                };
            }
        }
    }
}
