using BPA.KitChen.GroupMeal.Application.BaseDto;
using BPA.KitChen.GroupMeal.Application.Service.Device.Dtos;
using BPA.KitChen.GroupMeal.Core.Entity;
using BPA.KitChen.GroupMeal.Core.Enum;
using BPA.KitChen.GroupMeal.SqlSugar;
using BPA.Message;
using Furion.DependencyInjection;
using Furion.FriendlyException;
using Mapster;
using MQTTnet;
using MQTTnet.Client;
using Newtonsoft.Json;
using SqlSugar;

namespace BPA.KitChen.GroupMeal.Application.Service.Device.Services
{
    public class DevicePushRecodeService: IDevicePushRecodeService, ITransient
    {
        private readonly SqlSugarScope _db;
        private readonly IMqttClient _mqttClient;
        RequestParmsHeadlen requestParmsHeadlen = new();
        public DevicePushRecodeService( IMqttClient mqttClient)
        {
            _db = SqlSugarDb.Db;
            _mqttClient =mqttClient;
        }
        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageUtil> Page(DevicePushRecodeDtoPageInput input)
        {
            RefAsync<int> total = 0;
            var res = await _db.Queryable<BPA_DevicePushRecode>().Where(x=>x.Type== input.Type)
                .WhereIF(!string.IsNullOrWhiteSpace(input.DeviceName),x=>x.DeviceName.Contains(input.DeviceName))
                  .WhereIF(!string.IsNullOrWhiteSpace(input.Status), x => x.Status == (CommonStatus)Convert.ToInt32(input.Status))
                   .Select(t => new 
                   {
                       CreateAt = t.CreateAt,
                       CreateBy = t.CreateBy,
                       Id = t.Id,
                       DeviceId = t.DeviceId,
                       DeviceName= t.DeviceName,
                      Type =t.Type,
                       Topic=t.Topic,
                       DataResore=t.DataResore,
                       Status=t.Status,
                       Description=t.Description,
                   }).OrderBy(x => x.CreateAt, OrderByType.Desc).ToPageListAsync(input.Current, input.PageSize, total);
            PageUtil util = new PageUtil()
            {
                Total = total,
                Data = res

            };
            return util;
        }
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> Add(DevicePushRecodeDtoInput input)
        {
            var DataResore =await requestParmsHeadlen.GetParm(input.Type, input.Data.ToString(), input.DeviceId);
            var data = input.Adapt<BPA_DevicePushRecode>();
            string topstr = "";
            string Topic = GetTopic(input.Type, input.DeviceAutoKey.ToString(), input.ProductVersion, input.ProductKey, out topstr);
            if (string.IsNullOrEmpty(Topic)) throw Oops.Oh("请配置相关topic");
         
            data.Topic= Topic;
            data.Status = CommonStatus.ENABLE;
            data.DataResore =  JsonConvert.SerializeObject(DataResore);
            data.DeviceAutoKey= input.DeviceAutoKey;
            data.Description = "成功";
            if (input.TopicsData.Count > 0)
            {
                var chaeck = input.TopicsData.Any(x => x.Topics.Trim() == topstr.Trim());
                if (!chaeck)
                {
                    data.Status = CommonStatus.DISABLE;
                    data.Description = "下发数据失败，该产品还未配置对应的topic,请联系管理员进行配置";
                }
            }
            else
            {
                data.Status = CommonStatus.DISABLE;
                data.Description = "下发数据失败，该产品还未配置对应的topic,请联系管理员进行配置";
            }
            if (data.Status == CommonStatus.ENABLE)
            {
                var respush = await Push(Topic, new PushData() { Data = data.DataResore, DeviceId = input.DeviceAutoKey });
                if (respush != "success")
                {
                    data.Description = respush;
                    data.Status = CommonStatus.ENABLE;
                }
            }
           // return true;
            var res = await _db.Insertable(data).CallEntityMethod(t => t.Create()).ExecuteCommandAsync();
            return res>0;
        }
        public async Task<bool> Update(string id)
        {
            var data = _db.Queryable<BPA_DevicePushRecode>().Where(x => x.Id == id).First();
            data.Status = CommonStatus.ENABLE;
            var respush = await Push(data.Topic, new PushData() { Data = data.DataResore, DeviceId = data.DeviceAutoKey });
            if (respush!= "success")
            {
                data.Description = respush;
                data.Status = CommonStatus.DISABLE;
            }
            var res = await _db.Updateable(data).ExecuteCommandAsync();
            return res > 0;
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> Delete(List<string> input)
        {
            try
            {
                // 查询数据库中是否存在未删除的活动信息
                var resEntitites = _db.Queryable<BPA_DevicePushRecode>().In(input).ToList();
                var res = await _db.Deleteable(resEntitites).ExecuteCommandAsync();
                return res > 0;

            }
            catch (Exception)
            {
                throw Oops.Oh("删除失败");
            }
        }
        private async Task<string> Push(string Topic,PushData data)
        {
            try
            {
                // Topic = TOPIC.GetInstance.GetBusinessTopic(x, storeInfo.FirstOrDefault(a => a.Id == item.OrgId).AutoKey) + "/" + item.AutoKey;
                BPAPackage bPAPackage = new BPAPackage
                {
                    MessageId = MessageID.TMC_PUSH_INGREDIENTS,
                    ClientId = data.DeviceId,
                    //ClientType = Procuct
                    MessageVersion = 0x30,
                    Timestamp = DateTime.Now,
                    Message = data
                };
                //每次下发暂停200毫秒 by 王刚 2022-06-08 测试提出修改
                // Thread.Sleep(200);
                //string aa = bPAPackage.Serialize(false);
                var applictionmessage = new MqttApplicationMessageBuilder().WithTopic(Topic).WithPayload(bPAPackage.Serialize(false)).WithAtLeastOnceQoS().Build();
                 await _mqttClient.PublishAsync(applictionmessage);
                return "success";
            }
            catch (Exception e)
            {
                return "下发错误，错误信息：" + e.Message; 
               
            }
        }
        private string GetTopic(int type,string deviceKey, string productVersion, string productKey,out string topstr )
        {
            string topic = "";
            topstr = "";
            switch (type)
            {
                case 1: //商品下发
                    topic = $"/{productKey}/{productVersion}/{deviceKey}/defaul/goodspush";
                    topstr = "/"+productKey+"/"+productVersion+"/${deviceKey}/defaul/goodspush";
                    break;
                case 2://物料下发
                    topic = $"/{productKey}/{productVersion}/{deviceKey}/defaul/batvhingpush";
                    topstr = "/" + productKey + "/" + productVersion + "/${deviceKey}/defaul/batvhingpush";
                    break;
                case 4:
                    topic = $"/{productKey}/{productVersion}/{deviceKey}/defaul/chnologypush";
                    topstr = "/" + productKey + "/" + productVersion + "/${deviceKey}/defaul/chnologypush";
                    break;
            }
            return topic;
        }
    }
}
