using BBWY.Common.Models;
using BBWY.Server.Business;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using NLog;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace JD.API.Middlewares
{
    public class CustomExceptionMiddleWare
    {
        /// <summary>
        /// 管道请求委托
        /// </summary>
        private RequestDelegate _next;

        /// <summary>
        /// 需要处理的状态码字典
        /// </summary>
        private IDictionary<int, string> _exceptionStatusCodeDic;

        //private ILogger logger;
        private NLogManager nLogManager;

        public CustomExceptionMiddleWare(RequestDelegate next, NLogManager nLogManager)
        {
            _next = next;
            this.nLogManager = nLogManager;
            _exceptionStatusCodeDic = new Dictionary<int, string>
            {
                { 401, "未授权的请求" },
                { 404, "找不到该资源" },
                { 403, "访问被拒绝" },
                { 500, "服务器发生意外的错误" },
                { 503, "服务不可用" }
                //其余状态自行扩展
            };
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                await _next(context);   //调用管道执行下一个中间件
            }
            catch (Exception ex)
            {
                if (ex is BusinessException)
                {
                    var busEx = ex as BusinessException;
                    context.Response.StatusCode = 200;  //业务异常时将Http状态码改为200
                    await ErrorHandle(context, busEx.Code, busEx.Message);
                }
                else
                {
                    context.Response.Clear();
                    context.Response.StatusCode = 500;   //发生未捕获的异常,手动设置状态码
                    nLogManager.Default().Error(ex); //记录错误
                }
            }
            finally
            {
                if (_exceptionStatusCodeDic.TryGetValue(context.Response.StatusCode, out string exMsg))
                {
                    await ErrorHandle(context, context.Response.StatusCode, exMsg);
                }
            }
        }

        /// <summary>
        /// 处理方式:返回Json格式
        /// </summary>
        /// <param name="context"></param>
        /// <param name="code"></param>
        /// <param name="exMsg"></param>
        /// <returns></returns>
        private async Task ErrorHandle(HttpContext context, int code, string exMsg)
        {
            var apiResponse = ApiResponse.Error(code, exMsg);
            var serialzeStr = JsonConvert.SerializeObject(apiResponse);
            context.Response.ContentType = "application/json";
            await context.Response.WriteAsync(serialzeStr, Encoding.UTF8);
        }
    }
}