using Hotline.Settings;
using Hotline.Share.Tools;
using Hotline.Tools;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using System.Text;

namespace Hotline.Api.Filter;

public class LogFilterAlphaAttribute : ActionFilterAttribute
{
    private ILogger<LogFilterAlphaAttribute> _logger;
    public string Name { get; set; }

    public bool Record { get; set; }

    public LogFilterAlphaAttribute(string name = "", bool record = true)
    {
        Name = name;
        Record = record;
    }

    public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        var repository = context.HttpContext.RequestServices.GetService<ISystemLogRepository>();
        _logger = context.HttpContext.RequestServices.GetService<ILogger<LogFilterAlphaAttribute>>();

        if (Record == false)
        {
            await next();
        }
        else
        {
            var request = context.HttpContext.Request;
            var systemLog = new SystemLog
            {
                Name = this.Name,
            };
            GetMethod(context, systemLog);

            var resultContext = await next();

            if (resultContext.Exception != null)
            {
                StringBuilder sbException = new StringBuilder();
                Exception exception = resultContext.Exception;
                sbException.AppendLine(exception.Message);
                if (exception.InnerException != null)
                    sbException.AppendLine(exception.InnerException.Message);

                sbException.AppendLine(LogTool.GetSubString(resultContext.Exception.StackTrace, 4000));
                systemLog.ExecuteResult = sbException.ToString();
                systemLog.Status = 0;
            }
            else
            {
                systemLog.Status = 1;
                ObjectResult result = context.Result as ObjectResult;
                if (result != null)
                {
                    systemLog.ExecuteResult = JsonConvert.SerializeObject(result.Value);
                }
            }

            await repository.AddAsyncNoException(systemLog);
        }
    }

    private void GetMethod(ActionExecutingContext context, SystemLog systemLog)
    {
        var request = context.HttpContext.Request;
        try
        {
            if (request != null)
            {
                systemLog.ExecuteUrl = request.Method.ToUpper() + "|" + request.Path;
                if (request.Method.ToUpper() == "GET")
                {
                    systemLog.ExecuteParam = request.QueryString.ToString();
                }
                else
                {
                    if (request.ContentType?.IndexOf("multipart/form-data", StringComparison.Ordinal) == -1 && context.ActionArguments.Values.FirstOrDefault() != null)
                    {
                        systemLog.ExecuteParam = context.ActionArguments.Values.FirstOrDefault();
                        systemLog.ExecuteParam = systemLog.ExecuteParam.ToJson().FromJson<dynamic>();
                    }
                }
            }
        }
        catch (Exception e)
        {
            _logger.LogError(e, "GetMethod 异常");
        }
    }
}
