using BPA.KitChen.GroupMeal.Application.BaseDto;
using BPA.KitChen.GroupMeal.Application.Service.Shop;
using BPA.KitChen.GroupMeal.Application.Service.Shop.Dtos;
using BPA.KitChen.GroupMeal.Core.Entity;
using BPA.KitChen.GroupMeal.SqlSugar;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Mapster;
using Mapster.Utils;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using StackExchange.Profiling.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BPA.KitChen.GroupMeal.Application.Service.OneCard.Gate.Dto;
using Furion.DatabaseAccessor;
using MQTTnet.Client;
using MQTTnet;
using EasyNetQ;
using NPOI.OpenXml4Net.OPC;
using BPA.Message;
using System.Drawing.Drawing2D;

namespace BPA.KitChen.GroupMeal.Application.Service.OneCard.Gate
{

    [ApiDescriptionSettings("一卡通", Tag = "档口管理", SplitCamelCase = false)]
    public class GateService : SupperRepository, IDynamicApiController, ITransient, IGateService
    {

        private readonly SqlSugarScope db;

        private readonly IMqttClient _mqttClient;

        public GateService(IMqttClient mqttClient)
        {
            db = SqlSugarDb.Db;
            _mqttClient = mqttClient;
        }



        [HttpPost("/api/GateInfo/add")]
        public async Task<bool> Add(GateInfoAddDto inputDto)
        {
            return await db.Insertable(inputDto.Adapt<BPA_Gate>())
                 .CallEntityMethod(m => m.Create()).ExecuteCommandAsync() > 0;
        }
        [HttpPost("/api/GateInfo/Enable")]
        public async Task<bool> Enable(GateInfoEnableDto inputDto)
        {
            var data = await db.Queryable<BPA_Gate>().Where(x => inputDto.Id == x.Id).ToListAsync();
            foreach (var item in data)
            {
                item.Status = inputDto.Status;
            }
            var res = await db.Updateable(data)
              .CallEntityMethod(m => m.Modify()).ExecuteCommandAsync();
            return res > 0;
        }


        [HttpGet("/api/GateInfo/gatealllist")]
        public async Task<List<GateInfoQueryDto>> GetGateAllList([FromQuery] GateInfoQueryAllInputDto inputDto)
        {
            var total = new RefAsync<int>();
            List<IConditionalModel> conModels = new List<IConditionalModel>();
            if (!string.IsNullOrEmpty(inputDto.StoreId))
            {
                conModels.Add(new ConditionalModel() { FieldName = "a.StoreId", ConditionalType = ConditionalType.Equal, FieldValue = inputDto.StoreId });
            }

            return await db.Queryable<BPA_Gate, ShopEntity>((a, b) =>
                      new JoinQueryInfos(JoinType.Inner, a.StoreId == b.Id))
                .Where((a, b) => a.IsDeleted == 0)
                   .Where(conModels)
               .OrderBy((a, b) => a.CreateAt, OrderByType.Desc)
               .Select((a, b) => new GateInfoQueryDto
               {
                   Id = a.Id.SelectAll(),
                   StoreName = b.Name
               })
               .ToListAsync();
        }

        [HttpGet("/api/GateInfo/gatelist")]
        public async Task<PageUtil> GetGateList([FromQuery] GateInfoQueryInputDto inputDto)
        {
            var total = new RefAsync<int>();
            List<IConditionalModel> conModels = new List<IConditionalModel>();
            if (!string.IsNullOrEmpty(inputDto.StoreId))
            {
                conModels.Add(new ConditionalModel() { FieldName = "a.StoreId", ConditionalType = ConditionalType.Equal, FieldValue = inputDto.StoreId });
            }

            var data = await db.Queryable<BPA_Gate, ShopEntity>((a, b) =>
                      new JoinQueryInfos(JoinType.Left, a.StoreId == b.Id))
                .Where((a, b) => a.IsDeleted == 0)
                   .Where(conModels)
               .OrderBy((a, b) => a.CreateAt, OrderByType.Desc)
               .Select((a, b) => new GateInfoQueryDto
               {
                   Id = a.Id.SelectAll(),
                   StoreName = b.Name
               })
               .ToPageListAsync(inputDto.Current, inputDto.PageSize, total);
            return new PageUtil()
            {
                Data = data,
                Total = total

            };
        }


        [HttpPost("/api/GateInfo/Update")]
        public async Task<bool> Update(GateInfoUpdateDto inputDto)
        {
            var data = await db.Queryable<BPA_Gate>().Where(x => inputDto.Id == x.Id).FirstAsync();
            data.Name = inputDto.Name;
            data.StoreId = inputDto.StoreId;
            data.Remaek = inputDto.Remaek;
            data.Mode = inputDto.Mode;
            data.Status = inputDto.Status;
            data.Price = inputDto.Price;
            var res = await db.Updateable(data)
               .CallEntityMethod(m => m.Modify()).ExecuteCommandAsync();
            return res > 0;
        }
        [HttpPost("/api/GateInfo/AddGateFood")]
        public async Task<bool> AddGateFood(List<GateFoodInputDto> inputDto)
        {
            if (inputDto.Count() <= 0)
                return false;
            string GateId = inputDto.FirstOrDefault().GateId;
            var data = db.Queryable<BPA_GateFood>().Where(a => a.GateId == GateId).ToList();
            if (data.Count() > 0)
            {
                db.Deleteable(data).ExecuteCommand();
            }
            List<BPA_GateFood> bPA_GateFoods = inputDto.Adapt<List<BPA_GateFood>>();
            string[] foodIds = bPA_GateFoods.Select(a => a.FoodId).ToArray();



            //List<BPA_GoodsInfo> foods = await db.Queryable<BPA_GoodsInfo>().Where(a => foodIds.Contains(a.Id)).ToListAsync();
            //foreach (var item in foods)
            //{
            //    var model = bPA_GateFoods.Where(c => c.FoodId == item.Id).FirstOrDefault();
            //    model.FoodName = item.Goods_Name;
            //}
            var key = $"GateFood";
            //ServiceQueryPush.QueryPush.PushMQ("add", key, MQEnum.Push);
           await Push(key,null);
            return await db.Insertable(bPA_GateFoods)
                 .CallEntityMethod(m => m.Create()).ExecuteCommandAsync() > 0;

        }

        [HttpGet("/api/GateInfo/GetGateFoodList")]
        public async Task<List<BPA_GateFood>> GetGateFoodList(string gateId)
        {

            return db.Queryable<BPA_GateFood>().Where(x=>x.GateId==gateId).ToList();
        }


        [HttpPost("/api/GateInfo/AddGateSetUp")]
        public async Task<bool> AddGateSetUp(List<GateSetUpDtoInputDto> inputDto)
        {
            if (inputDto.Count() <= 0)
                return false;
            string GateId = inputDto.FirstOrDefault().GateId;
            var data = db.Queryable<BPA_GateSetUp>().Where(a => a.GateId == GateId).ToList();
            if (data.Count() > 0)
            {
                db.Deleteable(data).ExecuteCommand();
            }
            var key = $"GateSet";
            //TODO:MQ;
            // ServiceQueryPush.QueryPush.PushMQ("add", key, MQEnum.Push);
            return await db.Insertable(inputDto.Adapt<List<BPA_GateSetUp>>())
                 .CallEntityMethod(m => m.Create()).ExecuteCommandAsync() > 0;
        }


        [HttpPost("/api/GateInfo/GetGateFood")]
        public async Task<List<GateFoodInputDto>> GetGateFood(GateFoodQueryInputDto inputDto)
        {
            return await db.Queryable<BPA_GateFood>().Where(a => a.GateId == inputDto.GateId).Select(a => new GateFoodInputDto
            {
                GateId = a.GateId,
                FoodId = a.FoodId,
                FoodName = a.FoodName
            }).ToListAsync();
        }

        [HttpPost("/api/GateInfo/GetGateSetUp")]
        public async Task<List<GateSetUpDtoInputDto>> GetGateSetUp(GateSetUpDtoQueryInputDto inputDto)
        {
            return await db.Queryable<BPA_GateSetUp>().Where(a => a.GateId == inputDto.GateId).Select(a => new GateSetUpDtoInputDto
            {
                GateId = a.GateId,
                Key = a.Key
            }).ToListAsync();
        }



        /// <summary>
        /// 删除档口
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>

        [HttpPost("/api/GateInfo/del")]
        public async Task<bool> Del(string id)
        {
            var data = await db.Queryable<BPA_Gate>().FirstAsync(x => x.Id == id);
            if (data == null)
            {
                throw Oops.Oh($"删除的数据不存在");
            }
            data.IsDeleted = 1;
            var res = await db.Updateable(data)
                .CallEntityMethod(m => m.Delete()).ExecuteCommandAsync();
            return res > 0;
        }


        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 = 0,
                    //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 true;
            }
            catch (Exception e)
            {
                throw Oops.Oh("下发错误，错误信息：" + e.Message);
            }
        }
    }
}
