using Furion.DataValidation;
using Furion.DependencyInjection;
using Furion.UnifyResult;
using Furion.UnifyResult.Internal;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Nirvana.Common.ApiBase;

namespace YBDevice.NWeb.Handler
{
    /// <summary>
    /// RESTFUL 风格返回值
    /// </summary>
    [SuppressSniffer, UnifyModel(typeof(RESTfulResult<>))]
    public class RESTfulResultProvider : IUnifyResultProvider
    {
        /// <summary>
        /// 异常返回值
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public IActionResult OnException(ExceptionContext context, ExceptionMetadata metadata)
        {
            //解析异常信息
            var ErrorCode = metadata.ErrorCode;
            var StatusCode = metadata.StatusCode;
            var Errors = metadata.Errors;
            object data;
            // 处理内容结果
            if (context.Result is ContentResult contentResult) data = contentResult.Content;
            // 处理对象结果
            else if (context.Result is ObjectResult objectResult) data = objectResult.Value;
            else if (context.Result is JsonResult jsonResult) data = jsonResult.Value;
            else if (context.Result is EmptyResult) data = null;
            else data = null;
            return new JsonResult(data);
        }
        /// <summary>
        /// 处理输出状态码
        /// </summary>
        /// <param name="context"></param>
        /// <param name="statusCode"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public async Task OnResponseStatusCodes(HttpContext context, int statusCode, UnifyResultSettingsOptions unifyResultSettings)
        {
            // 设置响应状态码
            UnifyContext.SetResponseStatusCodes(context, statusCode, unifyResultSettings);
            switch (statusCode)
            {
                // 处理 401 状态码
                case StatusCodes.Status401Unauthorized:
                    var result = new ResultInfo(ResultState.NOAUTH, "没有访问权限", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
                    context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                    await context.Response.WriteAsJsonAsync(result);
                    break;
                // 处理 403 状态码
                case StatusCodes.Status403Forbidden:
                    result = new ResultInfo(ResultState.Forbidden, "403 Forbidden", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
                    await context.Response.WriteAsJsonAsync(result);
                    break;

                default:
                    break;
            }
        }

        /// <summary>
        /// 成功返回值
        /// </summary>
        /// <param name="context"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public IActionResult OnSucceeded(ActionExecutedContext context, object data)
        {
            // 处理内容结果
            if (context.Result is ContentResult contentResult) data = contentResult.Content;
            // 处理对象结果
            else if (context.Result is ObjectResult objectResult) data = objectResult.Value;
            else if (context.Result is JsonResult jsonResult) data = jsonResult.Value;
            else if (context.Result is EmptyResult) data = null;
            else return null;
            return new JsonResult(data);
        }
        /// <summary>
        /// 验证失败返回值
        /// </summary>
        /// <param name="context"></param>
        /// <param name="metadata"></param>
        /// <returns></returns>
        public IActionResult OnValidateFailed(ActionExecutingContext context, ValidationMetadata metadata)
        {
            var msg = "发生错误";
            var validationResults = metadata.ValidationResult;
            if (validationResults != null && validationResults.Count() > 0)
            {
                var messages = validationResults.FirstOrDefault().Value;
                if (messages.Length > 0)
                {
                    msg = messages[0];
                }
            }
            var result = new ResultInfo(ResultState.FAIL, msg, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
            return new JsonResult(result);
        }
        /// <summary>
        /// 返回 RESTful 风格结果集
        /// </summary>
        /// <param name="statusCode"></param>
        /// <param name="succeeded"></param>
        /// <param name="data"></param>
        /// <param name="errors"></param>
        /// <returns></returns>
        private static RESTfulResult<object> RESTfulResult(int statusCode, bool succeeded = default, object data = default, object errors = default)
        {
            return new RESTfulResult<object>
            {
                StatusCode = statusCode,
                Succeeded = succeeded,
                Data = data,
                Errors = errors,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            };
        }
    }
}
