using BPA.SAAS.Manage.Application.DataBase.Dtos.Bom;
using BPA.SAAS.Manage.Application.DataBase.Dtos.GoodsAttribute;
using BPA.SAAS.Manage.Application.DataBase.Interface;
using BPA.SAAS.Manage.Comm.Enum;
using BPA.SAAS.Manage.Core.Base;
using BPA.SAAS.Manage.Core.DataBase;
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPA.SAAS.Manage.Application.DataBase.Services
{
    public class BomService: IBomService,ITransient
    {
        private readonly ISqlSugarClient _db;
        public BomService(ISqlSugarClient db) 
        {
            _db=db;
        }
        /// <summary>
        /// 配方分类列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<BomSelectList>> GetBomList()
        {
            var res = await _db.Queryable<BPA_Bom>().Select(x => new BomSelectList

            {
                Id = x.Id,
                Name = x.Name
            }).ToListAsync();
            return res;
        }
        /// <summary>
        /// 根据配方id查询配方信息
        /// </summary>
        /// <param name="bomId"></param>
        /// <returns></returns>
        public async Task<BomList> GetBomList(string bomId)
        {
            var res = await _db.Queryable<BPA_Bom>().Where(x=>x.Id== bomId).Select(x => new BomList
            {
                Id = x.Id,
                Name = x.Name,
                Code=x.Code,
                IsMain=x.IsMain,
                Sort=x.Sort,
            }).Mapper(x =>
            {
                x.BomTypeIds = _db.Queryable<BPA_BomTypeInfo>().Where(t => t.BomId == x.Id).Select(t => t.BomTypeId).ToList();
                x.BomEntry = _db.Queryable<BPA_BomEntry>().Where(t => t.BomId == x.Id).ToList();
            }).FirstAsync();
            return res;
        }
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> AddBom(BomInputDto dto)
        {
            BPA_Bom newbPA_BOM = new BPA_Bom
            {
                Name = dto.Name,
                Code = GetNumber2(),
                IsMain = dto.IsMain,
                Sort = dto.Sort,
            };
            var bom =await _db.Insertable(newbPA_BOM).CallEntityMethod(m => m.Create()).ExecuteReturnEntityAsync();
            //添加配方分类
            var list = dto.BomTypeIds.Select(item => new BPA_BomTypeInfo() { BomId = bom.Id, BomTypeId = item }).ToList();
             var res =await _db.Insertable(list).CallEntityMethod(m => m.Create()).ExecuteCommandAsync();
            return res > 0;
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> UpdateBom(BomInputDto dto)
        {
            try
            {
                _db.Ado.BeginTran();
                // 查询数据库中是否存在未删除的商品类型
                var resEntity = _db.Queryable<BPA_Bom>().Where(it => it.IsDeleted == 0).First(it => it.Id == dto.Id);
                if (null == resEntity)
                {
                    return false;
                }
                resEntity.Name = dto.Name;
                resEntity.IsMain = dto.IsMain;
                resEntity.Sort = dto.Sort;
                var res = await _db.Updateable(resEntity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                var bomType = _db.Queryable<BPA_BomTypeInfo>().Where(it => it.BomId == dto.Id).ToList();
                await _db.Deleteable(bomType).ExecuteCommandAsync();
                List<BPA_BomTypeInfo> list = new();
                for (int i = 0; i < dto.BomTypeIds.Count; i++)
                {
                    BPA_BomTypeInfo bomTypeInfo = new();
                    bomTypeInfo.BomId = dto.Id;
                    bomTypeInfo.BomTypeId = dto.BomTypeIds[i];
                    bomTypeInfo.Status = CommonStatus.ENABLE;
                    list.Add(bomTypeInfo);
                }
                await _db.Insertable(list).CallEntityMethod(m => m.Create()).ExecuteCommandAsync();
                _db.Ado.CommitTran();
                return res > 0;
            }
            catch (Exception e)
            {
                _db.Ado.RollbackTran();
                throw Oops.Oh("更新失败，失败信息："+e.Message);
            }
          
        }


        /// <summary>
        /// 更新配方详情
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> UpdateBomBatcing(BomBatcingInputDto dto)
        {
            try
            {
                _db.Ado.BeginTran();
                // 查询数据库中是否存在未删除的商品类型
                var resEntity = _db.Queryable<BPA_Bom>().Where(it => it.IsDeleted == 0).First(it => it.Id == dto.BomId);
                if (null == resEntity)
                {
                    throw Oops.Oh("配方不存在");
                }
                var bomEntry = _db.Queryable<BPA_BomEntry>().Where(it => it.BomId == dto.BomId).ToList();
                await _db.Deleteable(bomEntry).ExecuteCommandAsync();
                List<BPA_BomEntry> list = new();
                for (int i = 0; i < dto.BomEntry.Count; i++)
                {
                    BPA_BomEntry bomEntryInfo = new();
                    bomEntryInfo.BomId = dto.BomEntry[i].BomId;
                    bomEntryInfo.BatchingId = dto.BomEntry[i].BatchingId;
                    bomEntryInfo.BomQty = dto.BomEntry[i].Dosage;
                    bomEntryInfo.IsReplace = false;
                    bomEntryInfo.Status = CommonStatus.ENABLE;
                    list.Add(bomEntryInfo);
                }
                var res=await _db.Insertable(list).CallEntityMethod(m => m.Create()).ExecuteCommandAsync();
                _db.Ado.CommitTran();
                return res > 0;
            }
            catch (Exception e)
            {
                _db.Ado.RollbackTran();
                throw Oops.Oh("更新失败，失败信息：" + e.Message);
            }

        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> DeleteBom(string id)
        {
            try
            {
                _db.Ado.BeginTran();
                var resEntity = _db.Queryable<BPA_Bom>().Where(it => it.IsDeleted == 0).First(it => it.Id == id);
                if (null == resEntity)
                {
                    throw Oops.Oh("配方不存在");
                }
                resEntity.IsDeleted = 1;
                var res = await _db.Updateable(resEntity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                var BomTypeInfo = _db.Queryable<BPA_BomTypeInfo>().Where(it => it.BomId == id).Select(x => x.Id).ToList();
                await _db.Deleteable<BPA_BomTypeInfo>(BomTypeInfo).ExecuteCommandAsync();
                _db.Ado.CommitTran();
                return res > 0;
            }
            catch (Exception)
            {
                _db.Ado.RollbackTran(); 
                throw Oops.Oh("删除失败"); ;
            }
        }
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> AddBomType(AddBomTypeInputDto dto)
        {
            BPA_BomType newbPA_BOM = new BPA_BomType
            {
                Name = dto.Name
            };
            var res = await _db.Insertable(newbPA_BOM).CallEntityMethod(m => m.Create()).ExecuteCommandAsync();
            return res > 0;
        }
        /// <summary>
        /// 配方分类列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<dynamic>> GetBomTypeList()
        {
            var res = await _db.Queryable<BPA_BomType>().Select<dynamic>(x => new

            {
                id = x.Id,
                name = x.Name
            }).ToListAsync();
            return res;
        }

        private string GetNumber2(int Length = 10)
        {
            byte[] buffer = Guid.NewGuid().ToByteArray();
            var ram = BitConverter.ToInt64(buffer, 0);
            var str = string.Format("{0}", ram.ToString().Substring(0, Length));
            return str;
        }

        /// <summary>
        ///获取 配方列表
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        public async Task<PageUtil> BomPage(BomPageInputDto inputDto)
        {

            var pertainList = _db.Queryable<BPA_BomTypeInfo, BPA_BomType>((a, b) =>
                    new JoinQueryInfos(JoinType.Left, a.BomTypeId == b.Id))
                .Where((a, b) => a.IsDeleted == 0 && b.IsDeleted == 0)
                //.WhereIF(inputDto.Pertains != null && inputDto.Pertains.Count > 0, (a, b) => inputDto.Pertains.Contains(b.Pertain))
                //.WhereIF(!string.IsNullOrWhiteSpace(inputDto.bomTypeList), (a, b) => b.Id == inputDto.bomTypeList)
                .Select((a, b) => a.BomId)
                .ToList();

            int total = new RefAsync<int>();
            var res =  _db.Queryable<BPA_Bom>()
                .Where(it => it.IsDeleted == 0)
                .WhereIF(!string.IsNullOrEmpty(inputDto.Name),x=>x.Name.Contains(inputDto.Name))
                //.WhereIF(!string.IsNullOrWhiteSpace(inputDto.bomTypeList), x => pertainList.Contains(x.Id))
                .OrderBy(i => i.CreateAt, OrderByType.Desc)
                .ToPageList(inputDto.Current, inputDto.PageSize, ref total);


            var listtype = _db.Queryable<BPA_BomTypeInfo>()
                .Where(a => res.Select(x => x.Id).Contains(a.BomId) && a.IsDeleted == 0).ToList();

            var data = new List<object>();
            foreach (var item in res)
            {
                var obj = listtype.Where(x => x.BomId == item.Id).Select(x => x.BomTypeId).ToList();
                data.Add(new
                {
                    BomTypeList = obj,
                    Name = item.Name,
                    Code = item.Code,
                    item.IsMain,
                    item.BOMInfo,
                    item.Status,
                    item.Id,
                    item.Sort,
                });
            }

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

        /// <summary>
        /// 添加配方
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> AddBom(BomCreateInputDto dto)
        {
            _db.Ado.BeginTran();
            try
            {
                var sortMax = _db.Queryable<BPA_Bom>().Max(x => x.Sort);
                BPA_Bom newbPA_BOM = new BPA_Bom
                {
                    Name = dto.BomName,
                    Code = GetNumber2(),
                    IsMain = true,
                    Sort = sortMax + 1,
                    Id = Guid.NewGuid().ToString(),
                    CreateAt = DateTime.Now,
                    Status = CommonStatus.ENABLE,
                };
                //添加配方
                var res = _db.Insertable(newbPA_BOM).CallEntityMethod(m => m.Create()).ExecuteCommand();
                //添加配方分类
                var list = dto.BomtypeList.Select(item => new BPA_BomTypeInfo() { BomId = newbPA_BOM.Id, BomTypeId = item }).ToList();
                _db.Insertable(list).CallEntityMethod(m => m.Create()).ExecuteCommand();

              
                List<BPA_BomEntry> BOMEntryList = new();
                if (dto.Mate.Count > 0)
                {
                    for (int i = 0; i < dto.Mate.Count; i++)
                    {
                        BPA_BomEntry newbPA_BOMEnty = new BPA_BomEntry
                        {
                            BatchingId = dto.Mate[i].batchingId,
                            //BatchingKey = dto.Mate[i].AutoKey,
                            BomQty = dto.Mate[i].dosage,
                            BomId = newbPA_BOM.Id,
                            Status = CommonStatus.ENABLE,
                            IsReplace = false,
                        };
                        BOMEntryList.Add(newbPA_BOMEnty);
                    }
                }
                //添加配方物料关系
                _db.Insertable(BOMEntryList).CallEntityMethod(m => m.Create()).ExecuteCommand();
                _db.Ado.CommitTran();
                return true;
            }
            catch (Exception e)
            {
                _db.Ado.RollbackTran();
                throw Oops.Oh("添加失败，失败信息：" + e.Message);
            }
        }

        /// <summary>
        /// 删除配方
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> DelBom(string id)
        {

            try
            {
                _db.Ado.BeginTran();
                await _db.Deleteable<BPA_Bom>().Where(x => x.Id == id).ExecuteCommandAsync();
                await _db.Deleteable<BPA_BomEntry>().Where(x => x.BomId == id).ExecuteCommandAsync();
                _db.Ado.CommitTran();
                return true;
            }
            catch (Exception e)
            {
                _db.Ado.RollbackTran();
                throw Oops.Oh("删除失败" + e.Message);
            }
        }
    }
}
