using DotNetCore.CAP;
using Furion.DependencyInjection;
using Furion.DistributedIDGenerator;
using Microsoft.Extensions.Caching.Distributed;
using Nirvana.Common;
using Senparc.Weixin.MP.AdvancedAPIs;
using Senparc.Weixin.MP.AdvancedAPIs.TemplateMessage;
using Senparc.Weixin.Open.Containers;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YBDevice.Core;
using YBDevice.Entity;

namespace YBDevice.NApi.Application.BodyInfo
{
    /// <summary>
    /// 八电极处理接口
    /// </summary>
    public class BodyService : IBodyService, ITransient
    {
        public string component_AppId = Senparc.Weixin.Config.SenparcWeixinSetting.Component_Appid;
        public string component_Secret = Senparc.Weixin.Config.SenparcWeixinSetting.Component_Secret;
        public string component_Token = Senparc.Weixin.Config.SenparcWeixinSetting.Component_Token;
        public string component_EncodingAESKey = Senparc.Weixin.Config.SenparcWeixinSetting.Component_EncodingAESKey;
        private readonly ISqlSugarRepository<YB_WifiBind> repository;
        private readonly SqlSugarClient dbClient;
        private readonly ILoggerService _loggerService;
        private readonly INoticeService _noticeService;
        private readonly IDistributedCache _cache;
        private readonly ICapPublisher _capBus;
        public BodyService(ISqlSugarRepository<YB_WifiBind> sqlSugarRepository, ILoggerService loggerService, INoticeService noticeService, IDistributedCache cache, ICapPublisher capPublisher)

        {
            repository = sqlSugarRepository;
            dbClient = repository.Context;
            _loggerService = loggerService;
            _noticeService = noticeService;
            _cache = cache;
            _capBus = capPublisher;
        }
        /// <summary>
        /// 数据包解析
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private BodyAnalyDto AnalyProto(BodyRequstDto data)
        {
            BodyAnalyDto dto = new BodyAnalyDto();
            //检查是否为有效的base64数据
            if (!AESEncrypt.IsBase64(data.@params))
            {
                dto.data = data.@params;
                return dto;
            }
            //数据为base64加密
            byte[] resultByte = Convert.FromBase64String(data.@params);
            dto.data = resultByte.BytesToHexStr();
            _loggerService.AddLogger($"八电极wifi结果推送,解析出的数据:{dto.data}", 2);
            int len = resultByte.Count();//数据总长度
            //长度格式是否正确,固定长度为36位
            if (len < 33)
            {
                return dto;
            }
            //前15个字节为sn。中间以 00 分隔。后面为测量结果数据 AA 00 01 F4 00 64 00 64 00 64 00 64 02 30 06 A4 00 00 00 00 
            int i = 0;
            byte[] snbyte = new byte[15];
            for (i = 0; i < 15; i++)
            {
                snbyte[i] = resultByte[i];
            }
            dto.sn = snbyte.BytesToHexStr().Replace(" ", "");
            dto.splitstr = resultByte[i].ByteToHexStr();
            int datalen = len - 16;//数据体长度
            byte[] databyte = new byte[datalen];
            i++;
            for (int j = 0; j < datalen; j++)
            {
                databyte[j] = resultByte[i];
                i++;
            }
            dto.Header = databyte[0].ByteToHexStr();
            if (dto.Header != "A1" && dto.Header != "A2") //第一条数据为A1，第二条数据为A2
            {
                return dto;
            }
            dto.ischecked = true;
            string tmpstr = "";
            for (int j = 1; j < datalen; j++)
            {
                tmpstr += databyte[j].ByteToHexStr();
                if (dto.Header == "A1")
                {
                    if (j == 3)
                    {
                        dto.Weight = tmpstr.HexToDesc();
                        tmpstr = "";
                    }
                    if (j == 7)
                    {
                        dto.lefthandimp = tmpstr.HexToDesc();
                        tmpstr = "";
                    }
                    if (j == 11)
                    {
                        dto.righthandimp = tmpstr.HexToDesc();
                        tmpstr = "";
                    }
                    if (j == 15)
                    {
                        dto.leftfootimp = tmpstr.HexToDesc();
                        tmpstr = "";
                    }
                }
                if (dto.Header == "A2")
                {

                    if (j == 4)
                    {
                        dto.rightfootimp = tmpstr.HexToDesc();
                        tmpstr = "";
                    }
                    if (j == 8)
                    {
                        dto.bodyimp = tmpstr.HexToDesc();
                        tmpstr = "";
                    }
                    if (j == 10)
                    {
                        dto.height = tmpstr.HexToDesc();
                        tmpstr = "";
                    }
                }
            }
            return dto;
        }
        ///<summary>
        /// 处理wifi模块发送过来的数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<int> HandlerBodyDataAsync(BodyRequstDto data)
        {
            //记录发送过来的数据
            _loggerService.AddLogger($"八电极发送原始数据,data={data.ToJson()}", 2);
            var result = AnalyProto(data);
            if (!result.ischecked)
            {
                return -1;
            }
            //数据分两条发送,首先保存第一条,然后根据二条的数据间隔进行保存
            //保存到redis
            var sn = result.sn;
            var key = $"YBDeviceCache:Container:{sn}";
            if (result.Header == "A1")
            {
                var param1 = $"{result.ToJson()}";
                var param1byte = Encoding.UTF8.GetBytes(param1);
                await _cache.SetAsync(key, param1byte, new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromSeconds(5)));
                return 0;
            }
            else
            {
                var existsbyte = await _cache.GetAsync(key);
                if (existsbyte != null && existsbyte.Length > 0)
                {
                    var firstdata = Encoding.UTF8.GetString(existsbyte);
                    var firstjsondata = firstdata.ToObject<BodyAnalyDto>();
                    result.Weight = firstjsondata.Weight;
                    result.lefthandimp = firstjsondata.lefthandimp;
                    result.righthandimp = firstjsondata.righthandimp;
                    result.leftfootimp = firstjsondata.leftfootimp;
                }
                else
                {
                    return -1;
                }
            }

            //检查设备是否存在
            var equ = await dbClient.Queryable<YB_Device>().FirstAsync(x => x.Ecode == result.sn);
            if (equ == null)
            {
                _loggerService.AddLogger($"八电极wifi结果推送,设备未找到,参数:{result.ToJson()}", 3);
                return -1;
            }
            //获取设备绑定的用户列表
            var list = await dbClient.Queryable<YB_WifiBind>().Where(x => x.DevCode == result.sn && x.Subscribe == 1).ToListAsync();
            if (list.Count == 0)
            {
                _loggerService.AddLogger($"八电极wifi结果推送,未绑定用户或均已取关,参数:{result.ToJson()}", 3);
                return -1;
            }
            //由于传送过来的体重为实际*100,身高为实际*10
            decimal weight = (result.Weight * 1.0 / 100.0).ToDecimal();
            decimal height = (result.height * 1.0 / 10.0).ToDecimal();
            #region 记录数据
            Guid resultid = IDGen.NextID();
            await _capBus.PublishAsync("result.service.insertuserresult", new InsertResultDataS2SDto
            {
                DevId = equ.Id,
                IsUserTake = false,
                DeviceLastHeartTime = equ.LastHeartTime,
                DevType = equ.Type,
                BusinessId = equ.BusinessId,
                CreateTime = DateTime.Now,
                SourceType = 3,
                ecode = equ.Ecode,
                familyid = 0,
                fansid = null,
                height = height,
                imp = result.bodyimp,
                LeftArmImp = result.lefthandimp,
                LeftLegImp = result.leftfootimp,
                RightArmImp = result.righthandimp,
                RightLegImp = result.rightfootimp,
                UserId = 0,
                weight = weight,
                orderid = null,
                publicid = "",
                ResultId = resultid
            });
            #endregion
            //发送模版消息
            decimal mheight = height / 100.0m;
            var tpldata = new
            {
                first = new TemplateDataItem($"收到新的测量结果"),
                keyword1 = new TemplateDataItem($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}"),
                keyword2 = new TemplateDataItem($"{height}"),
                keyword3 = new TemplateDataItem($"{weight}"),
                keyword4 = new TemplateDataItem($"{(((weight / (mheight * mheight)) * 10.0m) / 10.0m).ToDecimal(1)}"),
                remark = new TemplateDataItem($"点击查看您的测量报告")
            };
            var token = await AuthorizerContainer.TryGetAuthorizerAccessTokenAsync(component_AppId, "wxda671f842dfda2b8");
            string url = $"https://ybapi.ybhdmob.com/body/br?d={result.sn}|{weight}|{height}|{result.lefthandimp}|{result.righthandimp}|{result.leftfootimp}|{result.rightfootimp}|{result.bodyimp}|{resultid}";

            foreach (var item in list)
            {
                SendTemplateMessageResult results = await TemplateApi.SendTemplateMessageAsync(token, item.OpenId, "0P6GebIlc5vjYJnO272DNt94VS1SDqxDxRgNzAQTmDA", url, tpldata);
                //记录发送结果
                _loggerService.AddLogger($"八电极wifi结果推送,模版消息推送,参数:{result.ToJson()}\r\n结果:{results.ToJson()}", 3);
            }
            return 0;
        }
        /// <summary>
        /// 处理PCH01W发送过来的数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<object> Handler01WDataAsync(BodyRequstDto data)
        {
            var result = AnalyH01WProto(data);
            var successdata = Encoding.UTF8.GetBytes("A901019A");
            var returndata = new
            {
                status = "1",
                data = Convert.ToBase64String(successdata)
            };
            if (!result.ischecked)
            {
                return returndata;
            }
            //发送模版消息
            decimal height = (result.Height * 1.0m) / 10.0m;
            decimal weight = (result.Weight * 1.0m) / 10.0m;
            var tpldata = new
            {
                first = new TemplateDataItem($"收到新的测量结果"),
                keyword1 = new TemplateDataItem($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}"),
                keyword2 = new TemplateDataItem($"{height}CM|{result.imp}Ω"),
                keyword3 = new TemplateDataItem($"{weight}斤"),
                keyword4 = new TemplateDataItem($"{result.sn}"),
                remark = new TemplateDataItem($"点击查看您的测量报告")
            };
            var token = await AuthorizerContainer.TryGetAuthorizerAccessTokenAsync(component_AppId, "wxda671f842dfda2b8");
            var openlist = new List<string>()
            {
                "o2No269VSmA3C3WNFLDrgc1k2vyo",
                "o2No265s2YTuDN4CQwfCcdflk4L0"
            };
            foreach (var item in openlist)
            {
                SendTemplateMessageResult results = await TemplateApi.SendTemplateMessageAsync(token, item, "0P6GebIlc5vjYJnO272DNt94VS1SDqxDxRgNzAQTmDA", "", tpldata);
                //记录发送结果
                _loggerService.AddLogger($"PCH01Wwifi结果推送,模版消息推送,参数:{result.ToJson()}\r\n结果:{results.ToJson()}", 3);
            }
            return returndata;
        }
        /// <summary>
        /// 解析PCH01W数据包
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private H01WAnalyDto AnalyH01WProto(BodyRequstDto data)
        {
            _loggerService.AddLogger($"PCH01W发送原始数据,data={data.ToJson()}", 3);
            H01WAnalyDto dto = new H01WAnalyDto();
            //检查是否为有效的base64数据
            if (!AESEncrypt.IsBase64(data.@params))
            {
                dto.data = data.@params;
                return dto;
            }
            //数据为base64加密
            byte[] resultByte = Convert.FromBase64String(data.@params);
            dto.data = resultByte.BytesToHexStr();
            _loggerService.AddLogger($"PCH01W_wifi结果推送,解析出的数据:{dto.data}", 3);
            int len = resultByte.Count();//数据总长度
            //长度格式是否正确,固定长度为36位
            if (len < 33)
            {
                return dto;
            }
            //前15个字节为sn。中间以 00 分隔。后面为测量结果数据 A9 0F 01
            int i = 0;
            byte[] snbyte = new byte[15];
            for (i = 0; i < 15; i++)
            {
                snbyte[i] = resultByte[i];
            }
            dto.sn = snbyte.BytesToHexStr().Replace(" ", "");
            dto.splitstr = resultByte[i].ByteToHexStr();
            int datalen = len - 16;//数据体长度
            byte[] databyte = new byte[datalen];
            i++;
            for (int j = 0; j < datalen; j++)
            {
                databyte[j] = resultByte[i];
                i++;
            }
            dto.Header = databyte[0].ByteToHexStr();
            if (dto.Header != "A9") //数据包头为A9
            {
                return dto;
            }
            //检查标志位
            var flag = databyte[2].ByteToHexStr();
            if (flag != "01")
            {
                return dto;
            }
            dto.ischecked = true;
            string tmpstr = "";
            for (int j = 1; j < datalen; j++)
            {
                tmpstr += databyte[j].ByteToHexStr();
                if (j == 2)
                {
                    tmpstr = "";
                }
                if (j == 5)
                {
                    dto.Weight = tmpstr.HexToDesc();
                    tmpstr = "";
                }
                if (j == 11)
                {
                    tmpstr = "";
                }
                if (j == 13)
                {
                    dto.Height = tmpstr.HexToDesc();
                    tmpstr = "";
                }
                if (j == 15)
                {
                    dto.imp = tmpstr.HexToDesc();
                    tmpstr = "";
                }
            }
            return dto;
        }
    }
}
