using System;using System.Threading.Tasks;using System.Linq;
using BLL.Interfaces;
using DAL.Interfaces;
using MDL.Models;
using MDL.DTOs;
using MDL.Enums;
using Microsoft.Extensions.Logging;

namespace BLL.Services
{
    /// <summary>
    /// 标签替换服务实现类
    /// </summary>
    public class LabelReplaceService : ILabelReplaceService
    {
        private readonly ILabelReplaceRepository _labelReplaceRepository;
        private readonly ICustomerApiRepository _customerApiRepository;
        private readonly ICustomerRepository _customerRepository;
        private readonly ILabelScanService _labelScanService;
        private readonly IOrderLogService _orderLogService;
        private readonly IArrivalHandoverFormService _arrivalHandoverFormService;
        private readonly ILogger<LabelReplaceService> _logger;
        private readonly ILabelPdfCacheService _labelPdfCacheService;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="labelReplaceRepository">标签替换仓库</param>
        /// <param name="customerApiRepository">客户API仓库</param>
        /// <param name="customerRepository">客户仓库</param>
        /// <param name="labelScanService">标签扫描服务</param>
        /// <param name="orderLogService">订单日志服务</param>
        /// <param name="arrivalHandoverFormService">到货交接单服务</param>
        /// <param name="logger">日志记录器</param>
        /// <param name="labelPdfCacheService">PDF缓存服务</param>
        public LabelReplaceService(ILabelReplaceRepository labelReplaceRepository, 
                                ICustomerApiRepository customerApiRepository,
                                ICustomerRepository customerRepository,
                                ILabelScanService labelScanService,
                                IOrderLogService orderLogService,
                                IArrivalHandoverFormService arrivalHandoverFormService,
                                ILogger<LabelReplaceService> logger,
                                ILabelPdfCacheService labelPdfCacheService)
        {
            _labelReplaceRepository = labelReplaceRepository;
            _customerApiRepository = customerApiRepository;
            _customerRepository = customerRepository;
            _labelScanService = labelScanService;
            _orderLogService = orderLogService;
            _arrivalHandoverFormService = arrivalHandoverFormService;
            _logger = logger;
            _labelPdfCacheService = labelPdfCacheService;
        }

        /// <summary>
        /// 处理标签替换请求
        /// </summary>
        public async Task<LabelReplaceResult> ProcessLabelReplaceAsync(LabelReplaceMessage request, string customerCode, string apiKey)
        {
            var result = new LabelReplaceResult
            {
                Status = "ok",
                Timestamp = DateTime.UtcNow,
                NeutralWaybillNumber = request?.NeutralWaybillNumber
            };

            try
            {
                // 验证请求参数
                if (request == null || string.IsNullOrEmpty(request.NeutralWaybillNumber))
                {
                    return CreateErrorResult(result, "Neutral waybill number is required");
                }

                // 验证换单状态参数
                if (!string.IsNullOrEmpty(request.ReplaceStatus) && 
                    !request.ReplaceStatus.Equals("Y", StringComparison.OrdinalIgnoreCase) && 
                    !request.ReplaceStatus.Equals("N", StringComparison.OrdinalIgnoreCase))
                {
                    return CreateErrorResult(result, "Invalid replace status. Use 'Y' for normal replacement or 'N' for frozen replacement");
                }

                // 验证API凭证
                int? customerId = null;
                if (!string.IsNullOrEmpty(customerCode) && !string.IsNullOrEmpty(apiKey))
                {
                    var customerApiInfo = await _customerApiRepository.ValidateAndGetApiCredentialsAsync(customerCode, apiKey);
                    if (customerApiInfo == null)
                    {
                        _logger.LogWarning("Invalid API credentials: CustomerCode={CustomerCode}, ApiKey={ApiKey}", 
                            customerCode, apiKey);
                        return CreateErrorResult(result, "Invalid API credentials. Please check your customer_code and api_key.");
                    }

                    // 验证CustomerId是否在customers表中存在
                    var customerExists = await _customerRepository.GetByIdAsync(customerApiInfo.CustomerId) != null;
                    if (!customerExists)
                    {
                        _logger.LogError("Customer not found: CustomerId={CustomerId}, CustomerCode={CustomerCode}", 
                            customerApiInfo.CustomerId, customerCode);
                        return CreateErrorResult(result, "Internal server error: Invalid customer configuration.");
                    }

                    customerId = customerApiInfo.CustomerId;
                    _logger.LogInformation("API credentials validated successfully: CustomerCode={CustomerCode}, CustomerId={CustomerId}", 
                        customerCode, customerId);
                }
                else
                {
                    // 参数为空时的处理（暂时允许）
                    _logger.LogWarning("API credentials not provided or incomplete: CustomerCode={CustomerCode}, ApiKeyProvided={ApiKeyProvided}", 
                        customerCode, !string.IsNullOrEmpty(apiKey));
                }

                _logger.LogInformation("Processing label replace request. NeutralWaybillNumber: {number}, ReplaceStatus: {status}", 
                    request.NeutralWaybillNumber, request.ReplaceStatus);

                // 将请求转换为数据库实体
                var replaceStatus = request.ReplaceStatus?.ToUpper() ?? "Y";
                string labelValue = request.Label;
                
                // 检查Label是否为base64编码，如果是则转换为PDF文件
                if (!string.IsNullOrEmpty(request.Label))
                {
                    // 检查是否为base64编码（简单判断：是否包含base64特征或长度是否符合base64特征）
                    bool isBase64 = request.Label.Length % 4 == 0 && 
                                   (request.Label.StartsWith("data:application/pdf;base64,") || 
                                    System.Text.RegularExpressions.Regex.IsMatch(request.Label, "^[a-zA-Z0-9+/]*={0,3}$"));
                    
                    if (isBase64)
                    {
                        try
                        {
                            // 调用ConvertBase64ToPdfAsync方法将base64转换为PDF文件
                            string fileName = $"{request.NeutralWaybillNumber}.pdf";
                            await _labelReplaceRepository.ConvertBase64ToPdfAsync(request.Label, fileName);
                            
                            // 更新Label值为指定的URL格式
                            labelValue = $"http://172.232.21.79/api-lable/pdf/20260302/{request.NeutralWaybillNumber}.pdf";
                            _logger.LogInformation("Converted base64 label to PDF file for waybill: {number}", request.NeutralWaybillNumber);
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(ex, "Error converting base64 to PDF for waybill: {number}", request.NeutralWaybillNumber);
                            // 如果转换失败，保持原始Label值
                        }
                    }
                }
                
                var labelReplaceEntity = new LabelReplaceEntity
                {
                    BillOfLadingNumber = request.BillOfLadingNumber,
                    MasterPackageNumber = request.MasterPackageNumber,
                    ReferenceNumber = request.ReferenceNumber,
                    NeutralWaybillNumber = request.NeutralWaybillNumber,
                    FinalMileTrackingNumber = request.FinalMileTrackingNumber,
                    Label = labelValue,
                    ReplaceStatus = replaceStatus,
                    CustomerId = customerId // 关联客户ID
                };

                // 检查是否已存在相同的中性面单单号记录
                var existingRecord = await _labelReplaceRepository.GetByWaybillNumberAsync(request.NeutralWaybillNumber);
                int recordId;
                string operation;

                if (existingRecord != null)
                {
                    // 检查是否存在已返回面单的扫描记录，若存在则禁止修改
                    var scanRecords = await _labelScanService.GetScanRecordsByNeutralWaybillNumberAsync(request.NeutralWaybillNumber);
                    if (scanRecords.Any(scan => scan.Result == ScanResult.ReturnedLabel))
                    {
                        return CreateErrorResult(result, "Label has been returned and cannot be modified");
                    }

                    // 更新现有记录 - 仅更新请求中提供的非空字段
                    if (request.BillOfLadingNumber != null)
                    {
                        existingRecord.BillOfLadingNumber = request.BillOfLadingNumber;
                    }
                    if (request.MasterPackageNumber != null)
                    {
                        existingRecord.MasterPackageNumber = request.MasterPackageNumber;
                    }
                    if (request.ReferenceNumber != null)
                    {
                        existingRecord.ReferenceNumber = request.ReferenceNumber;
                    }
                    if (request.FinalMileTrackingNumber != null)
                    {
                        existingRecord.FinalMileTrackingNumber = request.FinalMileTrackingNumber;
                    }
                    if (request.Label != null)
                    {
                        // 检查Label是否为base64编码，如果是则转换为PDF文件
                        string updatedLabelValue = request.Label;
                        
                        // 检查是否为base64编码（简单判断：是否包含base64特征或长度是否符合base64特征）
                        bool isBase64 = request.Label.Length % 4 == 0 && 
                                       (request.Label.StartsWith("data:application/pdf;base64,") || 
                                        System.Text.RegularExpressions.Regex.IsMatch(request.Label, "^[a-zA-Z0-9+/]*={0,3}$"));
                        
                        if (isBase64)
                        {
                            try
                            {
                                // 调用ConvertBase64ToPdfAsync方法将base64转换为PDF文件
                                string fileName = $"{request.NeutralWaybillNumber}.pdf";
                                await _labelReplaceRepository.ConvertBase64ToPdfAsync(request.Label, fileName);
                                
                                // 更新Label值为指定的URL格式
                                updatedLabelValue = $"http://172.232.21.79/api-lable/pdf/20260302/{request.NeutralWaybillNumber}.pdf";
                                _logger.LogInformation("Converted base64 label to PDF file for waybill: {number}", request.NeutralWaybillNumber);
                            }
                            catch (Exception ex)
                            {
                                _logger.LogError(ex, "Error converting base64 to PDF for waybill: {number}", request.NeutralWaybillNumber);
                                // 如果转换失败，保持原始Label值
                            }
                        }
                        
                        existingRecord.Label = updatedLabelValue;
                    }
                    // 总是更新ReplaceStatus字段
                    existingRecord.ReplaceStatus = replaceStatus;
                    // 仅在customerId不为空时更新
                    if (customerId != null)
                    {
                        existingRecord.CustomerId = customerId;
                    }
                    existingRecord.UpdatedAt = DateTime.UtcNow;

                    await _labelReplaceRepository.UpdateAsync(existingRecord);
                    recordId = existingRecord.Id;
                    operation = "updated";
                    
                    // 记录订单日志 - 更新订单
                    await _orderLogService.RecordOrderLogAsync(
                        neutralWaybillNumber: request.NeutralWaybillNumber,
                        finalMileTrackingNumber: request.FinalMileTrackingNumber,
                        operationType: OrderLogOperationType.UPDATE,
                        operationResult: OrderLogOperationResult.SUCCESS,
                        operationDescription: "更新订单成功",
                        @operator: customerCode
                    );
                }
                else
                {
                    // 创建新记录
                recordId = await _labelReplaceRepository.CreateAsync(labelReplaceEntity);
                operation = "created";
                
                // 记录订单日志 - 下单
                await _orderLogService.RecordOrderLogAsync(
                    neutralWaybillNumber: request.NeutralWaybillNumber,
                    finalMileTrackingNumber: request.FinalMileTrackingNumber,
                    operationType: OrderLogOperationType.CREATE_ORDER,
                    operationResult: OrderLogOperationResult.SUCCESS,
                    operationDescription: $"客户在 {DateTime.Now} 下单成功",
                    @operator: customerCode
                );
                }

                _logger.LogInformation("Label replacement request {op} successfully for {number}, RecordId: {id}, ReplaceStatus: {status}", 
                    operation, request.NeutralWaybillNumber, recordId, replaceStatus);

                // 设置成功结果
                result.Id = recordId;
                result.ReplaceStatus = replaceStatus;
                result.LabelReplaced = replaceStatus == "Y";
                result.Message = replaceStatus == "Y"
                    ? "Label replacement request processed successfully"
                    : "Label replacement request has been frozen";

                return result;
            }
            catch (System.Exception ex)
            {
                _logger.LogError(ex, "Error processing label replace request");
                return CreateErrorResult(result, "An error occurred during processing. Please contact support.", ex.Message);
            }
        }

        /// <summary>
        /// 创建错误结果
        /// </summary>
        private LabelReplaceResult CreateErrorResult(LabelReplaceResult result, string message, string errorDetails = "")
        {
            result.Status = "error";
            result.Message = message;
            result.ErrorDetails = errorDetails;
            result.LabelReplaced = false;
            return result;
        }

        /// <summary>
        /// 根据跟踪单号获取标签替换请求记录
        /// </summary>
        public async Task<List<LabelReplaceEntity>> GetLabelReplaceRequestsByTrackingNumberAsync(string trackingNumber)
        {
            if (string.IsNullOrEmpty(trackingNumber))
            {
                return new List<LabelReplaceEntity>();
            }

            try
            {
                _logger.LogInformation("Retrieving label replace requests by tracking number: {number}", trackingNumber);
                var requests = await _labelReplaceRepository.GetByTrackingNumberAsync(trackingNumber);
                _logger.LogInformation("Found {count} label replace requests for tracking number: {number}", requests.Count, trackingNumber);
                return requests;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error retrieving label replace requests by tracking number: {number}", trackingNumber);
                return new List<LabelReplaceEntity>();
            }
        }

        /// <summary>
        /// 根据中性面单单号获取标签替换请求记录
        /// </summary>
        public async Task<LabelReplaceEntity?> GetLabelReplaceRequestByWaybillNumberAsync(string waybillNumber)
        {
            if (string.IsNullOrEmpty(waybillNumber))
            {
                return null;
            }

            try
            {
                _logger.LogInformation("Retrieving label replace request by waybill number: {number}", waybillNumber);
                var request = await _labelReplaceRepository.GetByWaybillNumberAsync(waybillNumber);
                if (request != null)
                {
                    _logger.LogInformation("Found label replace request for waybill number: {number}, Id: {id}", waybillNumber, request.Id);
                }
                else
                {
                    _logger.LogInformation("No label replace request found for waybill number: {number}", waybillNumber);
                }
                return request;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error retrieving label replace request by waybill number: {number}", waybillNumber);
                return null;
            }
        }

        /// <summary>
        /// 获取所有标签替换请求记录
        /// </summary>
        /// <returns>标签替换请求实体列表</returns>
        public async Task<List<LabelReplaceEntity>> GetAllLabelReplaceRequestsAsync()
        {
            try
            {
                _logger.LogInformation("Retrieving all label replace requests");
                var requests = await _labelReplaceRepository.GetAllAsync();
                _logger.LogInformation("Found {count} label replace requests", requests.Count);
                return requests;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error retrieving all label replace requests");
                return new List<LabelReplaceEntity>();
            }
        }

        /// <summary>
        /// 分页获取标签替换请求记录
        /// </summary>
        /// <param name="page">页码</param>
        /// <param name="pageSize">每页大小</param>
        /// <param name="sortBy">排序字段</param>
        /// <param name="sortOrder">排序顺序</param>
        /// <param name="billOfLadingNumber">提单号</param>
        /// <param name="masterPackageNumber">大包号</param>
        /// <param name="referenceNumber">参考号</param>
        /// <param name="neutralWaybillNumber">中性面单单号</param>
        /// <param name="finalMileTrackingNumber">尾程跟踪单号</param>
        /// <param name="replaceStatus">换单状态</param>
        /// <param name="customerId">客户ID</param>
        /// <returns>标签替换请求实体列表和总记录数</returns>
        public async Task<(List<LabelReplaceWithCustomerDto>, int)> GetLabelReplaceRequestsByPageAsync(int page, int pageSize, string sortBy, string sortOrder, string billOfLadingNumber, string masterPackageNumber, string referenceNumber, string neutralWaybillNumber, string finalMileTrackingNumber, string replaceStatus, int? customerId, string startCreatedAt, string endCreatedAt, string startReplacedAt, string endReplacedAt)
        {
            try
            {
                _logger.LogInformation("Retrieving label replace requests by page. Page: {page}, PageSize: {pageSize}, SortBy: {sortBy}, SortOrder: {sortOrder}", page, pageSize, sortBy, sortOrder);
                var (requests, totalCount) = await _labelReplaceRepository.GetByPageAsync(page, pageSize, sortBy, sortOrder, billOfLadingNumber, masterPackageNumber, referenceNumber, neutralWaybillNumber, finalMileTrackingNumber, replaceStatus, customerId, startCreatedAt, endCreatedAt, startReplacedAt, endReplacedAt);
                _logger.LogInformation("Found {count} label replace requests, total: {total}", requests.Count, totalCount);
                return (requests, totalCount);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error retrieving label replace requests by page");
                return (new List<LabelReplaceWithCustomerDto>(), 0);
            }
        }

        /// <summary>
        /// 批量查询换单状态
        /// </summary>
        /// <param name="customerCode">客户代码</param>
        /// <param name="waybillNumbers">中性面单单号列表</param>
        /// <param name="trackingNumbers">尾程跟踪单号列表</param>
        /// <returns>换单状态查询结果列表</returns>
        public async Task<List<LabelReplaceStatusResult>> GetLabelReplaceStatusAsync(string customerCode, List<string> waybillNumbers, List<string> trackingNumbers)
        {
            try
            {
                _logger.LogInformation("Retrieving label replace status. CustomerCode: {customerCode}, Waybills: {waybillCount}, Trackings: {trackingCount}", 
                    customerCode, waybillNumbers?.Count ?? 0, trackingNumbers?.Count ?? 0);

                // 获取客户信息
                var customer = await _customerRepository.GetByCustomerCodeAsync(customerCode);
                if (customer == null)
                {
                    _logger.LogWarning("Customer not found: {customerCode}", customerCode);
                    return new List<LabelReplaceStatusResult>();
                }

                // 确保参数不为null
                var safeWaybillNumbers = waybillNumbers ?? new List<string>();
                var safeTrackingNumbers = trackingNumbers ?? new List<string>();
                
                // 调用仓库方法获取标签替换请求和最新扫描记录
                var (labelReplaceEntities, latestScanMap) = await _labelReplaceRepository.GetLabelReplaceStatusAsync(customer.Id, safeWaybillNumbers, safeTrackingNumbers);
                _logger.LogInformation("Found {count} label replace entities", labelReplaceEntities.Count);
                
                // 确保所有传入的中性面单单号都能查询到最新的扫描记录
                var allWaybillNumbers = new HashSet<string>();
                if (safeWaybillNumbers != null)
                {
                    allWaybillNumbers.UnionWith(safeWaybillNumbers);
                }
                if (labelReplaceEntities != null)
                {
                    allWaybillNumbers.UnionWith(labelReplaceEntities.Select(e => e.NeutralWaybillNumber));
                }
                
                // 对于所有中性面单单号，确保获取最新的扫描记录
                foreach (var waybill in allWaybillNumbers)
                {
                    if (!latestScanMap.ContainsKey(waybill))
                    {
                        // 尝试获取该中性面单单号的扫描记录
                        var scans = await _labelScanService.GetScanRecordsByNeutralWaybillNumberAsync(waybill);
                        if (scans != null && scans.Count > 0)
                        {
                            // 只考虑成功的扫描记录，然后按时间排序取最新的一条
                            var successfulScans = scans.Where(s => s.Result == 0).ToList();
                            if (successfulScans.Count > 0)
                            {
                                var latestScan = successfulScans.OrderByDescending(s => s.CreatedAt).First();
                                latestScanMap[waybill] = latestScan.CreatedAt;
                            }
                        }
                    }
                }

                // 构建结果列表，确保每个单号只返回一次
                var results = new List<LabelReplaceStatusResult>();
                var processedNumbers = new HashSet<string>();

                foreach (var entity in labelReplaceEntities)
                {
                    // 从映射中获取最新扫描时间
                    var replaced = latestScanMap.ContainsKey(entity.NeutralWaybillNumber);
                    var replacedAt = replaced ? latestScanMap[entity.NeutralWaybillNumber] : (DateTime?)null;

                    // 检查是否已经处理过这个中性面单号
                    if (!processedNumbers.Contains(entity.NeutralWaybillNumber))
                    {
                        var result = new LabelReplaceStatusResult
                        {
                            WaybillNumber = entity.NeutralWaybillNumber,
                            TrackingNumber = entity.FinalMileTrackingNumber ?? string.Empty,
                            Replaced = replaced,
                            ReplacedAt = replacedAt
                        };

                        results.Add(result);
                        processedNumbers.Add(entity.NeutralWaybillNumber);
                    }
                    
                    // 检查是否已经处理过这个尾程跟踪单号
                    if (!string.IsNullOrEmpty(entity.FinalMileTrackingNumber) && !processedNumbers.Contains(entity.FinalMileTrackingNumber))
                    {
                        var result = new LabelReplaceStatusResult
                        {
                            WaybillNumber = string.Empty,
                            TrackingNumber = entity.FinalMileTrackingNumber,
                            Replaced = replaced,
                            ReplacedAt = replacedAt
                        };

                        results.Add(result);
                        processedNumbers.Add(entity.FinalMileTrackingNumber);
                    }
                }

                // 处理未找到的单号
                if (waybillNumbers != null && waybillNumbers.Count > 0)
                {
                    foreach (var waybill in waybillNumbers)
                    {
                        if (!processedNumbers.Contains(waybill))
                        {
                            // 尝试通过中性面单单号获取标签替换请求
                            var labelReplaceEntity = await _labelReplaceRepository.GetByWaybillNumberAsync(waybill);
                            
                            var result = new LabelReplaceStatusResult
                            {
                                WaybillNumber = waybill,
                                TrackingNumber = labelReplaceEntity?.FinalMileTrackingNumber ?? string.Empty,
                                Replaced = latestScanMap.ContainsKey(waybill),
                                ReplacedAt = latestScanMap.ContainsKey(waybill) ? latestScanMap[waybill] : (DateTime?)null
                            };
                            
                            results.Add(result);
                            processedNumbers.Add(waybill);
                        }
                    }
                }

                if (trackingNumbers != null && trackingNumbers.Count > 0)
                {
                    foreach (var tracking in trackingNumbers)
                    {
                        if (!processedNumbers.Contains(tracking))
                        {
                            results.Add(new LabelReplaceStatusResult
                            {
                                WaybillNumber = string.Empty,
                                TrackingNumber = tracking,
                                Replaced = false,
                                ReplacedAt = null
                            });
                            processedNumbers.Add(tracking);
                        }
                    }
                }

                _logger.LogInformation("Retrieved {count} label replace status results", results.Count);
                return results;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error retrieving label replace status");
                return new List<LabelReplaceStatusResult>();
            }
        }

        /// <summary>
        /// 批量取消订单
        /// </summary>
        public async Task<BatchCancelResult> BatchCancelOrdersAsync(string customerCode, string apiKey, List<string> waybillNumbers)
        {
            var result = new BatchCancelResult
            {
                Status = "ok",
                Timestamp = DateTime.UtcNow,
                SuccessCount = 0,
                FailedCount = 0,
                FailedItems = new List<CancelFailedItem>(),
                Message = "Batch cancellation completed"
            };

            try
            {
                // 验证API凭证
                int? customerId = null;
                if (!string.IsNullOrEmpty(customerCode) && !string.IsNullOrEmpty(apiKey))
                {
                    var customerApiInfo = await _customerApiRepository.ValidateAndGetApiCredentialsAsync(customerCode, apiKey);
                    if (customerApiInfo == null)
                    {
                        _logger.LogWarning("Invalid API credentials: CustomerCode={CustomerCode}, ApiKey={ApiKey}", 
                            customerCode, apiKey);
                        result.Status = "error";
                        result.Message = "Invalid API credentials. Please check your customer_code and api_key.";
                        return result;
                    }

                    // 验证CustomerId是否在customers表中存在
                    var customerExists = await _customerRepository.GetByIdAsync(customerApiInfo.CustomerId) != null;
                    if (!customerExists)
                    {
                        _logger.LogError("Customer not found: CustomerId={CustomerId}, CustomerCode={CustomerCode}", 
                            customerApiInfo.CustomerId, customerCode);
                        result.Status = "error";
                        result.Message = "Internal server error: Invalid customer configuration.";
                        return result;
                    }

                    customerId = customerApiInfo.CustomerId;
                    _logger.LogInformation("API credentials validated successfully: CustomerCode={CustomerCode}, CustomerId={CustomerId}", 
                        customerCode, customerId);
                }
                else
                {
                    // 参数为空时的处理（暂时允许）
                    _logger.LogWarning("API credentials not provided or incomplete: CustomerCode={CustomerCode}, ApiKeyProvided={ApiKeyProvided}", 
                        customerCode, !string.IsNullOrEmpty(apiKey));
                }

                _logger.LogInformation("Processing batch cancel request. Waybill count: {count}", waybillNumbers?.Count ?? 0);

                if (waybillNumbers == null || waybillNumbers.Count == 0)
                {
                    result.Message = "No waybill numbers provided";
                    return result;
                }

                foreach (var waybillNumber in waybillNumbers)
                {
                    try
                    {
                        // 检查是否已存在相同的中性面单单号记录
                        var existingRecord = await _labelReplaceRepository.GetByWaybillNumberAsync(waybillNumber);

                        if (existingRecord != null)
                        {
                            // 检查是否存在已返回面单的扫描记录，若存在则禁止修改
                            var scanRecords = await _labelScanService.GetScanRecordsByNeutralWaybillNumberAsync(waybillNumber);
                            if (scanRecords.Any(scan => scan.Result == ScanResult.ReturnedLabel))
                            {
                                result.FailedItems.Add(new CancelFailedItem
                                {
                                    WaybillNumber = waybillNumber,
                                    Reason = "Label has been returned and cannot be modified"
                                });
                                result.FailedCount++;
                                continue;
                            }

                            // 更新状态为取消（N）
                            existingRecord.ReplaceStatus = "N";
                            existingRecord.UpdatedAt = DateTime.UtcNow;

                            await _labelReplaceRepository.UpdateAsync(existingRecord);
                            result.SuccessCount++;
                            _logger.LogInformation("Order cancelled successfully: {waybillNumber}", waybillNumber);
                            
                            // 记录订单日志 - 取消订单
                            await _orderLogService.RecordOrderLogAsync(
                                neutralWaybillNumber: waybillNumber,
                                finalMileTrackingNumber: existingRecord.FinalMileTrackingNumber,
                                operationType: OrderLogOperationType.CANCEL_ORDER,
                                operationResult: OrderLogOperationResult.SUCCESS,
                                operationDescription: $"客户在 {DateTime.Now} 取消订单成功",
                                @operator: customerCode
                            );
                        }
                        else
                        {
                            result.FailedItems.Add(new CancelFailedItem
                            {
                                WaybillNumber = waybillNumber,
                                Reason = "Order not found"
                            });
                            result.FailedCount++;
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, "Error cancelling order: {waybillNumber}", waybillNumber);
                        result.FailedItems.Add(new CancelFailedItem
                        {
                            WaybillNumber = waybillNumber,
                            Reason = "Internal error: " + ex.Message
                        });
                        result.FailedCount++;
                    }
                }

                result.Message = $"Batch cancellation completed. Success: {result.SuccessCount}, Failed: {result.FailedCount}";
                _logger.LogInformation("Batch cancel operation completed. Success: {success}, Failed: {failed}", result.SuccessCount, result.FailedCount);

                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error processing batch cancel request");
                result.Status = "error";
                result.Message = "An error occurred during batch cancellation. Please contact support.";
                return result;
            }
        }

        /// <summary>
        /// 获取数据看板数据
        /// </summary>
        public async Task<List<DashboardDataDto>> GetDashboardDataAsync(string arrivalNumber, string startDate, string endDate, int? customerId)
        {
            try
            {
                _logger.LogInformation("Retrieving dashboard data. ArrivalNumber: {arrivalNumber}", arrivalNumber);

                DateTime? start = null;
                DateTime? end = null;

                if (!string.IsNullOrEmpty(startDate))
                    start = DateTime.Parse(startDate);
                else
                    start = DateTime.Now.AddDays(-30);

                if (!string.IsNullOrEmpty(endDate))
                    end = DateTime.Parse(endDate);

                var allArrivalForms = await _arrivalHandoverFormService.GetArrivalHandoverFormsBatchAsync(
                    page: 1, pageSize: 1000, sortBy: "ReceiptTime", sortOrder: "desc",
                    handoverNumber: arrivalNumber, creator: null, startDate: start, endDate: end);

                var filteredForms = allArrivalForms.Forms;

                if (filteredForms.Count == 0)
                    return new List<DashboardDataDto>();

                var handoverNumbers = filteredForms.Select(f => f.HandoverNumber).ToList();

                var matchedRequests = await _labelReplaceRepository.GetByHandoverNumbersAsync(handoverNumbers, customerId);

                var groupedData = new Dictionary<string, List<LabelReplaceEntity>>();
                foreach (var form in filteredForms)
                {
                    var relatedRequests = matchedRequests
                        .Where(req => (req.BillOfLadingNumber == form.HandoverNumber) || 
                                      (req.MasterPackageNumber == form.HandoverNumber))
                        .ToList();
                    
                    if (relatedRequests.Count > 0)
                    {
                        groupedData[form.HandoverNumber] = relatedRequests;
                    }
                }

                var customerIds = matchedRequests
                    .Where(r => r.CustomerId.HasValue)
                    .Select(r => r.CustomerId.Value)
                    .Distinct()
                    .ToList();

                var customers = customerIds.Count > 0
                    ? await _customerRepository.GetByIdsAsync(customerIds)
                    : new List<CustomerEntity>();

                var customerDict = customers.ToDictionary(c => c.Id);

                var allWaybillNumbers = matchedRequests
                    .Where(r => !string.IsNullOrEmpty(r.NeutralWaybillNumber))
                    .Select(r => r.NeutralWaybillNumber)
                    .Distinct()
                    .ToList();

                var allScans = allWaybillNumbers.Count > 0
                    ? await _labelScanService.GetScanRecordsByNeutralWaybillNumbersAsync(allWaybillNumbers)
                    : new List<LabelScanEntity>();

                var returnedWaybills = allScans
                    .Where(s => s.Result == ScanResult.ReturnedLabel)
                    .Select(s => s.NeutralWaybillNumber)
                    .ToHashSet();

                var dashboardData = new List<DashboardDataDto>();
                foreach (var form in filteredForms)
                {
                    List<LabelReplaceEntity> requests;
                    if (!groupedData.TryGetValue(form.HandoverNumber, out requests))
                        continue;

                    var firstRequest = requests.First();

                    string customerCode = "Unknown";
                    if (firstRequest.CustomerId.HasValue && customerDict.TryGetValue(firstRequest.CustomerId.Value, out var customer))
                    {
                        customerCode = customer.CustomerCode;
                    }

                    int arrivalOrderCount = requests.Count;
                    int noLabelDataCount = requests.Count(req => string.IsNullOrEmpty(req.Label));
                    int labeledOrderCount = requests.Count(req => !string.IsNullOrEmpty(req.Label));

                    string labelRate = arrivalOrderCount > 0
                        ? $"{((double)labeledOrderCount / arrivalOrderCount * 100):F2}%"
                        : "0%";

                    int replaceCompletedCount = requests.Count(req =>
                        !string.IsNullOrEmpty(req.NeutralWaybillNumber) &&
                        returnedWaybills.Contains(req.NeutralWaybillNumber));

                    var dto = new DashboardDataDto
                    {
                        ArrivalNumber = form.HandoverNumber,
                        CustomerCode = customerCode,
                        ArrivalOrderCount = arrivalOrderCount,
                        ReplaceCompletedCount = replaceCompletedCount,
                        ReplacePendingCount = arrivalOrderCount - replaceCompletedCount,
                        NoLabelDataCount = noLabelDataCount,
                        LabeledOrderCount = labeledOrderCount,
                        LabelRate = labelRate,
                        ArrivalTime = form.ReceiptTime,
                        BillOfLadingNumber = firstRequest.BillOfLadingNumber,
                        MasterPackageNumber = firstRequest.MasterPackageNumber
                    };

                    dashboardData.Add(dto);
                }

                _logger.LogInformation("Retrieved {count} dashboard data items", dashboardData.Count);
                return dashboardData;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error retrieving dashboard data");
                return new List<DashboardDataDto>();
            }
        }

        /// <summary>
        /// 将指定中性面单号对应的Label从base64转换为URL格式，保持LabelRetrievedAt不变
        /// </summary>
        /// <param name="neutralWaybillNumber">中性面单号</param>
        /// <returns>转换结果</returns>
        public async Task<ConvertBase64ToUrlResult> ConvertBase64LabelToUrlAsync(string neutralWaybillNumber)
        {
            var result = new ConvertBase64ToUrlResult
            {
                Status = "ok",
                Timestamp = DateTime.UtcNow,
                NeutralWaybillNumber = neutralWaybillNumber,
                Converted = false,
                Message = ""
            };

            try
            {
                if (string.IsNullOrEmpty(neutralWaybillNumber))
                {
                    result.Status = "error";
                    result.Message = "Neutral waybill number is required";
                    return result;
                }

                // 获取现有记录
                var existing = await _labelReplaceRepository.GetByWaybillNumberAsync(neutralWaybillNumber);
                if (existing == null)
                {
                    result.Status = "error";
                    result.Message = "Order not found";
                    return result;
                }

                // 检查Label是否为空
                if (string.IsNullOrEmpty(existing.Label))
                {
                    result.Message = "Label is empty, no need to convert";
                    return result;
                }

                // 检查Label是否已经是URL格式
                if (existing.Label.StartsWith("http://") || existing.Label.StartsWith("https://"))
                {
                    result.Message = "Label is already in URL format";
                    result.Url = existing.Label;
                    return result;
                }

                // 检查是否是base64编码
                bool isBase64 = existing.Label.Length % 4 == 0 &&
                               (existing.Label.StartsWith("data:application/pdf;base64,") ||
                                System.Text.RegularExpressions.Regex.IsMatch(existing.Label, "^[a-zA-Z0-9+/]*={0,3}$"));

                if (!isBase64)
                {
                    result.Status = "error";
                    result.Message = "Label is not in base64 format";
                    return result;
                }

                // 转换base64为PDF文件
                string fileName = $"{neutralWaybillNumber}.pdf";
                await _labelReplaceRepository.ConvertBase64ToPdfAsync(existing.Label, fileName);

                // 构建URL
                string newLabelUrl = $"http://172.232.21.79/api-lable/pdf/20260302/{neutralWaybillNumber}.pdf";

                // 更新Label字段，保持LabelRetrievedAt不变
                bool updateSuccess = await _labelReplaceRepository.UpdateLabelWithoutChangingRetrievedAtAsync(existing.Id, newLabelUrl);

                // 标签更新后失效缓存
                if (updateSuccess)
                {
                    await _labelPdfCacheService.InvalidateCacheAsync(neutralWaybillNumber);
                }

                if (updateSuccess)
                {
                    result.Converted = true;
                    result.Url = newLabelUrl;
                    result.Message = "Successfully converted base64 label to URL";
                    _logger.LogInformation("Successfully converted base64 label to URL for waybill: {number}", neutralWaybillNumber);
                }
                else
                {
                    result.Status = "error";
                    result.Message = "Failed to update label in database";
                }

                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error converting base64 label to URL for waybill: {number}", neutralWaybillNumber);
                result.Status = "error";
                result.Message = "An unexpected error occurred during conversion";
                result.ErrorDetails = ex.Message;
                return result;
            }
        }

        /// <summary>
        /// 获取每日标签统计数据
        /// </summary>
        /// <param name="startDate">开始日期</param>
        /// <param name="endDate">结束日期</param>
        /// <param name="customerId">客户ID</param>
        /// <returns>每日标签统计数据列表</returns>
        public async Task<List<DailyLabelStatsDto>> GetDailyLabelStatsAsync(string startDate, string endDate, int? customerId)
        {
            try
            {
                _logger.LogInformation("Retrieving daily label stats. StartDate: {startDate}, EndDate: {endDate}, CustomerId: {customerId}", 
                    startDate, endDate, customerId);
                
                var stats = await _labelReplaceRepository.GetDailyLabelStatsAsync(startDate, endDate, customerId);
                
                _logger.LogInformation("Retrieved {count} daily label stats items", stats.Count);
                return stats;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error retrieving daily label stats");
                return new List<DailyLabelStatsDto>();
            }
        }

        /// <summary>
        /// 获取每日标签统计数据（中文版本，使用自定义SQL）
        /// </summary>
        /// <returns>每日标签统计数据列表</returns>
        public async Task<List<DailyLabelStatsChineseDto>> GetDailyLabelStatsChineseAsync()
        {
            try
            {
                _logger.LogInformation("Retrieving daily label stats Chinese version");
                
                var stats = await _labelReplaceRepository.GetDailyLabelStatsChineseAsync();
                
                _logger.LogInformation("Retrieved {count} daily label stats Chinese items", stats.Count);
                return stats;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error retrieving daily label stats Chinese");
                return new List<DailyLabelStatsChineseDto>();
            }
        }

        /// <summary>
        /// 获取订单表中有标签的所有订单
        /// </summary>
        /// <param name="limit">限制返回的最大数量</param>
        /// <returns>有标签的订单列表</returns>
        public async Task<List<LabelReplaceEntity>> GetAllOrdersWithLabelsAsync(int limit = 1000)
        {
            try
            {
                _logger.LogInformation("Retrieving all orders with labels, limit: {limit}", limit);
                
                var orders = await _labelReplaceRepository.GetAllOrdersWithLabelsAsync(limit);
                
                _logger.LogInformation("Retrieved {count} orders with labels", orders.Count);
                return orders;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error retrieving orders with labels");
                return new List<LabelReplaceEntity>();
            }
        }

        /// <summary>
        /// 获取指定日期范围内有标签的订单
        /// </summary>
        /// <param name="startDate">开始日期</param>
        /// <param name="endDate">结束日期</param>
        /// <param name="limit">限制返回的最大数量</param>
        /// <returns>有标签的订单列表</returns>
        public async Task<List<LabelReplaceEntity>> GetOrdersWithLabelsByDateRangeAsync(DateTime startDate, DateTime endDate, int limit = 1000)
        {
            try
            {
                _logger.LogInformation("Retrieving orders with labels by date range: {startDate} to {endDate}, limit: {limit}", startDate, endDate, limit);
                
                var orders = await _labelReplaceRepository.GetOrdersWithLabelsByDateRangeAsync(startDate, endDate, limit);
                
                _logger.LogInformation("Retrieved {count} orders with labels in date range", orders.Count);
                return orders;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error retrieving orders with labels by date range");
                return new List<LabelReplaceEntity>();
            }
        }

        /// <summary>
        /// 获取指定客户有标签的订单
        /// </summary>
        /// <param name="customerId">客户ID</param>
        /// <param name="limit">限制返回的最大数量</param>
        /// <returns>有标签的订单列表</returns>
        public async Task<List<LabelReplaceEntity>> GetOrdersWithLabelsByCustomerAsync(int customerId, int limit = 1000)
        {
            try
            {
                _logger.LogInformation("Retrieving orders with labels for customer: {customerId}, limit: {limit}", customerId, limit);
                
                var orders = await _labelReplaceRepository.GetOrdersWithLabelsByCustomerAsync(customerId, limit);
                
                _logger.LogInformation("Retrieved {count} orders with labels for customer", orders.Count);
                return orders;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error retrieving orders with labels for customer");
                return new List<LabelReplaceEntity>();
            }
        }

        public async Task<List<OpsMonitorDto>> GetOpsMonitorDataAsync()
        {
            try
            {
                return await _labelReplaceRepository.GetOpsMonitorDataAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error retrieving ops monitor data");
                return new List<OpsMonitorDto>();
            }
        }
    }
}