using System;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;
using Bailun.ServiceFabric.Extension;
using Bailun.ServiceFabric.Core.Extension.HttpContext;
using Bailun.ServiceFabric.Core.Extension;

namespace Bailun.DC.Web
{
    public class BrowseLogAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// 项目id 
        /// </summary>
        private readonly string _projectCode;

        /// <summary>
        /// 模块名称
        /// </summary>
        private readonly string _moduleName;

        /// <summary>
        /// 备注信息
        /// </summary>
        private readonly string _remark;

        /// <summary>
        /// 操作类型 (0查、1增、2删、3修改)
        /// </summary>
        private readonly int _operationType;

        /// <summary>
        /// 此特性负责写浏览日志
        /// </summary>
        /// <param name="projectId">项目id</param>
        /// <param name="moduleName">模块名称</param>
        /// <param name="operationType">操作类型 (0查、1增、2删、3修改)</param>
        /// <param name="remark">备注信息</param>
        public BrowseLogAttribute(string projectCode, string moduleName, int operationType, string remark = "")
        {
            _projectCode = projectCode;
            _moduleName = moduleName;
            _operationType = operationType;
            _remark = remark;
        }

        public override void OnActionExecuted(ActionExecutedContext context)
        {
            try
            {
                string canLogValue = ConfigManagerConf.GetValue("BrowseLogSetting:CanLog");
                if (canLogValue != "yes")
                {
                    return;
                }

                var userId = HttpContextHelper.Current?.User?.GetUid();
                var userName = HttpContextHelper.Current?.User?.GetUserName();
                var companyId = HttpContextHelper.Current?.User?.GetCompanyId();

                // 执行结果
                var isSuccessed = true;
                // 执行失败的信息
                var execFaildMsg = "";

                if (context.Exception != null && context.Result == null)
                {
                    // 方法执行失败  有异常
                    isSuccessed = false;
                    execFaildMsg = context.Exception.Message;
                }

                // 组装写日志的入参
                var input = new AddOperationLogInfoInput
                {
                    UserId = (int)userId,
                    UserName = userName,
                    ProjectCode = _projectCode,
                    OperationType = _operationType,
                    OperationContent = _moduleName,
                    OperationTime = DateTime.Now,
                    IsSuccessed = isSuccessed,
                    FailInfo = execFaildMsg,
                    Remarks = _remark,
                    CompanyId = companyId
                };

                var url = ConfigManagerConf.GetValue("BrowseLogSetting:Url");

                var logRes = PostAsync<AddOperationLogInfoInput, AddOperationLogInfoOutput>(url, input);

                if (logRes.StatusCode != 200)
                {
                    Console.WriteLine($"写浏览日志失败:{logRes.Message}");
                }

            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
        /// <summary>
        /// HttpClient实现Post请求
        /// </summary>
        /// <typeparam name="T1">传入对象类型</typeparam>
        /// <typeparam name="T2">返回对象类型</typeparam>
        /// <param name="url"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public static T2 PostAsync<T1, T2>(string url, T1 content) where T2 : new()
        {
            if (string.IsNullOrWhiteSpace(url) || content == null)
            {
                return new T2();
            }
            try
            {
                //设置内容压缩
                var handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip };
                using (var client = new HttpClient(handler))
                {

                    client.DefaultRequestHeaders.Accept.Clear();
                    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                    var postDataJson = JsonConvert.SerializeObject(content, new JsonSerializerSettings()
                    {
                        ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                        NullValueHandling = NullValueHandling.Ignore
                    });

                    var response = client.PostAsync(url, new StringContent(postDataJson, Encoding.UTF8, "application/json")).Result;
                    //var response = client.PostAsJsonAsync<T1>(url, content).Result;
                    if (response.IsSuccessStatusCode)
                    {
                        var reponseResult = response.Content.ReadAsStringAsync().Result;
                        var result = JsonConvert.DeserializeObject<T2>(reponseResult, new JsonSerializerSettings()
                        {
                            ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                            NullValueHandling = NullValueHandling.Ignore
                        });

                        return result;
                    }
                    return JsonConvert.DeserializeObject<T2>(null, new JsonSerializerSettings()
                    {
                        ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                        NullValueHandling = NullValueHandling.Ignore
                    });
                    //return new T2() { Message = "HTTP响应失败", };
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public class AddOperationLogInfoOutput
        {
            /// <summary>
            /// 信息
            /// </summary>
            [JsonProperty("message")]
            public string Message { get; set; }

            /// <summary>
            /// 结果
            /// </summary>
            [JsonProperty("result")]
            public object Result { get; set; }

            /// <summary>
            /// 状态码
            /// </summary>
            [JsonProperty("statusCode")]
            public int StatusCode { get; set; }
        }
        public class AddOperationLogInfoInput
        {
            /// <summary>
            /// 
            /// </summary>
            public int UserId { get; set; }
            /// <summary>
            /// 系统id
            /// </summary>

            public int ProjectId { get; set; }

            /// <summary>
            /// 系统代码
            /// </summary>
            public string ProjectCode { get; set; }

            /// <summary>
            /// 
            /// </summary>

            public string UserName { get; set; }

            /// <summary>
            /// 公司id
            /// </summary>
            public string CompanyId { get; set; }

            /// <summary>
            /// 操作类型（0查、1增、2删、3修改）
            /// </summary>

            public int OperationType { get; set; }
            /// <summary>
            /// 操作内容
            /// </summary>
            public string OperationContent { get; set; }
            /// <summary>
            /// 操作时间
            /// </summary>
            public DateTime OperationTime { get; set; } = DateTime.Now;
            /// <summary>
            /// 是否操作成功
            /// </summary>
            public bool IsSuccessed { get; set; }

            /// <summary>
            /// 失败原因
            /// </summary>
            public string FailInfo { get; set; }

            /// <summary>
            /// 备注
            /// </summary>
            public string Remarks { get; set; }
        }
    }
}