using BPA.KitChen.GroupMeal.Application.Service.OneCard.DiningPlate.Dtos;
using BPA.KitChen.GroupMeal.Core.Entity;
using BPA.KitChen.GroupMeal.Core.Enum;
using BPA.KitChen.GroupMeal.SqlSugar;
using Furion.DependencyInjection;
using Furion.FriendlyException;
using MQTTnet.Client;
using NPOI.POIFS.Crypt.Dsig;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BPA.KitChen.GroupMeal.Application.BaseDto;
using BPA.KitChen.GroupMeal.Application.Service.OneCard.Member.MemberInfo.Dtos.MemberTag;
using Microsoft.AspNetCore.Components.Forms;
using MathNet.Numerics.Distributions;
using BPA.KitChen.GroupMeal.Core.Common;
using BPA.Kitchen.Core.Common.RequestAnalysis;
using BPA.KitChen.GroupMeal.Application.Service.OneCard.ReportStatistics.Reservation.Dto;
using Furion;
using Newtonsoft.Json;
using BPA.KitChen.GroupMeal.Application.Service.AExternalPlatform.Service.DiningPlateService.Dtos;

namespace BPA.KitChen.GroupMeal.Application.Service.OneCard.DiningPlate.Service
{
    public class DiningPlateService: UserAnalysis,ITransient, IDiningPlateService
    {
        private readonly SqlSugarScope db;

        public DiningPlateService()
        {
            db = SqlSugarDb.Db;
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        public async Task<PageUtil> Page(DiningPlatePageIndexDto inputDto)
        {
            var result = new List<BPA_DiningPlate>();

            int total = new RefAsync<int>();
            if (string.IsNullOrEmpty(inputDto.IsOccupy))
            {
                var res = db.Queryable<BPA_DiningPlate>()
                    .Where(x => x.IsDeleted == 0)
                    .WhereIF(!string.IsNullOrEmpty(inputDto.QRCode), x => x.QRCode.Contains(inputDto.QRCode) )
                    .WhereIF(!string.IsNullOrEmpty(inputDto.ChipCode), x => x.ChipCode.Contains(inputDto.ChipCode) )
                    .WhereIF(inputDto.Status.HasValue, x => x.Status == inputDto.Status)
                    .OrderBy(x => x.CreateAt, OrderByType.Desc)
                    .Select(t => new DiningPlateDto
                    {
                        Id = t.Id.SelectAll()

                    }).ToPageList(inputDto.Current, inputDto.PageSize, ref total);

                var data = await GetDiningPlateOccupyInfo(res.Select(x => x.Id).ToList());
                if (data != null)
                {
                    foreach (var item1 in data)
                    {
                        foreach (var item2 in res.Where(item2 => item1.DiningPlateId == item2.Id))
                        {
                            item2.IsOccupy = item1.IsOccupy;
                            item2.WeighOrderId = item1.WeighOrderId;
                        }
                    }
                }

                return new PageUtil()
                {
                    Data = res,
                    Total = total
                };
            }

            if (inputDto.IsOccupy.ToUpper() == "true".ToUpper())
            {
                var data = await GetDiningPlateOccupyInfo(new List<string>());
                var diningPlateIdList = data==null?new List<string>():data.Select(x => x.DiningPlateId).ToList();
                var res = db.Queryable<BPA_DiningPlate>()
                    .Where(x => x.IsDeleted == 0)
                    .WhereIF(!string.IsNullOrEmpty(inputDto.QRCode), x => x.QRCode == inputDto.QRCode)
                    .WhereIF(!string.IsNullOrEmpty(inputDto.ChipCode), x => x.ChipCode == inputDto.ChipCode)
                    .WhereIF(inputDto.Status.HasValue, x => x.Status == inputDto.Status)
                    .Where(x=> diningPlateIdList.Contains(x.Id))
                    .OrderBy(x => x.CreateAt, OrderByType.Desc)
                    .Select(t => new DiningPlateDto
                    {
                        Id = t.Id.SelectAll()

                    }).ToPageList(inputDto.Current, inputDto.PageSize, ref total);
                if (data != null)
                {
                    foreach (var item1 in data)
                    {
                        foreach (var item2 in res.Where(item2 => item1.DiningPlateId == item2.Id))
                        {
                            item2.IsOccupy = item1.IsOccupy;
                            item2.WeighOrderId = item1.WeighOrderId;
                        }
                    }
                }

                return new PageUtil()
                {
                    Data = res,
                    Total = total
                };
            }

            if (inputDto.IsOccupy.ToUpper() == "false".ToUpper())
            {
                var data = await GetDiningPlateOccupyInfo(new List<string>());
                var diningPlateIdList = data == null ? new List<string>() : data.Select(x => x.DiningPlateId).ToList();
                var res = db.Queryable<BPA_DiningPlate>()
                    .Where(x => x.IsDeleted == 0)
                    .WhereIF(!string.IsNullOrEmpty(inputDto.QRCode), x => x.QRCode == inputDto.QRCode)
                    .WhereIF(!string.IsNullOrEmpty(inputDto.ChipCode), x => x.ChipCode == inputDto.ChipCode)
                    .WhereIF(inputDto.Status.HasValue, x => x.Status == inputDto.Status)
                    .WhereIF(diningPlateIdList.Count > 0, x => !diningPlateIdList.Contains(x.Id))
                    .OrderBy(x => x.CreateAt, OrderByType.Desc)
                    .Select(t => new DiningPlateDto
                    {
                        Id = t.Id.SelectAll()

                    }).ToPageList(inputDto.Current, inputDto.PageSize, ref total);

                if (data != null)
                {
                    foreach (var item1 in data)
                    {
                        foreach (var item2 in res.Where(item2 => item1.DiningPlateId == item2.Id))
                        {
                            item2.IsOccupy = item1.IsOccupy;
                            item2.WeighOrderId = item1.WeighOrderId;
                        }
                    }
                }
                return new PageUtil()
                {
                    Data = res,
                    Total = total
                };
            }


            return new PageUtil()
            {
                Data = new DiningPlateDto(),
                Total = total
            };
        }

        /// <summary>
        /// 新增餐盘 
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        public async Task<bool> Add(DiningPlateCreateOrUpdataDto inputDto)
        {
            //
            var data = await db.Queryable<BPA_DiningPlate>()
                .FirstAsync(x => inputDto.QRCode == x.QRCode || inputDto.ChipCode == x.ChipCode);
            if (data!=null)
            {
                throw Oops.Oh($"二维码或芯片码已存在");
            }

            data = new BPA_DiningPlate()
            {
                ChipCode = inputDto.ChipCode,
                QRCode = inputDto.QRCode,
                Status = CommonStatus.ENABLE,
                IsPay=inputDto.IsPay,
            };
            var res=await db.Insertable(data).ExecuteCommandAsync();

            return res > 0;
        }


        /// <summary>
        /// 修改餐盘
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        public async Task<bool> Update(DiningPlateCreateOrUpdataDto inputDto)
        {
            var data1 = await db.Queryable<BPA_DiningPlate>()
                .FirstAsync(x => inputDto.QRCode == x.QRCode || inputDto.ChipCode == x.ChipCode);

            var data2 = await db.Queryable<BPA_DiningPlate>()
                .FirstAsync(x =>x.Id==inputDto.Id);
            if (data2==null)
            {
                throw Oops.Oh($"操作数据不存在");
            }
            else
            {
                if (data1!=null&& data1.Id!=data2.Id)
                {
                    throw Oops.Oh($"二维码或芯片码已存在");
                }
            }

            data2.ChipCode = inputDto.ChipCode;
            data2.QRCode = inputDto.QRCode;
            data2.IsPay = inputDto.IsPay;
            var res = await db.Updateable(data2).ExecuteCommandAsync();
            return res > 0;
        }


        /// <summary>
        /// 启用警用
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        public async Task<bool> EnableDisable(DiningPlateCreateOrUpdataDto inputDto)
        {
            

            var data = await db.Queryable<BPA_DiningPlate>()
                .FirstAsync(x => x.Id == inputDto.Id);
            if (data == null)
            {
                throw Oops.Oh($"操作数据不存在");
            }

            data.Status = data.Status== CommonStatus.DISABLE? CommonStatus.ENABLE: CommonStatus.DISABLE;
            var res = await db.Updateable(data).ExecuteCommandAsync();
            return res > 0;
        }


        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> Del(string id)
        {
            var data = await db.Queryable<BPA_DiningPlate>()
                .FirstAsync(x => x.Id == id);
            if (data == null)
            {
                throw Oops.Oh($"操作数据不存在");
            }
            var res =await db.Deleteable<BPA_DiningPlate>(data).ExecuteCommandAsync();

            return res > 0;
        }



        /// <summary>
        /// 解除占用
        /// </summary>
        /// <returns></returns>
        public async Task<bool> UnbindOccupy(List<DiningPlateOccupyDto> inputDto)
        {
            return await AddUnbindOccupyRecord(inputDto);
        }


        /// <summary>
        /// 获取餐盘信息
        /// </summary>
        /// <param name="diningPlateId"></param>
        /// <returns></returns>
        public async Task<List<DiningPlateDto>> GetDiningPlateInfo(List<string> inputDto)
        {
            var data = await db.Queryable<BPA_DiningPlate>()
                .Where(x=>inputDto.Contains(x.Id))
                .Select(x=>new DiningPlateDto()
                {
                    Id = x.Id.SelectAll(),
                }).ToListAsync();

            return data;
        }


        private async Task<List<DiningPlateOccupyDto>> GetDiningPlateOccupyInfo(List<string> inputDto)
        {
            var result = new List<DiningPlateOccupyDto>();

            try
            {
                Dictionary<string, string> dic = new Dictionary<string, string>();
                dic.Add("GroupId", CurrentUser.TenantId);
                var url = App.Configuration["GroupMealOrderUrl"] + "api/WeighOrder/GetDiningPlateOccupyInfo";
                var inputData = JsonConvert.SerializeObject(inputDto);
                var jsonData = HttpHelper.PostData(url, inputData, Encoding.UTF8, "application/json", dic);
                var data = JsonConvert.DeserializeObject<ResultSAASManageDto<List<DiningPlateOccupyDto>>>(jsonData);

                if (data.statusCode != 200)
                {
                    throw Oops.Oh(data.errors);
                }
                return data.data;
            }
            catch (Exception e)
            {
                throw Oops.Oh($"内部请求错误");
            }

            return result;


        }

        /// <summary>
        /// 获取餐盘信息更具二维码
        /// </summary>
        /// <param name="diningPlateId"></param>
        /// <returns></returns>
        public async Task<DiningPlateDto> GetDiningPlateInfoByQRCode(GetDiningPlateInfoByQRCodeDto inputDto)
        {
            var data = await db.Queryable<BPA_DiningPlate>()
                .Where(x => x.QRCode== inputDto.qrCode)
                .Select(x => new DiningPlateDto()
                {
                    Id = x.Id.SelectAll(),
                }).FirstAsync();

            return data;
        }

        /// <summary>
        /// 获取餐盘信息更具id
        /// </summary>
        /// <param name="diningPlateId"></param>
        /// <returns></returns>
        public async Task<DiningPlateDto> GetDiningPlateInfoById(GetDiningPlateInfoByIdDto inputDto)
        {
            var data = await db.Queryable<BPA_DiningPlate>()
                .Where(x => x.Id == inputDto.Id)
                .Select(x => new DiningPlateDto()
                {
                    Id = x.Id.SelectAll(),
                }).FirstAsync();

            return data;
        }

        /// <summary>
        /// 根据芯片码获取  餐盘
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        public async Task<List<DiningPlateDto>> GetDiningPlateInfoByChipCodeList(GetDiningPlateInfoByChipCodeListDto inputDto)
        {
            var data = await db.Queryable<BPA_DiningPlate>()
                .Where(x => inputDto.ChipCodeList.Contains(x.ChipCode))
                .Select(x => new DiningPlateDto()
                {
                    Id = x.Id.SelectAll(),
                }).ToListAsync();

            return data;
        }

        private async Task<bool> AddUnbindOccupyRecord(List<DiningPlateOccupyDto> inputDto)
        {
            var result = new List<DiningPlateOccupyDto>();

            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic.Add("GroupId", CurrentUser.TenantId);
            var url = App.Configuration["GroupMealOrderUrl"] + "api/WeighOrder/AddWeighOrderDiningPlateUnbindRecord";
            var inputData = JsonConvert.SerializeObject(inputDto);
            var jsonData = HttpHelper.PostData(url, inputData, Encoding.UTF8, "application/json", dic);
            var data = JsonConvert.DeserializeObject<ResultSAASManageDto>(jsonData);

            if (data.statusCode != 200)
            {
                throw Oops.Oh(data.errors);
            }
            return  Convert.ToBoolean(data.data) ;
        }


    }
}
