using Bp.Sync.Dto.Results;
using MediatR;
using System.Data;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Bp.Sync.BackEnd.Infrastructure.Repositories;
using System.Collections.Generic;
using Nest;
using Bp.Sync.Domain.Elastics.FcBusinesses;
using Bp.Sync.BackEnd.Infrastructure.Repositories.FcCustomers;
using Bp.Sync.BackEnd.Infrastructure.Repositories.FcBusinesses;
using CommonLibrary;
using System.Data.SqlClient;
using Microsoft.Extensions.Configuration;
using Dapper;
using Vina.Search.Infrastructure.Mappings;
using Bp.Sync.Domain.Elastics.FcBusinesses.Products;

namespace Bp.Sync.BackEnd.Application.Commands.FcBusinesses.RetailStatistics
{
    public class UpdateRetailStatisticCustomerPhoneNumberHandler : IRequestHandler<UpdateRetailStatisticCustomerPhoneNumberCommand, BaseResult>
    {
        private readonly IProductRepository _productRepository;
        private readonly IUnitRepository _unitRepository;
        private readonly IFcCustomerRepository _fcCustomerRepository;
        private readonly IRetailStatisticRepository _retailStatisticRepository;
        private readonly IFcReceiptBillRepository _fcReceiptBillRepository;
        private readonly IDbConnection _dbConnection;
        private readonly IFcProductStorageRepository _fcProductStorageRepository;

        public UpdateRetailStatisticCustomerPhoneNumberHandler(IConfiguration configuration, IFcCustomerRepository fcCustomerRepository,
            IRetailStatisticRepository retailStatisticRepository,
            IFcProductStorageRepository fcProductStorageRepository,
            IProductRepository productRepository, IUnitRepository unitRepository, IFcReceiptBillRepository fcReceiptBillRepository)
        {
            _productRepository = productRepository;
            _unitRepository = unitRepository;
            _fcCustomerRepository = fcCustomerRepository;
            _retailStatisticRepository = retailStatisticRepository;
            _fcReceiptBillRepository = fcReceiptBillRepository;
            var connectionString = configuration.GetConnectionString("FcBusinessConnection");
            _dbConnection = new SqlConnection(connectionString);
            _fcProductStorageRepository = fcProductStorageRepository;
        }
        public async Task<BaseResult> Handle(UpdateRetailStatisticCustomerPhoneNumberCommand request, CancellationToken cancellationToken)
        {
            var rs = new BaseResult();

            var listUpdated = new List<RetailStatisticElastic>();

            //lay ra RetailStatistic k co invoice
            var query = new BoolQueryDescriptor<RetailStatisticElastic>();

            var notCustomerNameQ = new QueryContainerDescriptor<RetailStatisticElastic>();
            notCustomerNameQ.Bool(b => b.MustNot(m => m.Exists(e => e.Field(f => f.CustomerPhoneNumber))));
            var notRetailCustomerQ = new QueryContainerDescriptor<RetailStatisticElastic>();
            notRetailCustomerQ.Range(b => b.Field(f => f.CustomerId).GreaterThan(0));

            var isDeletedQ = new QueryContainerDescriptor<RetailStatisticElastic>();
            isDeletedQ.Terms(t => t.Field(f => f.IsDeleted).Terms(false));

            var idQ = new QueryContainerDescriptor<RetailStatisticElastic>();
            if (request.Ids.Any()) idQ.Terms(t => t.Field(f => f.Id).Terms(request.Ids));
            if (request.Ids.Any())
                query.Filter(fl => idQ && isDeletedQ);
            else query.Filter(fl => notCustomerNameQ && notRetailCustomerQ && isDeletedQ);

            var items = await _retailStatisticRepository.Search(query, 10000);
            if (items.Items == null || !items.Items.Any()) return new BaseResult { Message = "No data update", Result = Dto.Results.Result.Success };


            var customerids = items.Items.Where(x => x.CustomerId.HasValue).Select(x => x.CustomerId.Value).Distinct().ToList();
            var customers = await _fcCustomerRepository.GetByIds(customerids.Select(x => (long)x).ToList());


            foreach (var item in items.Items)
            {
                if (item.CustomerId.HasValue && item.CustomerId.Value > 0)
                {
                    var cus = customers.Items.FirstOrDefault(x => x.Id == item.CustomerId.Value);
                    item.CustomerName = cus?.FullName;
                    item.CustomerUserName = cus?.UserName;
                    item.CustomerPhoneNumber = cus?.PhoneNumber;
                }
                else
                {
                    item.CustomerName = "Khách lẻ";
                    item.CustomerUserName = "Khách lẻ";
                    item.CustomerUserName = "";
                }

                listUpdated.Add(item);
            }

            if (listUpdated.Any())
            {
                var rs2 = await _retailStatisticRepository.AddManyAsync(listUpdated);
                if (rs2.Result == Dto.Results.Result.Success)
                {
                    rs.Message = $"{listUpdated.Count} - updated";
                    rs.Result = Dto.Results.Result.Success;
                }
                else
                {
                    rs.Message = $"can not insert db";
                    rs.Result = Dto.Results.Result.Success;
                }
            }
            return rs;
        }
    }
}
