using Bp.Sync.BackEnd.Application.Commands.Inventories.Bills.InboundBills;
using Bp.Sync.BackEnd.Application.Commands.Inventories.Bills.InventoryBills;
using Bp.Sync.BackEnd.Application.Commands.Inventories.Bills.OutboundBills;
using Bp.Sync.BackEnd.Infrastructure.Repositories;
using Bp.Sync.Domain.Elastics.Inventories.Bills;
using Bp.Sync.Dto.Results;
using MediatR;
using Nest;
using System.Data;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Bp.Sync.BackEnd.Application.Commands.Inventories.Bills.Bills
{
    public class UpdateChildBillByBillIdHandler : IRequestHandler<UpdateChildBillByBillIdCommand, BaseResult>
    {
        private readonly IInventoryBillRepository _InventoryBillRepository;
        private readonly IOutboundBillRepository _OutboundBillRepository;
        private readonly IInboundBillRepository _InboundBillRepository;
        private readonly IMediator _mediator;

        public UpdateChildBillByBillIdHandler(IInventoryBillRepository InventoryBillRepository,
            IOutboundBillRepository outboundBillRepository,
            IInboundBillRepository inboundBillRepository,
            IMediator mediator)
        {
            _InventoryBillRepository = InventoryBillRepository;
            _OutboundBillRepository = outboundBillRepository;
            _InboundBillRepository = inboundBillRepository;
            _mediator = mediator;
        }

        public async Task<BaseResult> Handle(UpdateChildBillByBillIdCommand request, CancellationToken cancellationToken)
        {
            var rs = new BaseResult();
            if (!request.Ids.Any()) return new BaseResult { Result = Dto.Results.Result.Failed, Message = "No data" };

            //đồng bộ phiếu kiểm kho
            if (true)
            {
                var query = new BoolQueryDescriptor<InventoryBillElastic>();

                var idQ = new QueryContainerDescriptor<InventoryBillElastic>();
                idQ.Terms(t => t.Field(f => f.BillId).Terms(request.Ids));

                query.Filter(fl => idQ);

                var items = await _InventoryBillRepository.SearchIds(query);

                if (items.Items != null || items.Items.Any())
                {
                    var ids = items.Items.Select(x => x.Id).Distinct().ToList();

                    await _mediator.Send(new UpdateInventoryBillCommand(ids));
                }
            }
            //phiếu nhập kho
            if (true)
            {
                var query = new BoolQueryDescriptor<OutboundBillElastic>();

                var idQ = new QueryContainerDescriptor<OutboundBillElastic>();
                idQ.Terms(t => t.Field(f => f.BillId).Terms(request.Ids));

                query.Filter(fl => idQ);

                var items = await _OutboundBillRepository.SearchIds(query);

                if (items.Items != null || items.Items.Any())
                {
                    var ids = items.Items.Select(x => x.Id).Distinct().ToList();

                    await _mediator.Send(new UpdateOutboundBillCommand(ids));
                }
            }

            //phiếu xuất kho
            if (true)
            {
                var query = new BoolQueryDescriptor<InboundBillElastic>();

                var idQ = new QueryContainerDescriptor<InboundBillElastic>();
                idQ.Terms(t => t.Field(f => f.BillId).Terms(request.Ids));

                query.Filter(fl => idQ);

                var items = await _InboundBillRepository.SearchIds(query);

                if (items.Items != null || items.Items.Any())
                {
                    var ids = items.Items.Select(x => x.Id).Distinct().ToList();

                    await _mediator.Send(new UpdateInboundBillCommand(ids));
                }
            }

            return rs;
        }
    }
}