using FastExpressionCompiler.LightExpression;
using HKLib.Dto;
using HKLib.RabbitMQ.Config;
using HKLib.RabbitMQ.Publisher;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using XExten.Advance.HttpFramework.MultiCommon;
using XExten.Advance.HttpFramework.MultiFactory;
using XExten.Advance.LinqFramework;
using static RabbitMQ.Client.Logging.RabbitMqClientEventSource;

namespace HKLib.Interfaces
{
    public class HKLibHelper
    {
        static Dictionary<string, string> Header = new Dictionary<string, string> {
            {"TenantId",Configer.TenantId }
        };
        /// <summary>
        /// 设置刷卡时间端
        /// </summary>
        public static async Task<bool> SetTime(TimeSpilte input)
        {
            TimeSpilteDto dto = new TimeSpilteDto
            {
                AMEndTime = input.AMEndTime.ToShortTimeString(),
                AMStartTime = input.AMStartTime.ToShortTimeString(),
                PMEndTime = input.PMEndTime.ToShortTimeString(),
                PMStartTime = input.PMStartTime.ToShortTimeString(),
                ATEndTime = input.ATEndTime.ToShortTimeString(),
                ATStartTime = input.ATStartTime.ToShortTimeString(),
            };

            var data = await IHttpMultiClient.HttpMulti
               .AddHeader(t => t.Headers = Header)
               .AddNode(t =>
               {
                   t.NodePath = $"{Configer.SaasRoute}api/one-card/eat-time-interval";
                   t.JsonParam = dto.ToJson();
                   t.ReqType = MultiType.PUT;
               }).Build().RunStringFirstAsync();
            var res = data.ToModel<JObject>()["data"]["isSuccess"].ToString().AsBool();
            if (res)
            {
                Task.Run(() => ServiceQueryPush.QueryPush.PushMQAsync(input, "TimeChanged", MQEnum.Push));
                return res;
            }
            return false;
        }
        /// <summary>
        /// 获取时间
        /// </summary>
        /// <returns></returns>
        public static async Task<TimeSpilte> GetTime()
        {
            var data = await IHttpMultiClient.HttpMulti.AddNode(t =>
            {
                t.NodePath = $"{Configer.SaasRoute}api/one-card/eat-time-interval";
                t.ReqType = MultiType.GET;
            }).Build().RunStringFirstAsync();
   
            return data.ToModel<JObject>()["data"]["data"].ToJson().ToModel<TimeSpilte>();
        }

        /// <summary>
        /// 添加机构
        /// </summary>
        public static async Task<string> SetOrg(string input)
        {
            try
            {
                var data = await IHttpMultiClient.HttpMulti.AddHeader(t => t.Headers = Header).AddNode(t =>
                {
                    t.NodePath = $"{Configer.SaasRoute}api/one-card/member-tag";
                    t.ReqType = MultiType.POST;
                    t.JsonParam = (new { Name = input }).ToJson();
                }).Build().RunStringFirstAsync();
                return data.ToModel<JObject>()["data"]["data"]["id"].ToString();
            }
            catch (System.Exception)
            {
                return string.Empty;
            }
        }

        public static string SetOrgSync(string input)
        {
            var data = IHttpMultiClient.HttpMulti
                .AddHeader(t => t.Headers = Header)
                .AddNode(t =>
                {
                    t.NodePath = $"{Configer.SaasRoute}api/one-card/member-tag";
                    t.ReqType = MultiType.POST;
                    t.JsonParam = (new { Name = input }).ToJson();
                }).Build().RunStringFirst();
            return data.ToModel<JObject>()["data"]["data"]["id"].ToString();
        }

        /// <summary>
        /// 删除机构
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public static async Task<bool> DelOrg(string Id)
        {
            var data = await IHttpMultiClient.HttpMulti
                     .AddHeader(t => t.Headers = Header)
                     .AddNode(t =>
                     {
                         t.NodePath = $"{Configer.SaasRoute}api/one-card/member-tag/{Id}";
                         t.ReqType = MultiType.DELETE;
                     }).Build().RunStringFirstAsync();
            var res = data.ToModel<JObject>()["data"]["isSuccess"].ToString().AsBool();
            return res;
        }


        /// <summary>
        /// /获取机构
        /// </summary>
        /// <returns></returns>
        public static async Task<List<OrgDto>> GetOrg()
        {
            var data = await IHttpMultiClient.HttpMulti.AddHeader(t => t.Headers = Header).AddNode(t =>
              {
                  t.NodePath = $"{Configer.SaasRoute}api/one-card/member-tag-list";
                  t.ReqType = MultiType.GET;
              }).Build().RunStringFirstAsync();
            if (data.IsNullOrEmpty()) return new List<OrgDto>();
            var model = data.ToModel<JObject>()["data"]["data"].ToJson().ToModel<List<OrgOutDto>>();
            return model.Where(t => !t.Name.IsNullOrEmpty()).Select(t => new OrgDto
            {
                Name = t.Name,
                SId = t.Id
            }).ToList();
        }

        /// <summary>
        /// 修改机构
        /// </summary>
        public static async Task<bool> AlterOrg(string input, string Sid)
        {
            var param = (new { Name = input, Id = Sid }).ToJson();
            var data = await IHttpMultiClient.HttpMulti.AddHeader(t => t.Headers = Header).AddNode(t =>
            {
                t.NodePath = $"{Configer.SaasRoute}api/one-card/member-tag";
                t.ReqType = MultiType.PUT;
                t.JsonParam = param;
            }).Build().RunStringFirstAsync();

            return data.ToModel<JObject>()["data"]["isSuccess"].ToString().AsBool();
        }

        public static async Task<string> GetUserMaxNum()
        {
            var data = await IHttpMultiClient.HttpMulti.AddHeader(t => t.Headers = Header).AddNode(t =>
            {
                t.NodePath = $"{Configer.SaasRoute}api/one-card/max-num";
                t.ReqType = MultiType.GET;
            }).Build().RunStringFirstAsync();
            var str = data.ToModel<JObject>()["data"]["data"].ToString();
            var check = str.IsNullOrEmpty();
            if (check) return "0001";
            return (str.AsInt() + 1).ToString().PadLeft(4, '0');
        }
        public static string GetUserMaxNumSync()
        {
            var data = IHttpMultiClient.HttpMulti.AddHeader(t => t.Headers = Header).AddNode(t =>
            {
                t.NodePath = $"{Configer.SaasRoute}api/one-card/max-num";
                t.ReqType = MultiType.GET;
            }).Build().RunStringFirst();
            var str = data.ToModel<JObject>()["data"]["data"].ToString();
            var check = str.IsNullOrEmpty();
            if (check) return "0001";
            return (str.AsInt() + 1).ToString().PadLeft(4, '0');
        }

        /// <summary>
        /// 根据用户命获取下拉用户列表
        /// </summary>
        /// <param name="keyword"></param>
        public static async Task<List<UserListDto>> GetUserList(string keyword)
        {
            var data = await IHttpMultiClient.HttpMulti.AddHeader(t => t.Headers = Header).AddNode(t =>
            {
                t.NodePath = $"{Configer.SaasRoute}api/one-card/staff-list";
                t.ReqType = MultiType.POST;
                t.JsonParam = (new { realName = keyword }).ToJson();
            }).Build().RunStringFirstAsync();
            if (string.IsNullOrEmpty(data))
                return new List<UserListDto>();
            var res = data.ToModel<JObject>()["data"]["data"].ToJson().ToModel<List<UserListDto>>();
            return res.Where(t=>!string.IsNullOrEmpty(t.Name)).OrderByDescending(t=>t.Num).ToList();
        }

        public static List<UserListDto> GetUserListSync(string keyword)
        {
            var data = IHttpMultiClient.HttpMulti.AddHeader(t => t.Headers = Header).AddNode(t =>
            {
                t.NodePath = $"{Configer.SaasRoute}api/one-card/staff-list";
                t.ReqType = MultiType.POST;
                t.JsonParam = (new { realName = keyword }).ToJson();
            }).Build().RunStringFirst();
            if (string.IsNullOrEmpty(data))
                return new List<UserListDto>();
            var res = data.ToModel<JObject>()["data"]["data"].ToJson().ToModel<List<UserListDto>>();
            return res.Where(t => !string.IsNullOrEmpty(t.Name)).OrderBy(t => t.Num).ToList();
        }

        /// <summary>
        /// 添加用户并绑卡
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static async Task<bool> AddUserAndBindCard(UserDto input)
        {
            var data = await IHttpMultiClient.HttpMulti.AddHeader(t => t.Headers = Header).AddNode(t =>
            {
                t.NodePath = $"{Configer.SaasRoute}api/one-card/mmenber-card";
                t.ReqType = MultiType.POST;
                t.JsonParam = (new
                {
                    tagId = input.OrgId,
                    realName = input.Name,
                    num = input.Num,
                    phone = input.Phone,
                    cardNum = input.CardNo
                }).ToJson();
            }).Build().RunStringFirstAsync();
            return data.ToModel<JObject>()["data"]["isSuccess"].ToString().AsBool();

        }

        public static bool AddUserAndBindCardSync(UserDto input)
        {
            var data =  IHttpMultiClient.HttpMulti.AddHeader(t => t.Headers = Header).AddNode(t =>
            {
                t.NodePath = $"{Configer.SaasRoute}api/one-card/mmenber-card";
                t.ReqType = MultiType.POST;
                t.JsonParam = (new
                {
                    tagId = input.OrgId,
                    realName = input.Name,
                    num = input.Num,
                    phone = input.Phone,
                    cardNum = input.CardNo
                }).ToJson();
            }).Build().RunStringFirst();
            return data.ToModel<JObject>()["data"]["isSuccess"].ToString().AsBool();

        }
        /// <summary>
        /// 删除用户
        /// </summary>
        /// <returns></returns>
        public static async Task<bool> DisableUser(string userName)
        {
            List<string> a = new List<string>() { userName };
            var data = await IHttpMultiClient.HttpMulti.AddHeader(t => t.Headers = Header).AddNode(t =>
            {
                t.NodePath = $"{Configer.SaasRoute}api/one-card/del-staff";
                t.ReqType = MultiType.POST;
                t.JsonParam = a.ToJson();
            }).Build().RunStringFirstAsync();
            return data.ToModel<JObject>()["data"]["isSuccess"].ToString().AsBool();
        }
        /// <summary>
        /// 添加用户
        /// </summary>
        /// <param name="input"></param>
        public static async Task<bool> AddUser(UserDto input)
        {
            var data = await IHttpMultiClient.HttpMulti.AddHeader(t => t.Headers = Header).AddNode(t =>
               {
                   t.NodePath = $"{Configer.SaasRoute}api/one-card/staff";
                   t.ReqType = MultiType.POST;
                   t.JsonParam = (new { tagId = input.OrgId, realName = input.Name, phone = input.Phone, num = input.Num }).ToJson();
               }).Build().RunStringFirstAsync();
            return data.ToModel<JObject>()["data"]["isSuccess"].ToString().AsBool();
        }

        public static bool AddUserSync(UserDto input)
        {
            var data = IHttpMultiClient.HttpMulti.AddHeader(t => t.Headers = Header).AddNode(t =>
            {
                t.NodePath = $"{Configer.SaasRoute}api/one-card/staff";
                t.ReqType = MultiType.POST;
                t.JsonParam = (new { tagId = input.OrgId, realName = input.Name, phone = input.Phone, num = input.Num }).ToJson();
            }).Build().RunStringFirst();
            return data.ToModel<JObject>()["data"]["isSuccess"].ToString().AsBool();
        }
        /// <summary>
        /// 变更卡状态 销户
        /// </summary>
        /// <param name="input"></param>
        public static async Task<bool> CardStutasChange(CardStutasDto input)
        {
            input.CardNo = (await GetUserList(input.keywrod)).FirstOrDefault(t => t.Name.Equals(input.keywrod))?.Cards?.FirstOrDefault()?.CardNum;

            var res = await IHttpMultiClient.HttpMulti.AddHeader(t => t.Headers = Header).AddNode(t =>
             {
                 t.NodePath = $"{Configer.SaasRoute}api/one-card/mmenber-card-state";
                 t.ReqType = MultiType.PUT;
                 t.JsonParam = (new { CardNum = input.CardNo, State = input.Stutas }).ToJson();
             }).Build().RunStringFirstAsync();
            var data = res.ToModel<JObject>()["data"]["isSuccess"].ToString().AsBool();
            if (data)
            {
                Task.Run(() => ServiceQueryPush.QueryPush.PushMQAsync(input, "CardStutasChanged", MQEnum.Top));
                return data;
            }
            return false;
        }
        /// <summary>
        /// 报表数据 
        /// type=1 数据参考
        /// 
        /// {
        ///"name": "张三",
        /// "phone": "18208263734",
        ///  "date": "2022-09-24",
        ///  "tag": null,
        ///  "amCount": 3,
        ///  "pmCount": 0,
        ///   "atCount": 0,
        ///   "totalCount": 3
        /// }
        /// 
        /// type=2 数据参考
        /// 
        /// {
        ///"name": null,
        ///"phone": null,
        ///"date": "2022-09-13",
        ///"tag": null,
        ///"amCount": 3,
        ///"pmCount": 1,
        ///"atCount": 0,
        ///"totalCount": 4
        ///}
        /// 
        /// 
        /// </summary>
        /// <param name="input"></param>
        /// <param name="type">1 计次就餐天消费表(每人),2每月餐段消费报表,3月餐段汇总表</param>
        public static async Task<List<ReportCountDto>> Report(ReportDto input, int type = 1)
        {
            var Route = Configer.SaasRoute;
            if (type == 1)
                Route += "api/one-card/day-consume-info";
            if (type == 2)
                Route += "api/one-card/consume-info";
            if (type == 3)
                Route += "api/one-card/time-interval-consume-info";
            var data = await IHttpMultiClient.HttpMulti.AddHeader(t => t.Headers = Header).AddNode(t =>
              {
                  t.NodePath = Route;
                  t.ReqType = MultiType.POST;
                  t.JsonParam = (new { StartTime = input.StartTime.ToShortDateString(), EndTime = input.EndTime.ToShortDateString() }).ToJson();
              }).Build().RunStringFirstAsync();
            return data.ToModel<JObject>()["data"]["data"].ToJson().ToModel<List<ReportCountDto>>();
        }
    }
}
