using Dapper;
using Nest;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XYY.Common.Standard;
using XYY.Core.Standard.Data.Infrastructure;
using XYY.Data.Standard.Channel;
using XYY.Data.Standard.First;
using XYY.Model.Standard.Channel;
using XYY.Model.Standard.Order;

namespace XYY.Service.Standard.Order
{
    public interface ILadingTrunkLineService
    {
        Task<PageResult<Logistics_TrunkLine>> GetTrunkLinePager(QueryModel queryModel);
        Task<Logistics_TrunkLine> GetTrunkLineInfo(int id);
        Task<bool> DeleteTrunkLineInfo(int id);
        Task EditTrunkLinePager(Logistics_TrunkLine model);
        Task<ChannelTrunkLineParam> GetTrunkLinePushInfo(int Id, IEnumerable<int> channelIds);
    }
    public class LadingTrunkLineService : ILadingTrunkLineService
    {
        private IUnitOfWork _unitOfWork;
        private ILogistics_LadingBillRepository _ladingBillRepository;
        readonly ILogistics_ChannelRepository _channelRepository;
        public LadingTrunkLineService(IUnitOfWork unitOfWork, ILogistics_LadingBillRepository ladingBillRepository, ILogistics_ChannelRepository channelRepository)
        {
            _unitOfWork = unitOfWork;
            _ladingBillRepository = ladingBillRepository;
            _channelRepository = channelRepository;
        }
        public async Task<PageResult<Logistics_TrunkLine>> GetTrunkLinePager(QueryModel queryModel)
        {
            var pager = await _unitOfWork.GetPagingList2Async<Logistics_TrunkLine>(queryModel);
            return pager;
        }
        public async Task<Logistics_TrunkLine> GetTrunkLineInfo(int id)
        {
            var result = await _unitOfWork.QueryAsync<Logistics_TrunkLine>(x => x.Id == id);
            return result.FirstOrDefault();
        }
        public async Task<bool> DeleteTrunkLineInfo(int id)
        {
            return await _unitOfWork.UpdateByPrimaryKeyAsync<Logistics_TrunkLine>("IsDelete", true, id);
        }
        public async Task EditTrunkLinePager(Logistics_TrunkLine model)
        {
            if (!await _ladingBillRepository.IsExistsAsync(x => x.LadingBillNumber == model.LadingBillNumber && x.IsDeleted == false))
            {
                throw new Exception("当前提单号不存在系统中，请确认提单号是否正确！");
            }
            if (model.Id > 0) { await _unitOfWork.UpdateAsync(model); }
            else { await _unitOfWork.InsertAsync(model); }
        }
        public async Task<ChannelTrunkLineParam> GetTrunkLinePushInfo(int Id, IEnumerable<int> channelIds)
        {
            string trunkLineSql = @$"select a.*,b.TotalWeight LadingBillWeight from Logistics_TrunkLine(nolock) a
left join Logistics_LadingBill(nolock) b on b.LadingBillNumber=a.LadingBillNumber
where a.Id={Id}";
            var dbTrunkLine = (await _unitOfWork.QueryBySqlAsync<Logistics_TrunkLine>(trunkLineSql)).FirstOrDefault();
            if (dbTrunkLine.IsDelete) { throw new Exception("干线推送信息已删除，不可使用！"); }
            string boxsSql = @$"select b.* from Logistics_LadingBill(nolock) a
left join Logistics_Box(nolock) b on b.LadingBillNumber=a.LadingBillNumber
where a.LadingBillNumber='{dbTrunkLine.LadingBillNumber}' and b.ChannelId in ({string.Join(',', channelIds)}) ";
            var dbBoxs = await _unitOfWork.QueryBySqlAsync<Logistics_Box>(boxsSql);
            string ordersSql = @"select c.* from Logistics_Box(nolock) a
left join Logistics_BoxDetail(nolock) b on b.BoxId=a.Id
left join Order_Order(nolock) c on c.Id=b.OrderId
where a.Id in @boxIds";
            var dbOrders = await _unitOfWork.QueryBySqlAsync<Order_Order>(ordersSql, null, new { boxIds = dbBoxs.Select(x => x.Id).ToList() });
            var channelInfo = (await _channelRepository.QueryAsync(x => x.Id == channelIds.FirstOrDefault())).FirstOrDefault();
            ChannelTrunkLineParam channelTrunkLineParam = new ChannelTrunkLineParam()
            {
                TrunkLine = dbTrunkLine,
                Box = dbBoxs,
                Orders = dbOrders,
                Channel = channelInfo
            };
            return channelTrunkLineParam;
        }
    }

}
