using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DAL.Interfaces;
using MDL.Models;
using DB.Database;
using SqlSugar;

namespace DAL.Repositories
{
    /// <summary>
    /// 货物数据仓库实现类
    /// </summary>
    public class CargoDataRepository : ICargoDataRepository
    {
        private readonly ISqlSugarProvider _provider;
        
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="provider">SqlSugar数据库提供程序</param>
        public CargoDataRepository(ISqlSugarProvider provider)
        {
            _provider = provider;
        }
        
        /// <summary>
        /// 批量插入货物数据
        /// </summary>
        public async Task<int> BatchInsertAsync(List<CargoDataEntity> cargoDataList)
        {
            var db = _provider.GetClient();
            return await db.Insertable(cargoDataList).ExecuteCommandAsync();
        }
        
        /// <summary>
        /// 根据中性面单单号查询货物数据
        /// </summary>
        public async Task<CargoDataEntity?> GetByWaybillNumberAsync(string neutralWaybillNumber)
        {
            var db = _provider.GetClient();
            return await db.Queryable<CargoDataEntity>()
                .Where(x => x.NeutralWaybillNumber == neutralWaybillNumber && x.Status == "Y")
                .FirstAsync();
        }
        
        /// <summary>
        /// 查询货物数据
        /// </summary>
        public async Task<IEnumerable<CargoDataEntity>> QueryAsync(string? searchKey = null, int? customerId = null, int pageIndex = 1, int pageSize = 100)
        {
            var db = _provider.GetClient();
            var query = db.Queryable<CargoDataEntity>().Where(x => x.Status == "Y");
            
            // 搜索关键字过滤
            if (!string.IsNullOrEmpty(searchKey))
            {
                query = query.Where(x => 
                    x.NeutralWaybillNumber.Contains(searchKey) ||
                    (x.BillOfLadingNumber != null && x.BillOfLadingNumber.Contains(searchKey)) ||
                    (x.MasterPackageNumber != null && x.MasterPackageNumber.Contains(searchKey)));
            }
            
            // 客户ID过滤
            if (customerId.HasValue)
            {
                query = query.Where(x => x.CustomerId == customerId.Value);
            }
            
            // 分页查询
            return await query
                .OrderByDescending(x => x.ImportedAt)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync();
        }
        
        /// <summary>
        /// 按中性面单单号批量更新货物数据
        /// </summary>
        public async Task<int> BatchUpdateByWaybillNumberAsync(List<CargoDataEntity> cargoDataList)
        {
            var db = _provider.GetClient();
            int totalUpdated = 0;
            
            // 分组更新（每批处理100条）
            foreach (var batch in cargoDataList.GroupBy(x => x.NeutralWaybillNumber))
            {
                var data = batch.FirstOrDefault();
                if (data == null)
                {
                    continue;
                }
                
                // 更新除中性面单单号外的其他字段
                int updated = await db.Updateable<CargoDataEntity>()
                    .SetColumns(x => new CargoDataEntity
                    {
                        BillOfLadingNumber = data.BillOfLadingNumber,
                        MasterPackageNumber = data.MasterPackageNumber,
                        CustomerId = data.CustomerId,
                        ImportedAt = data.ImportedAt,
                        ImportedBy = data.ImportedBy,
                        Status = data.Status
                    })
                    .Where(x => x.NeutralWaybillNumber == data.NeutralWaybillNumber)
                    .ExecuteCommandAsync();
                
                totalUpdated += updated;
            }
            
            return totalUpdated;
        }
        
        /// <summary>
        /// 按中性面单单号批量删除货物数据
        /// </summary>
        public async Task<int> BatchDeleteByWaybillNumbersAsync(List<string> neutralWaybillNumbers)
        {
            var db = _provider.GetClient();
            return await db.Updateable<CargoDataEntity>()
                .SetColumns(x => new CargoDataEntity { Status = "N" })
                .Where(x => neutralWaybillNumbers.Contains(x.NeutralWaybillNumber))
                .ExecuteCommandAsync();
        }
    }
}