using BPA.KitChen.GroupMeal.Application.BaseDto;
using BPA.KitChen.GroupMeal.Application.Service.OneCard.Gate;
using BPA.KitChen.GroupMeal.Core.Entity;
using BPA.KitChen.GroupMeal.SqlSugar;
using BPA.Message;
using BPA.Message.API请求;
using BPA.Message.IOT;
using BPA.SAAS.KitChenManage.Application.Device.Dtos;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Furion.LinqBuilder;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Hosting;
using MQTTnet;
using MQTTnet.Client;
using Newtonsoft.Json;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Json;
using System.Text;
using System.Threading.Tasks;

namespace BPA.KitChen.GroupMeal.Application.Service.Device.Services
{

    [ApiDescriptionSettings("设备下发", Tag = "设备下发", SplitCamelCase = false)]
    public class DevicePushRecodeService: IDynamicApiController, ITransient, IDevicePushRecodeService
    {
        private readonly SqlSugarScope _db;
        private readonly IMqttClient _mqttClient;
        public DevicePushRecodeService(ISqlSugarClient db, IMqttClient mqttClient)
        {
            _db = SqlSugarDb.Db; 
            _mqttClient=mqttClient;
        }


        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/api/devicepushrecode/page")]
        public async Task<PageUtil> Page(DevicePushRecodeDtoPageInput input)
        {
            RefAsync<int> total = 0;
            var res = await _db.Queryable<BPA_DevicePushRecode>().Where(x=>x.Type== input.Type)
                   .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,
                   }).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>
        [HttpPost("/api/devicepushrecode/add")]
        public async Task<bool> Add(DevicePushRecodeDtoInput input)
        {
            
            var data = input.Adapt<BPA_DevicePushRecode>();
            string Topic = GetTopic(input.Type, input.DeviceAutoKey.ToString());
            if (string.IsNullOrEmpty(Topic)) throw Oops.Oh("请配置相关topic");
            data.Topic= Topic;
            data.DataResore = JsonConvert.SerializeObject(JsonConvert.DeserializeObject<dynamic>(input.Data.ToString()));
            var res = await Push(Topic, new PushData() { Data = input.Data, DeviceId = input.DeviceAutoKey });
            if (res)
            {
                await _db.Insertable(data).CallEntityMethod(t => t.Create()).ExecuteCommandAsync();
            }
            return res;
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/api/devicepushrecode/delete")]
        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<bool> 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 thisData = new
                {
                    MessageId = MessageID.TMC_PUSH_INGREDIENTS,
                    ClientId = data.DeviceId,
                    //ClientType = Procuct
                    MessageVersion = 0x30,
                    Timestamp = DateTime.Now,
                    Message = data.Data.ToString()
                };

                var applictionmessage = new MqttApplicationMessageBuilder()
                    .WithTopic(Topic)
                    .WithPayload(JsonConvert.SerializeObject(thisData))
                    .WithAtLeastOnceQoS().Build();
                await _mqttClient.PublishAsync(applictionmessage);
                return true;
            }
            catch (Exception e)
            {
                throw Oops.Oh("下发错误，错误信息："+e.Message);
            }
        }
        private string GetTopic(int type,string deviceKey)
        {
            string topic = "";
            switch (type)
            {
                case 1: //商品下发
                    topic = $"/da4bfff042c656210/${deviceKey}/use/goodspush";
                    break;
                case 2://物料下发
                    topic = $"/da4bfff042c656210/${deviceKey}/use/batvhingpush";
                    break;
                case 4:
                    topic = $"/da4bfff042c656210/${deviceKey}/use/chnologypush";
                    break;
            }
            return topic;
        }
    }
}
