using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FreeSql;
using Microsoft.Extensions.Logging;
using NPP.SmartSchedue.Api.Contracts.Core.Enums;
using NPP.SmartSchedue.Api.Contracts.Domain.Work;
using NPP.SmartSchedue.Api.Contracts.Services.Integration.Input;
using NPP.SmartSchedue.Api.Contracts.Services.Integration.Internal;

namespace NPP.SmartSchedue.Api.Services.Integration.Algorithms
{
    /// <summary>
    /// 输入验证引擎 - 专门处理全局分配的第一阶段：输入验证和数据准备
    /// 设计原则：单一职责，专注于输入数据的验证、转换和预处理
    /// 业务价值：将输入验证逻辑从主服务中剥离，提高代码可维护性和可测试性
    /// 性能优化：批量处理、缓存查询结果、减少重复数据库访问
    /// </summary>
    public class InputValidationEngine
    {
        private readonly IBaseRepository<WorkOrderEntity> _workOrderRepository;
        private readonly ILogger<InputValidationEngine> _logger;

        /// <summary>
        /// 构造函数 - 依赖注入模式
        /// </summary>
        /// <param name="workOrderRepository">工作任务仓储，用于加载任务数据</param>
        /// <param name="logger">日志记录器，用于记录验证过程和异常</param>
        public InputValidationEngine(
            IBaseRepository<WorkOrderEntity> workOrderRepository,
            ILogger<InputValidationEngine> logger)
        {
            _workOrderRepository = workOrderRepository ?? throw new ArgumentNullException(nameof(workOrderRepository));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }

        /// <summary>
        /// 执行完整的输入验证和数据准备
        /// 业务流程：空值检查 → 数据源处理 → 业务规则验证 → 数据完整性校验
        /// 性能优化：使用批量查询、预加载关联数据、避免N+1查询问题
        /// 错误处理：详细的错误信息，便于调试和用户理解
        /// </summary>
        /// <param name="input">全局分配输入参数</param>
        /// <returns>验证结果，包含验证状态、错误信息和处理后的任务数据</returns>
        public async Task<GlobalInputValidationResult> ValidateAndPrepareAsync(GlobalAllocationInput input)
        {
            var result = new GlobalInputValidationResult();
            var validationStopwatch = System.Diagnostics.Stopwatch.StartNew();

            try
            {
                _logger.LogInformation("🔍 开始输入验证引擎处理");

                // 第一步：基础参数验证
                var basicValidationResult = ValidateBasicInputParameters(input);
                if (!basicValidationResult.IsValid)
                {
                    _logger.LogWarning("❌ 基础参数验证失败：{ErrorMessage}", basicValidationResult.ErrorMessage);
                    return basicValidationResult;
                }

                // 第二步：处理任务数据源并加载完整数据
                var taskLoadResult = await LoadAndValidateTaskDataAsync(input);
                if (!taskLoadResult.IsValid)
                {
                    _logger.LogWarning("❌ 任务数据加载失败：{ErrorMessage}", taskLoadResult.ErrorMessage);
                    return taskLoadResult;
                }

                // 第三步：执行业务规则验证
                var businessRuleResult = await ValidateBusinessRulesAsync(taskLoadResult.WorkOrders);
                if (!businessRuleResult.IsValid)
                {
                    _logger.LogWarning("❌ 业务规则验证失败：{ErrorMessage}", businessRuleResult.ErrorMessage);
                    return businessRuleResult;
                }

                // 第四步：数据完整性和关联性检查
                var integrityResult = await ValidateDataIntegrityAsync(businessRuleResult.WorkOrders);
                if (!integrityResult.IsValid)
                {
                    _logger.LogWarning("❌ 数据完整性验证失败：{ErrorMessage}", integrityResult.ErrorMessage);
                    return integrityResult;
                }

                validationStopwatch.Stop();

                // 验证成功，返回完整的验证结果
                result.IsValid = true;
                result.WorkOrders = integrityResult.WorkOrders;
                
                _logger.LogInformation("✅ 输入验证引擎处理完成，耗时：{ElapsedMs}ms，有效任务数：{TaskCount}",
                    validationStopwatch.ElapsedMilliseconds, result.WorkOrders.Count);

                return result;
            }
            catch (Exception ex)
            {
                validationStopwatch.Stop();
                _logger.LogError(ex, "💥 输入验证引擎异常，耗时：{ElapsedMs}ms", validationStopwatch.ElapsedMilliseconds);
                
                return new GlobalInputValidationResult
                {
                    IsValid = false,
                    ErrorMessage = $"输入验证系统异常：{ex.Message}",
                    WorkOrders = new List<WorkOrderEntity>()
                };
            }
        }

        /// <summary>
        /// 验证基础输入参数
        /// 业务逻辑：检查空值、数据源完整性、配置参数合理性
        /// 设计原则：快速失败，在最早阶段发现问题并返回明确错误信息
        /// </summary>
        /// <param name="input">输入参数</param>
        /// <returns>基础验证结果</returns>
        private GlobalInputValidationResult ValidateBasicInputParameters(GlobalAllocationInput input)
        {
            var result = new GlobalInputValidationResult();

            // 空值检查
            if (input == null)
            {
                result.IsValid = false;
                result.ErrorMessage = "输入参数不能为空";
                return result;
            }

            // 数据源检查：必须提供任务数据来源
            if ((input.Tasks == null || !input.Tasks.Any()) && 
                (input.TaskIds == null || !input.TaskIds.Any()))
            {
                result.IsValid = false;
                result.ErrorMessage = "必须提供Tasks或TaskIds，不能同时为空";
                return result;
            }

            // 配置参数检查
            if (input.OptimizationConfig == null)
            {
                result.IsValid = false;
                result.ErrorMessage = "优化配置参数不能为空";
                return result;
            }

            // 配置参数合理性检查
            var configValidation = ValidateOptimizationConfig(input.OptimizationConfig);
            if (!configValidation.IsValid)
            {
                return configValidation;
            }

            result.IsValid = true;
            return result;
        }

        /// <summary>
        /// 验证优化配置参数的合理性
        /// 业务逻辑：检查遗传算法参数是否在合理范围内，避免性能问题
        /// </summary>
        /// <param name="config">优化配置</param>
        /// <returns>配置验证结果</returns>
        private GlobalInputValidationResult ValidateOptimizationConfig(GlobalOptimizationConfig config)
        {
            var result = new GlobalInputValidationResult();

            // 种群大小合理性检查
            if (config.PopulationSize < 10 || config.PopulationSize > 500)
            {
                result.IsValid = false;
                result.ErrorMessage = $"种群大小{config.PopulationSize}不合理，应在10-500之间";
                return result;
            }

            // 迭代代数合理性检查
            if (config.MaxGenerations < 5 || config.MaxGenerations > 300)
            {
                result.IsValid = false;
                result.ErrorMessage = $"最大迭代代数{config.MaxGenerations}不合理，应在5-300之间";
                return result;
            }

            // 执行时间限制检查
            if (config.MaxExecutionTimeSeconds < 5 || config.MaxExecutionTimeSeconds > 600)
            {
                result.IsValid = false;
                result.ErrorMessage = $"执行时间限制{config.MaxExecutionTimeSeconds}秒不合理，应在5-600秒之间";
                return result;
            }

            // 权重参数合理性检查
            if (config.FairnessWeight < 0 || config.FairnessWeight > 1 ||
                config.ConstraintWeight < 0 || config.ConstraintWeight > 1 ||
                config.QualificationWeight < 0 || config.QualificationWeight > 1)
            {
                result.IsValid = false;
                result.ErrorMessage = "权重参数必须在0-1之间";
                return result;
            }

            // 权重总和合理性检查（允许一定的浮点误差）
            var totalWeight = config.FairnessWeight + config.ConstraintWeight + config.QualificationWeight;
            if (Math.Abs(totalWeight - 1.0) > 0.1)
            {
                result.IsValid = false;
                result.ErrorMessage = $"权重总和{totalWeight:F2}不合理，应接近1.0";
                return result;
            }

            result.IsValid = true;
            return result;
        }

        /// <summary>
        /// 加载和验证任务数据
        /// 业务逻辑：根据输入类型选择最优的数据加载策略，批量处理提高性能
        /// 性能优化：预加载关联的工序信息，避免后续查询中的N+1问题
        /// </summary>
        /// <param name="input">输入参数</param>
        /// <returns>任务数据加载结果</returns>
        private async Task<GlobalInputValidationResult> LoadAndValidateTaskDataAsync(GlobalAllocationInput input)
        {
            var result = new GlobalInputValidationResult();
            
            try
            {
                List<WorkOrderEntity> workOrders;

                // 策略选择：优先使用已加载的任务实体，减少数据库查询
                if (input.Tasks != null && input.Tasks.Any())
                {
                    _logger.LogDebug("📋 使用预加载的任务实体，数量：{TaskCount}", input.Tasks.Count);
                    workOrders = input.Tasks;

                    // 验证预加载的任务数据是否包含必要的关联信息
                    await ValidateAndEnrichPreloadedTasksAsync(workOrders);
                }
                else if (input.TaskIds != null && input.TaskIds.Any())
                {
                    _logger.LogDebug("🔍 根据TaskIds批量加载任务数据，ID数量：{IdCount}", input.TaskIds.Count);
                    
                    // 批量查询：一次性加载所有需要的任务及其关联数据
                    workOrders = await _workOrderRepository.Select
                        .Where(w => input.TaskIds.Contains(w.Id))
                        .Include(w => w.ProcessEntity) // 预加载工序信息，用于资质匹配
                        .ToListAsync();

                    // 检查是否所有请求的任务都存在
                    if (workOrders.Count != input.TaskIds.Count)
                    {
                        var existingIds = workOrders.Select(w => w.Id).ToHashSet();
                        var missingIds = input.TaskIds.Where(id => !existingIds.Contains(id)).ToList();
                        
                        result.IsValid = false;
                        result.ErrorMessage = $"以下任务ID不存在：{string.Join(", ", missingIds)}";
                        return result;
                    }
                }
                else
                {
                    // 这种情况在基础验证阶段应该已经被捕获
                    result.IsValid = false;
                    result.ErrorMessage = "内部错误：无有效的任务数据源";
                    return result;
                }

                result.IsValid = true;
                result.WorkOrders = workOrders;
                
                _logger.LogDebug("✅ 任务数据加载完成，有效任务数：{TaskCount}", workOrders.Count);
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "💥 加载任务数据异常");
                result.IsValid = false;
                result.ErrorMessage = $"加载任务数据失败：{ex.Message}";
                return result;
            }
        }

        /// <summary>
        /// 验证并丰富预加载的任务数据
        /// 业务逻辑：确保预加载的任务包含完整的关联信息，必要时进行补充查询
        /// </summary>
        /// <param name="workOrders">预加载的任务列表</param>
        private async Task ValidateAndEnrichPreloadedTasksAsync(List<WorkOrderEntity> workOrders)
        {
            try
            {
                // 检查哪些任务缺少工序信息
                var tasksWithoutProcess = workOrders.Where(w => w.ProcessEntity == null).ToList();
                
                if (tasksWithoutProcess.Any())
                {
                    _logger.LogDebug("🔧 补充加载工序信息，任务数：{TaskCount}", tasksWithoutProcess.Count);
                    
                    // 批量补充工序信息
                    var taskIds = tasksWithoutProcess.Select(t => t.Id).ToList();
                    var tasksWithProcess = await _workOrderRepository.Select
                        .Where(w => taskIds.Contains(w.Id))
                        .Include(w => w.ProcessEntity)
                        .ToListAsync();
                    
                    // 更新原任务列表中的工序信息
                    var processMap = tasksWithProcess.ToDictionary(t => t.Id, t => t.ProcessEntity);
                    foreach (var task in tasksWithoutProcess)
                    {
                        if (processMap.TryGetValue(task.Id, out var processEntity))
                        {
                            task.ProcessEntity = processEntity;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "⚠️ 补充工序信息时发生异常，将继续处理");
            }
        }

        /// <summary>
        /// 验证业务规则
        /// 业务逻辑：检查任务状态、工序完整性、调度可行性等业务层面的约束
        /// 设计目的：在算法执行前发现明显的业务问题，避免无效计算
        /// </summary>
        /// <param name="workOrders">待验证的任务列表</param>
        /// <returns>业务规则验证结果</returns>
        private async Task<GlobalInputValidationResult> ValidateBusinessRulesAsync(List<WorkOrderEntity> workOrders)
        {
            var result = new GlobalInputValidationResult();
            var validationErrors = new List<string>();

            try
            {
                // 验证任务状态合法性
                await ValidateTaskStatusesAsync(workOrders, validationErrors);
                
                // 验证工序完整性
                await ValidateProcessIntegrityAsync(workOrders, validationErrors);
                
                // 验证时间合理性
                await ValidateTimeConstraintsAsync(workOrders, validationErrors);
                
                // 验证数据一致性
                await ValidateDataConsistencyAsync(workOrders, validationErrors);

                if (validationErrors.Any())
                {
                    result.IsValid = false;
                    result.ErrorMessage = string.Join("; ", validationErrors);
                    return result;
                }

                result.IsValid = true;
                result.WorkOrders = workOrders;
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "💥 业务规则验证异常");
                result.IsValid = false;
                result.ErrorMessage = $"业务规则验证失败：{ex.Message}";
                return result;
            }
        }

        /// <summary>
        /// 验证任务状态的合法性
        /// 业务规则：只有待分配或可重新分配的任务才能参与全局优化
        /// </summary>
        /// <param name="workOrders">任务列表</param>
        /// <param name="validationErrors">验证错误列表</param>
        private async Task ValidateTaskStatusesAsync(List<WorkOrderEntity> workOrders, List<string> validationErrors)
        {
            var invalidStatusTasks = workOrders
                .Where(w => w.Status != (int)WorkOrderStatusEnum.PendingIntegration)
                .ToList();

            if (invalidStatusTasks.Any())
            {
                var invalidIds = string.Join(", ", invalidStatusTasks.Select(t => t.Id));
                validationErrors.Add($"以下任务状态不允许参与分配：{invalidIds}");
            }

            // 添加异步占位符，后续可扩展更复杂的状态检查逻辑
            await Task.CompletedTask;
        }

        /// <summary>
        /// 验证工序完整性
        /// 业务规则：每个任务必须有有效的工序信息，工序必须处于可用状态
        /// </summary>
        /// <param name="workOrders">任务列表</param>
        /// <param name="validationErrors">验证错误列表</param>
        private async Task ValidateProcessIntegrityAsync(List<WorkOrderEntity> workOrders, List<string> validationErrors)
        {
            var tasksWithoutProcess = workOrders
                .Where(w => w.ProcessEntity == null || w.ProcessId <= 0)
                .ToList();

            if (tasksWithoutProcess.Any())
            {
                var taskIds = string.Join(", ", tasksWithoutProcess.Select(t => t.Id));
                validationErrors.Add($"以下任务缺少工序信息：{taskIds}");
            }

            var tasksWithInactiveProcess = workOrders
                .Where(w => w.ProcessEntity != null && !w.ProcessEntity.IsEnabled && !w.ProcessEntity.IsEnabled)
                .ToList();

            if (tasksWithInactiveProcess.Any())
            {
                var taskIds = string.Join(", ", tasksWithInactiveProcess.Select(t => t.Id));
                validationErrors.Add($"以下任务的工序已禁用：{taskIds}");
            }

            // 添加异步占位符，后续可扩展工序状态的数据库验证
            await Task.CompletedTask;
        }

        /// <summary>
        /// 验证时间约束合理性
        /// 业务规则：工作日期必须是未来时间，班次必须有效
        /// </summary>
        /// <param name="workOrders">任务列表</param>
        /// <param name="validationErrors">验证错误列表</param>
        private async Task ValidateTimeConstraintsAsync(List<WorkOrderEntity> workOrders, List<string> validationErrors)
        {
            var now = DateTime.Now.Date;
            
            var pastTasks = workOrders
                .Where(w => w.WorkOrderDate.Date < now)
                .ToList();

            if (pastTasks.Any())
            {
                var taskIds = string.Join(", ", pastTasks.Select(t => $"{t.Id}({t.WorkOrderDate:yyyy-MM-dd})"));
                validationErrors.Add($"以下任务的工作日期已过期：{taskIds}");
            }

            var invalidShiftTasks = workOrders
                .Where(w => w.ShiftId == null || w.ShiftId <= 0)
                .ToList();

            if (invalidShiftTasks.Any())
            {
                var taskIds = string.Join(", ", invalidShiftTasks.Select(t => t.Id));
                validationErrors.Add($"以下任务缺少有效的班次信息：{taskIds}");
            }

            // 添加异步占位符，后续可扩展班次有效性的数据库验证
            await Task.CompletedTask;
        }

        /// <summary>
        /// 验证数据一致性
        /// 业务规则：任务数据的各字段之间必须保持逻辑一致性
        /// </summary>
        /// <param name="workOrders">任务列表</param>
        /// <param name="validationErrors">验证错误列表</param>
        private async Task ValidateDataConsistencyAsync(List<WorkOrderEntity> workOrders, List<string> validationErrors)
        {
            // 验证项目编号和工序的关联性
            var inconsistentTasks = workOrders
                .Where(w => string.IsNullOrEmpty(w.ProjectNumber) || 
                           string.IsNullOrEmpty(w.ProcessEntity?.ProcessCode))
                .ToList();

            if (inconsistentTasks.Any())
            {
                var taskIds = string.Join(", ", inconsistentTasks.Select(t => t.Id));
                validationErrors.Add($"以下任务的项目编号或工序编号缺失：{taskIds}");
            }
            
            await Task.CompletedTask;
        }

        /// <summary>
        /// 验证数据完整性和关联性
        /// 业务逻辑：确保所有必需的关联数据都已正确加载，为后续算法执行做好准备
        /// 最终检查：这是验证流程的最后一步，确保返回的数据完全可用
        /// </summary>
        /// <param name="workOrders">已通过业务规则验证的任务列表</param>
        /// <returns>完整性验证结果</returns>
        private async Task<GlobalInputValidationResult> ValidateDataIntegrityAsync(List<WorkOrderEntity> workOrders)
        {
            var result = new GlobalInputValidationResult();
            
            try
            {
                // 最终数据完整性检查
                var incompleteDataTasks = workOrders
                    .Where(w => w.ProcessEntity == null || 
                               w.ShiftId == null || 
                               string.IsNullOrEmpty(w.ProjectNumber))
                    .ToList();

                if (incompleteDataTasks.Any())
                {
                    var taskIds = string.Join(", ", incompleteDataTasks.Select(t => t.Id));
                    result.IsValid = false;
                    result.ErrorMessage = $"以下任务数据不完整，无法进行分配：{taskIds}";
                    return result;
                }

                // 验证通过，返回清理后的任务列表
                result.IsValid = true;
                result.WorkOrders = workOrders.OrderBy(w => w.Priority).ThenBy(w => w.WorkOrderDate).ToList();
                
                _logger.LogDebug("✅ 数据完整性验证通过，最终任务数：{TaskCount}", result.WorkOrders.Count);
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "💥 数据完整性验证异常");
                result.IsValid = false;
                result.ErrorMessage = $"数据完整性验证失败：{ex.Message}";
                return result;
            }

            // 异步占位符已经在上面的方法调用中处理
        }

        /// <summary>
        /// 创建快速验证结果 - 用于简单场景的快速验证
        /// 业务场景：测试环境或简单的单任务验证场景
        /// 性能优化：跳过复杂的业务规则检查，仅执行基础验证
        /// </summary>
        /// <param name="input">输入参数</param>
        /// <returns>快速验证结果</returns>
        public async Task<GlobalInputValidationResult> QuickValidateAsync(GlobalAllocationInput input)
        {
            try
            {
                _logger.LogDebug("⚡ 执行快速验证模式");

                // 基础验证
                var basicResult = ValidateBasicInputParameters(input);
                if (!basicResult.IsValid)
                {
                    return basicResult;
                }

                // 简化的任务数据加载（跳过复杂的业务规则验证）
                var taskResult = await LoadAndValidateTaskDataAsync(input);
                if (!taskResult.IsValid)
                {
                    return taskResult;
                }

                _logger.LogDebug("✅ 快速验证完成，任务数：{TaskCount}", taskResult.WorkOrders.Count);
                return taskResult;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "💥 快速验证异常");
                return new GlobalInputValidationResult
                {
                    IsValid = false,
                    ErrorMessage = $"快速验证失败：{ex.Message}"
                };
            }
        }

        /// <summary>
        /// 验证输入参数 - 简化版本的输入验证接口
        /// </summary>
        /// <param name="input">全局分配输入参数</param>
        /// <returns>验证结果</returns>
        public async Task<GlobalInputValidationResult> ValidateInputAsync(GlobalAllocationInput input)
        {
            return await ValidateAndPrepareAsync(input);
        }
    }
}