
using DFS.Core.Abstractions;
using DFS.Core.Abstractions.View;
using DFS.Core.Mvc.Results;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace DFS.Core.Mvc.Filters
{
    /// <summary>
    /// 标准结果集
    /// </summary>
    public class StandardResultFilter : IResultFilter, IAsyncResultFilter
    {
        /// <summary>
        /// Result执行后
        /// </summary>
        /// <param name="context"></param>
        public void OnResultExecuted(ResultExecutedContext context)
        {
        }

        /// <summary>
        /// Result执行中
        /// </summary>
        /// <param name="context"></param>
        public void OnResultExecuting(ResultExecutingContext context)
        {
            string requestId = context.HttpContext.TraceIdentifier + new Random().Next(1000, 9999);
            if (context.Result is OkObjectResult)
            {
                return;
            }
            if (context.ActionDescriptor.EndpointMetadata.Any(p => p.GetType().Name == "NoStandardResultAttribute"))
            {
                return;
            }
            if (context.Result is BadRequestObjectResult)
            {
                context.Result = new StandardObjectResult(new ServiceProtocol()
                {
                    StatusCode = (int)MicroServiceStatus.BadRequest,
                    Content = null,
                    RequestId = requestId,
                    Notification = string.Join(",", ((context.Result as BadRequestObjectResult).Value as ValidationProblemDetails).Errors.Select(a => $"字段{a.Key}:{string.Join(',', a.Value)}"))
                });
            }
            else if (context.Result is ObjectResult)
            {
                ObjectResult result = context.Result as ObjectResult;

              
                if (context.HttpContext != null && context.HttpContext.Request != null && context.HttpContext.Request.Query != null && context.HttpContext.Request.Query.ContainsKey("requestId"))
                {
                    //Guid.TryParse(context.HttpContext.Request.Query["requestId"][0], out requestId);
                    requestId = context.HttpContext.Request.Query["requestId"][0];
                }

                if (context.Result is UnauthorizedObjectResult)
                {
                    context.Result = new StandardObjectResult(result, requestId, true);
                    return;
                }
                //如果是空值则返回404异常
                if (result.Value == null)
                {
                    context.Result = new StandardObjectResult(new ServiceProtocol()
                    {
                        StatusCode = (int)MicroServiceStatus.NotFound,
                        Content = null,
                        RequestId = requestId,
                        Notification = MicroServiceStatus.NotFound.Description()
                    });
                }
                else
                {
                    if (context.ActionDescriptor.EndpointMetadata.Any(p => p.GetType().Name == "RequestResNoPackingAttribute"))
                    {

                    }
                    else
                    {
                        StandardObjectResult standardObjectResult = new StandardObjectResult(result, requestId);
                        if (standardObjectResult.Value != null)
                        {
                            standardObjectResult.Value.RequestId = requestId;
                        }

                        context.Result = standardObjectResult;
                    }
                }
            }
        }

        /// <summary>
        /// 异步Result执行
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (next == null)
            {
                throw new ArgumentNullException(nameof(next));
            }

            OnResultExecuting(context);
            if (!context.Cancel)
            {
                OnResultExecuted(await next());
            }
        }
    }
}
