using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using ZhonTai.Admin.Core.Dto;
using ZhonTai.Admin.Services;
using NPP.SmartSchedue.Api.Contracts.Services.Integration;
using NPP.SmartSchedue.Api.Contracts.Services.Integration.Input;
using NPP.SmartSchedue.Api.Contracts.Services.Integration.Output;
using NPP.SmartSchedue.Api.Contracts.Services.Work;
using NPP.SmartSchedue.Api.Contracts.Services.Personnel;
using NPP.SmartSchedue.Api.Contracts.Core.Enums;
using NPP.SmartSchedue.Api.Contracts.Domain.Work;
using NPP.SmartSchedue.Api.Contracts.Domain.Time;
using NPP.SmartSchedue.Api.Contracts.Domain.Personnel;
using NPP.SmartSchedue.Api.Contracts.Domain.Equipment;
using NPP.SmartSchedue.Api.Repositories.Work;
using NPP.SmartSchedue.Api.Contracts;
using ZhonTai.DynamicApi;
using ZhonTai.DynamicApi.Attributes;

namespace NPP.SmartSchedue.Api.Services.Integration
{
    /// <summary>
    /// 任务整合前自检服务
    /// </summary>
    [DynamicApi(Area = "app")]
    public class TaskIntegrationPreCheckService : BaseService, ITaskIntegrationPreCheckService, IDynamicApi
    {
        private readonly WorkOrderRepository _workOrderRepository;
        private readonly IPersonService _personService;
        private readonly IWorkOrderService _workOrderService;
        private readonly IEquipmentRepository _equipmentRepository;
        private readonly IEquipmentMaintenanceRepository _equipmentMaintenanceRepository;
        private readonly IEquipmentCalibrationRepository _equipmentCalibrationRepository;
        private readonly IQualificationRepository _qualificationRepository;

        public TaskIntegrationPreCheckService(
            WorkOrderRepository workOrderRepository,
            IPersonService personService,
            IWorkOrderService workOrderService,
            IEquipmentRepository equipmentRepository,
            IEquipmentMaintenanceRepository equipmentMaintenanceRepository,
            IEquipmentCalibrationRepository equipmentCalibrationRepository,
            IQualificationRepository qualificationRepository)
        {
            _workOrderRepository = workOrderRepository ?? throw new ArgumentNullException(nameof(workOrderRepository));
            _personService = personService ?? throw new ArgumentNullException(nameof(personService));
            _workOrderService = workOrderService ?? throw new ArgumentNullException(nameof(workOrderService));
            _equipmentRepository = equipmentRepository ?? throw new ArgumentNullException(nameof(equipmentRepository));
            _equipmentMaintenanceRepository = equipmentMaintenanceRepository ?? throw new ArgumentNullException(nameof(equipmentMaintenanceRepository));
            _equipmentCalibrationRepository = equipmentCalibrationRepository ?? throw new ArgumentNullException(nameof(equipmentCalibrationRepository));
            _qualificationRepository = qualificationRepository ?? throw new ArgumentNullException(nameof(qualificationRepository));
        }

        /// <summary>
        /// 加载待整合的任务列表，支持多项目号筛选，按项目号分组展示
        /// </summary>
        [HttpPost]
        public async Task<TaskIntegrationListOutput> LoadPendingIntegrationTasksAsync(LoadPendingTasksInput input)
        {
            try
            {
                // 业务参数验证
                if (input == null)
                    throw new ArgumentNullException(nameof(input), "加载任务输入参数不能为空");
                
                // 日期范围合理性验证
                if (input.StartDate.HasValue && input.EndDate.HasValue && input.StartDate > input.EndDate)
                    throw new ArgumentException("开始日期不能晚于结束日期", nameof(input.StartDate));

                // 时间范围过大保护（防止性能问题）
                if (input.StartDate.HasValue && input.EndDate.HasValue)
                {
                    var timeSpan = input.EndDate.Value - input.StartDate.Value;
                    if (timeSpan.TotalDays > 365)
                        throw new ArgumentException("查询时间范围不能超过365天", nameof(input.StartDate));
                }

                // 构建查询条件
                var query = _workOrderRepository.Select
                    .Where(wo => wo.Status == (int)input.Status);

                // 项目号筛选
                if (input.ProjectNumbers?.Any() == true)
                {
                    query = query.Where(wo => input.ProjectNumbers.Contains(wo.ProjectNumber));
                }

                // 日期范围筛选
                if (input.StartDate.HasValue)
                {
                    query = query.Where(wo => wo.WorkOrderDate >= input.StartDate.Value);
                }
                if (input.EndDate.HasValue)
                {
                    query = query.Where(wo => wo.WorkOrderDate <= input.EndDate.Value);
                }

                // 工序筛选
                if (input.ProcessCodes?.Any() == true)
                {
                    query = query.Where(wo => input.ProcessCodes.Contains(wo.ProcessCode));
                }

                // 班次筛选
                if (input.ShiftIds?.Any() == true)
                {
                    query = query.Where(wo => wo.ShiftId.HasValue && input.ShiftIds.Contains(wo.ShiftId.Value));
                }

                // 执行查询获取任务列表
                var workOrders = await query
                    .OrderBy(wo => wo.ProjectNumber)
                    .OrderBy(wo => wo.WorkOrderDate)
                    .OrderBy(wo => wo.Priority)
                    .ToListAsync();

                // 数据完整性检查
                if (workOrders.Any(wo => string.IsNullOrEmpty(wo.ProjectNumber)))
                {
                    throw new InvalidOperationException("发现项目号为空的任务，数据不完整，无法进行分组");
                }

                // 按项目号分组
                var projectGroups = workOrders
                    .GroupBy(wo => wo.ProjectNumber)
                    .Select(g => new ProjectTaskGroup
                    {
                        ProjectNumber = g.Key,
                        ProjectName = g.Key, // 可以扩展从项目管理模块获取项目名称
                        ProjectCategory = g.First().ProjectCategory ?? "未分类",
                        TaskCount = g.Count(),
                        EstimatedTotalHours = g.Sum(wo => wo.EstimatedHours ?? 0),
                        EarliestStartDate = g.Min(wo => wo.WorkOrderDate),
                        LatestEndDate = g.Max(wo => wo.WorkOrderDate),
                        Tasks = g.Select(wo => new WorkOrderSummary
                        {
                            Id = wo.Id,
                            WorkOrderCode = wo.WorkOrderCode ?? $"WO_{wo.Id}",
                            WorkOrderDate = wo.WorkOrderDate,
                            ShiftId = wo.ShiftId ?? 0,
                            ShiftName = wo.ShiftName ?? "未知班次",
                            ShiftCode = wo.ShiftCode ?? "UNKNOWN",
                            ProcessId = wo.ProcessId,
                            ProcessName = wo.ProcessName ?? "未知工序",
                            ProcessCode = wo.ProcessCode ?? "UNKNOWN",
                            EstimatedHours = Math.Max(0, wo.EstimatedHours ?? 0), // 确保工时不为负数
                            Status = wo.Status,
                            Priority = Math.Max(0, wo.Priority), // 确保优先级不为负数
                            UrgencyLevel = Math.Max(0, wo.Urgency), // 确保紧急度不为负数
                            ComplexityLevel = Math.Max(0, wo.Complexity), // 确保复杂度不为负数
                            HasAssignedPersonnel = wo.AssignedPersonnelId.HasValue,
                            HasAssignedEquipment = wo.AssignedEquipmentId.HasValue
                        }).ToList()
                    })
                    .OrderBy(pg => pg.ProjectNumber) // 确保项目分组有序
                    .ToList();

                return new TaskIntegrationListOutput
                {
                    ProjectTaskGroups = projectGroups,
                    TotalTaskCount = workOrders.Count,
                    TotalProjectCount = projectGroups.Count
                };
            }
            catch (Exception ex)
            {
                throw new Exception($"加载待整合任务列表失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 对勾选的项目和任务进行整合前自检
        /// </summary>
        [HttpPost]
        public async Task<TaskIntegrationPreCheckResult> ExecutePreCheckAsync(TaskIntegrationPreCheckInput input)
        {
            try
            {
                // 输入参数完整性验证
                if (input == null)
                    throw new ArgumentNullException(nameof(input), "自检输入参数不能为空");

                // 检查是否有选择项目或任务
                if ((input.SelectedProjectNumbers?.Any() != true) && (input.SelectedTaskIds?.Any() != true))
                    throw new ArgumentException("必须至少选择一个项目或任务进行自检", nameof(input));

                // 检查时间范围合理性
                if (input.CheckStartDate > input.CheckEndDate)
                    throw new ArgumentException("检查开始时间不能晚于结束时间", nameof(input.CheckStartDate));

                // 时间范围过大保护
                var timeSpan = input.CheckEndDate - input.CheckStartDate;
                if (timeSpan.TotalDays > 90)
                    throw new ArgumentException("检查时间范围不能超过90天", nameof(input.CheckStartDate));

                var result = new TaskIntegrationPreCheckResult
                {
                    CheckedProjectCount = input.SelectedProjectNumbers?.Count ?? 0,
                    CheckedTaskCount = input.SelectedTaskIds?.Count ?? 0,
                    CheckTime = DateTime.Now
                };

                var projectResourceResults = new List<ProjectResourceSufficiencyResult>();

                // 如果选择了项目号，按项目进行检查
                if (input.SelectedProjectNumbers?.Any() == true)
                {
                    foreach (var projectNumber in input.SelectedProjectNumbers)
                    {
                        var projectResult = await CheckProjectResourceSufficiencyAsync(
                            projectNumber, 
                            input.CheckStartDate, 
                            input.CheckEndDate,
                            input.CheckPersonnelSufficiency,
                            input.CheckEquipmentSufficiency);
                        
                        projectResourceResults.Add(projectResult);
                    }
                }

                // 如果选择了具体任务，按任务所属项目进行检查
                if (input.SelectedTaskIds?.Any() == true)
                {
                    var selectedTasks = await _workOrderRepository.Select
                        .Where(wo => input.SelectedTaskIds.Contains(wo.Id))
                        .ToListAsync();

                    var taskProjectGroups = selectedTasks.GroupBy(t => t.ProjectNumber);
                    
                    foreach (var group in taskProjectGroups)
                    {
                        if (!projectResourceResults.Any(pr => pr.ProjectNumber == group.Key))
                        {
                            var projectResult = await CheckProjectResourceSufficiencyAsync(
                                group.Key,
                                input.CheckStartDate,
                                input.CheckEndDate,
                                input.CheckPersonnelSufficiency,
                                input.CheckEquipmentSufficiency);
                            
                            projectResourceResults.Add(projectResult);
                        }
                    }
                }

                result.ProjectResourceResults = projectResourceResults;

                // 判断整体检查是否通过
                result.IsCheckPassed = projectResourceResults.All(pr => 
                    pr.IsPersonnelSufficient && pr.IsEquipmentSufficient);

                // 生成检查摘要
                var passedProjects = projectResourceResults.Count(pr => pr.IsPersonnelSufficient && pr.IsEquipmentSufficient);
                var totalProjects = projectResourceResults.Count;
                
                result.CheckSummary = $"检查完成。项目总数: {totalProjects}，通过: {passedProjects}，未通过: {totalProjects - passedProjects}";

                // 收集警告和错误信息
                foreach (var projectResult in projectResourceResults)
                {
                    if (!projectResult.IsPersonnelSufficient)
                    {
                        result.Warnings.Add($"项目 {projectResult.ProjectNumber} 人员资源不足");
                    }
                    if (!projectResult.IsEquipmentSufficient)
                    {
                        result.Warnings.Add($"项目 {projectResult.ProjectNumber} 设备资源不足");
                    }
                }

                return result;
            }
            catch (Exception ex)
            {
                return new TaskIntegrationPreCheckResult
                {
                    IsCheckPassed = false,
                    CheckTime = DateTime.Now,
                    Errors = new List<string> { $"自检执行失败: {ex.Message}" }
                };
            }
        }

        /// <summary>
        /// 获取项目任务数量与可用人员数量对比（按日和周）
        /// </summary>
        [HttpPost]
        public async Task<ProjectResourceComparisonResult> GetProjectResourceComparisonAsync(ProjectResourceComparisonInput input)
        {
            try
            {
                // 输入参数验证
                if (input == null)
                    throw new ArgumentNullException(nameof(input), "项目资源对比输入参数不能为空");

                if (input.ProjectNumbers?.Any() != true)
                    throw new ArgumentException("必须至少指定一个项目号进行资源对比", nameof(input.ProjectNumbers));

                if (input.StartDate > input.EndDate)
                    throw new ArgumentException("开始日期不能晚于结束日期", nameof(input.StartDate));

                // 项目数量限制保护
                if (input.ProjectNumbers.Count > 50)
                    throw new ArgumentException("单次对比的项目数量不能超过50个", nameof(input.ProjectNumbers));

                var result = new ProjectResourceComparisonResult
                {
                    ComparisonDimension = input.Dimension.ToString(),
                    StartDate = input.StartDate,
                    EndDate = input.EndDate
                };

                var projectComparisons = new List<ProjectResourceComparison>();

                foreach (var projectNumber in input.ProjectNumbers)
                {
                    var comparison = await AnalyzeProjectResourceComparisonAsync(
                        projectNumber, 
                        input.StartDate, 
                        input.EndDate,
                        input.Dimension == ComparisonDimension.Daily,
                        input.Dimension == ComparisonDimension.Weekly);
                    
                    projectComparisons.Add(comparison);
                }

                result.ProjectComparisons = projectComparisons;

                // 计算总体资源充足性
                result.OverallSufficiency = projectComparisons.All(pc => pc.ResourceStatus == "充足");

                // 计算资源紧张度评分
                var totalTensionScore = projectComparisons.Sum(pc => CalculateResourceTensionScore(pc));
                result.ResourceTensionScore = projectComparisons.Any() ? 
                    (int)(totalTensionScore / projectComparisons.Count) : 0;

                return result;
            }
            catch (Exception ex)
            {
                throw new Exception($"获取项目资源对比失败: {ex.Message}", ex);
            }
        }

        #region 私有方法

        /// <summary>
        /// 检查项目资源充足性
        /// </summary>
        private async Task<ProjectResourceSufficiencyResult> CheckProjectResourceSufficiencyAsync(
            string projectNumber, 
            DateTime startDate, 
            DateTime endDate,
            bool checkPersonnel,
            bool checkEquipment)
        {
            // 参数验证
            if (string.IsNullOrWhiteSpace(projectNumber))
                throw new ArgumentException("项目号不能为空", nameof(projectNumber));

            if (startDate > endDate)
                throw new ArgumentException("开始日期不能晚于结束日期", nameof(startDate));

            var result = new ProjectResourceSufficiencyResult
            {
                ProjectNumber = projectNumber,
                ProjectName = projectNumber, // 可以从项目管理模块获取项目名称
                IsPersonnelSufficient = true,
                IsEquipmentSufficient = true,
                ResourceAnalysis = new ProjectResourceAnalysis()
            };

            try
            {
                // 获取项目在指定时间范围内的任务
                var projectTasks = await _workOrderRepository.Select
                    .Where(wo => wo.ProjectNumber == projectNumber)
                    .Where(wo => wo.WorkOrderDate >= startDate && wo.WorkOrderDate <= endDate)
                    .Where(wo => wo.Status == (int)WorkOrderStatusEnum.PendingIntegration)
                    .ToListAsync();

                if (!projectTasks.Any())
                {
                    return result;
                }

                // 按日分析资源需求
                var dailyDemands = await AnalyzeDailyResourceDemandAsync(projectTasks, checkPersonnel, checkEquipment);
                result.ResourceAnalysis.DailyDemands = dailyDemands;

                // 按周分析资源需求
                var weeklyDemands = await AnalyzeWeeklyResourceDemandAsync(projectTasks, checkPersonnel, checkEquipment);
                result.ResourceAnalysis.WeeklyDemands = weeklyDemands;

                // 判断人员资源充足性
                if (checkPersonnel)
                {
                    result.IsPersonnelSufficient = dailyDemands.All(d => d.IsSufficient) && 
                                                  weeklyDemands.All(w => w.IsSufficient);
                }

                // 判断设备资源充足性
                if (checkEquipment)
                {
                    result.IsEquipmentSufficient = dailyDemands.All(d => d.AvailableEquipmentCount >= d.RequiredEquipmentCount) && 
                                                  weeklyDemands.All(w => w.AvailableEquipmentCount >= w.RequiredEquipmentCount);
                }

                return result;
            }
            catch (Exception ex)
            {
                result.IsPersonnelSufficient = false;
                result.IsEquipmentSufficient = false;
                throw new Exception($"检查项目 {projectNumber} 资源充足性失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 分析日资源需求
        /// </summary>
        private async Task<List<DailyResourceDemand>> AnalyzeDailyResourceDemandAsync(
            List<WorkOrderEntity> projectTasks, 
            bool checkPersonnel, 
            bool checkEquipment)
        {
            var dailyDemands = new List<DailyResourceDemand>();

            var taskGroups = projectTasks.GroupBy(t => t.WorkOrderDate.Date);

            foreach (var group in taskGroups)
            {
                var date = group.Key;
                var tasksOnDate = group.ToList();

                var demand = new DailyResourceDemand
                {
                    Date = date,
                    RequiredPersonnelCount = CalculateRequiredPersonnelCountForDay(tasksOnDate),
                    RequiredEquipmentCount = CalculateRequiredEquipmentCountForDay(tasksOnDate),
                    EstimatedWorkHours = tasksOnDate.Sum(t => t.EstimatedHours ?? 0)
                };

                if (checkPersonnel)
                {
                    // 获取该日期可用人员数量（这里需要调用人员服务）
                    demand.AvailablePersonnelCount = await GetAvailablePersonnelCountAsync(date);
                }

                if (checkEquipment)
                {
                    // 获取该日期可用设备数量（这里需要调用设备服务）
                    demand.AvailableEquipmentCount = await GetAvailableEquipmentCountAsync(date);
                }

                dailyDemands.Add(demand);
            }

            return dailyDemands;
        }

        /// <summary>
        /// 分析周资源需求
        /// </summary>
        private async Task<List<WeeklyResourceDemand>> AnalyzeWeeklyResourceDemandAsync(
            List<WorkOrderEntity> projectTasks,
            bool checkPersonnel,
            bool checkEquipment)
        {
            var weeklyDemands = new List<WeeklyResourceDemand>();

            // 按周分组任务
            var weekGroups = projectTasks
                .GroupBy(t => GetWeekStartDate(t.WorkOrderDate.Date))
                .OrderBy(g => g.Key);

            foreach (var group in weekGroups)
            {
                var weekStart = group.Key;
                var weekEnd = weekStart.AddDays(6);
                var tasksInWeek = group.ToList();

                var demand = new WeeklyResourceDemand
                {
                    WeekStartDate = weekStart,
                    WeekEndDate = weekEnd,
                    RequiredPersonnelCount = CalculateRequiredPersonnelCount(tasksInWeek),
                    RequiredEquipmentCount = CalculateRequiredEquipmentCount(tasksInWeek),
                    EstimatedWorkHours = tasksInWeek.Sum(t => t.EstimatedHours ?? 0)
                };

                if (checkPersonnel)
                {
                    demand.AvailablePersonnelCount = await GetAvailablePersonnelCountForWeekAsync(weekStart, weekEnd);
                }

                if (checkEquipment)
                {
                    demand.AvailableEquipmentCount = await GetAvailableEquipmentCountForWeekAsync(weekStart, weekEnd);
                }

                weeklyDemands.Add(demand);
            }

            return weeklyDemands;
        }

        /// <summary>
        /// 分析项目资源对比
        /// </summary>
        private async Task<ProjectResourceComparison> AnalyzeProjectResourceComparisonAsync(
            string projectNumber,
            DateTime startDate,
            DateTime endDate,
            bool compareByDay,
            bool compareByWeek)
        {
            var projectTasks = await _workOrderRepository.Select
                .Where(wo => wo.ProjectNumber == projectNumber)
                .Where(wo => wo.WorkOrderDate >= startDate && wo.WorkOrderDate <= endDate)
                .Where(wo => wo.Status == (int)WorkOrderStatusEnum.PendingIntegration)
                .ToListAsync();

            var comparison = new ProjectResourceComparison
            {
                ProjectNumber = projectNumber,
                ProjectName = projectNumber,
                TotalTaskCount = projectTasks.Count,
                TotalEstimatedHours = projectTasks.Sum(t => t.EstimatedHours ?? 0)
            };

            if (projectTasks.Any())
            {
                // 计算人员需求峰值
                if (compareByDay)
                {
                    var dailyTaskCounts = projectTasks
                        .GroupBy(t => t.WorkOrderDate.Date)
                        .Select(g => g.Count());
                    comparison.PeakPersonnelDemand = dailyTaskCounts.Max();
                }

                // 获取可用人员和设备容量
                comparison.AvailablePersonnelCapacity = await GetAvailablePersonnelCapacityAsync(startDate, endDate);
                comparison.AvailableEquipmentCapacity = await GetAvailableEquipmentCapacityAsync(startDate, endDate);

                // 判断资源状态
                var personnelRatio = comparison.AvailablePersonnelCapacity > 0 ? 
                    (double)comparison.PeakPersonnelDemand / comparison.AvailablePersonnelCapacity : 1.0;

                if (personnelRatio <= 0.7)
                    comparison.ResourceStatus = "充足";
                else if (personnelRatio <= 0.9)
                    comparison.ResourceStatus = "紧张";
                else
                    comparison.ResourceStatus = "不足";

                // 生成建议
                comparison.Recommendations = GenerateResourceRecommendations(comparison);
            }

            return comparison;
        }

        /// <summary>
        /// 生成资源建议
        /// </summary>
        private List<string> GenerateResourceRecommendations(ProjectResourceComparison comparison)
        {
            var recommendations = new List<string>();

            if (comparison.ResourceStatus == "不足")
            {
                recommendations.Add("建议增加人员配置或调整任务优先级");
                recommendations.Add("考虑延长项目周期以平衡资源负载");
            }
            else if (comparison.ResourceStatus == "紧张")
            {
                recommendations.Add("建议优化任务分配，避免资源冲突");
                recommendations.Add("密切关注人员工作负荷，防止过度疲劳");
            }
            else
            {
                recommendations.Add("资源配置良好，可以按计划执行");
            }

            return recommendations;
        }

        /// <summary>
        /// 计算资源紧张度评分
        /// </summary>
        private int CalculateResourceTensionScore(ProjectResourceComparison comparison)
        {
            if (comparison.AvailablePersonnelCapacity == 0) return 100;

            var ratio = (double)comparison.PeakPersonnelDemand / comparison.AvailablePersonnelCapacity;
            return Math.Min(100, (int)(ratio * 100));
        }

        /// <summary>
        /// 获取指定日期可用人员数量
        /// 综合考虑班次安排、人员资质、请假状态、工作量限制等因素
        /// </summary>
        private async Task<int> GetAvailablePersonnelCountAsync(DateTime date)
        {
            try
            {
                // 1. 获取该日期的所有班次
                var shifts = await _workOrderRepository.Orm.Select<ShiftEntity>()
                    .Where(s => s.IsDeleted == false)
                    .ToListAsync();

                if (!shifts.Any())
                {
                    return 0; // 没有班次安排
                }

                // 2. 获取所有资质ID，用于统计全部人员数量
                var allQualifications = await _qualificationRepository.Select
                    .Where(q => q.IsDeleted == false)
                    .ToListAsync();
                
                var allQualificationIds = allQualifications.Any() 
                    ? string.Join(",", allQualifications.Select(q => q.Id))
                    : string.Empty; // 如果没有资质定义，传空字符串

                int totalAvailableCount = 0;

                // 3. 按班次计算可用人员数量
                foreach (var shift in shifts)
                {
                    // 构造该班次的实际工作时间段
                    var workStartTime = date.Date.Add(shift.StartTime);

                    // 调用人员服务获取该班次可用人员
                    // 传入所有资质ID，以获取具备任何资质的人员总数
                    var availablePersonnel = await _personService.GetAvailablePersonnelAsync(
                        allQualificationIds, // 传入所有资质ID
                        shift.Id,
                        workStartTime);
                    
                    totalAvailableCount += availablePersonnel.Count;
                }
                
                return totalAvailableCount;
            }
            catch (Exception)
            {
                return 5; // 保守的最小人员数量
            }
        }

        /// <summary>
        /// 获取指定日期可用设备数量
        /// 综合考虑设备状态、维护计划、校验计划、使用情况等因素
        /// 通过设备Repository直接查询数据库获取真实数据
        /// </summary>
        private async Task<int> GetAvailableEquipmentCountAsync(DateTime date)
        {
            try
            {
                // 1. 获取该日期所有可用的设备（状态为正常的设备）
                var availableEquipmentList = await _equipmentRepository.GetAvailableEquipmentAsync(date);
                
                if (availableEquipmentList == null || !availableEquipmentList.Any())
                {
                    return 0; // 没有可用设备
                }
                
                var baseEquipmentCount = availableEquipmentList.Count;
                
                // 2. 获取当日需要维护的设备ID列表
                var maintenanceEquipmentIds = await _equipmentMaintenanceRepository.GetMaintenanceEquipmentIdsAsync(date);
                var maintenanceEquipmentCount = maintenanceEquipmentIds?.Count ?? 0;
                
                // 3. 获取当日需要校验的设备ID列表
                var calibrationEquipmentIds = await _equipmentCalibrationRepository.GetCalibrationEquipmentIdsAsync(date);
                var calibrationEquipmentCount = calibrationEquipmentIds?.Count ?? 0;
                
                // 5. 计算最终可用设备数量
                // 业务逻辑：基础可用设备数 - 维护设备数 - 校验设备数 - 故障设备数
                // 注意：避免重复扣减，因为故障设备已经在基础可用设备统计中被排除
                var finalAvailableCount = baseEquipmentCount - maintenanceEquipmentCount - calibrationEquipmentCount;
                
                // 6. 数据合理性检查：确保返回值不为负数
                var result = Math.Max(0, finalAvailableCount);
                
                // 7. 业务验证：如果计算结果异常，进行日志记录和保护性处理
                if (result == 0 && baseEquipmentCount > 0)
                {
                    // 所有设备都被占用的情况，可能需要人工干预
                    // TODO: 记录警告日志，便于运维人员关注
                    return 1; // 返回最小可用数量，避免完全阻塞
                }
                
                return result;
            }
            catch (Exception)
            {
                // 异常处理：记录详细错误信息，返回保守估计值
                // TODO: 集成日志系统记录异常详情
                
                // 降级策略：当数据库查询异常时，返回基于历史数据的保守估计
                return await GetFallbackEquipmentCountAsync(date);
            }
        }

        /// <summary>
        /// 获取指定周可用人员数量
        /// 基于每日可用人员数量，计算一周内的平均可用人员数量
        /// </summary>
        private async Task<int> GetAvailablePersonnelCountForWeekAsync(DateTime weekStart, DateTime weekEnd)
        {
            try
            {
                var dailyCounts = new List<int>();
                
                // 遍历一周内每一天，计算每日可用人员数量
                for (var date = weekStart; date <= weekEnd; date = date.AddDays(1))
                {
                    var dailyCount = await GetAvailablePersonnelCountAsync(date);
                    dailyCounts.Add(dailyCount);
                }
                
                // 返回一周内的平均可用人员数量
                return dailyCounts.Any() ? (int)Math.Ceiling(dailyCounts.Average()) : 0;
            }
            catch (Exception)
            {
                return 30; // 保守估计的周平均人员数量
            }
        }

        /// <summary>
        /// 获取指定周可用设备数量
        /// 基于每日可用设备数量，计算一周内的平均可用设备数量
        /// </summary>
        private async Task<int> GetAvailableEquipmentCountForWeekAsync(DateTime weekStart, DateTime weekEnd)
        {
            try
            {
                var dailyCounts = new List<int>();
                
                // 遍历一周内每一天，计算每日可用设备数量
                for (var date = weekStart; date <= weekEnd; date = date.AddDays(1))
                {
                    var dailyCount = await GetAvailableEquipmentCountAsync(date);
                    dailyCounts.Add(dailyCount);
                }
                
                // 返回一周内的平均可用设备数量
                return dailyCounts.Any() ? (int)Math.Ceiling(dailyCounts.Average()) : 0;
            }
            catch (Exception)
            {
                return 20; // 保守估计的周平均设备数量
            }
        }

        /// <summary>
        /// 获取人员可用容量
        /// 计算指定时间范围内的人员总工作容量（人天）
        /// </summary>
        private async Task<int> GetAvailablePersonnelCapacityAsync(DateTime startDate, DateTime endDate)
        {
            try
            {
                var totalCapacity = 0;
                
                // 按日计算人员容量，累加得到总容量
                for (var date = startDate; date <= endDate; date = date.AddDays(1))
                {
                    var dailyPersonnelCount = await GetAvailablePersonnelCountAsync(date);
                    
                    // 假设每人每天工作8小时，将人员数量转换为工作容量
                    var dailyCapacity = dailyPersonnelCount * 8; // 8小时/人/天
                    totalCapacity += dailyCapacity;
                }
                
                // 返回总工作容量（工时）
                return totalCapacity;
            }
            catch (Exception)
            {
                // 异常时返回基于天数的保守估计
                var days = (endDate - startDate).Days + 1;
                return days * 5 * 8; // 5人 * 8小时 * 天数
            }
        }

        /// <summary>
        /// 获取设备可用容量
        /// 计算指定时间范围内的设备总工作容量（设备时）
        /// </summary>
        private async Task<int> GetAvailableEquipmentCapacityAsync(DateTime startDate, DateTime endDate)
        {
            try
            {
                var totalCapacity = 0;
                
                // 按日计算设备容量，累加得到总容量
                for (var date = startDate; date <= endDate; date = date.AddDays(1))
                {
                    var dailyEquipmentCount = await GetAvailableEquipmentCountAsync(date);
                    
                    // 假设每台设备每天可运行16小时（两班制）
                    var dailyCapacity = dailyEquipmentCount * 16; // 16小时/设备/天
                    totalCapacity += dailyCapacity;
                }
                
                // 返回总设备容量（设备时）
                return totalCapacity;
            }
            catch (Exception)
            {
                // 异常时返回基于天数的保守估计
                var days = (endDate - startDate).Days + 1;
                return days * 3 * 16; // 3台设备 * 16小时 * 天数
            }
        }

        /// <summary>
        /// 计算所需人员数量（基于业务规则的智能估算）
        /// </summary>
        private int CalculateRequiredPersonnelCount(List<WorkOrderEntity> tasks)
        {
            if (!tasks.Any()) return 0;

            // 按日期分组，计算每日最大并发人员需求
            var dailyRequirements = tasks
                .GroupBy(t => t.WorkOrderDate.Date)
                .Select(dayGroup =>
                {
                    var dayTasks = dayGroup.ToList();
                    
                    // 1. 基础需求：每个任务至少需要1个人员
                    var baseRequirement = dayTasks.Count;
                    
                    // 2. 复杂度调整：高复杂度任务可能需要额外人员
                    var complexityAdjustment = dayTasks
                        .Where(t => t.Complexity >= 8) // 高复杂度任务（优先级>=8）
                        .Count() * 0.5; // 每个高复杂度任务增加0.5个人员需求
                    
                    // 3. 紧急度调整：紧急任务可能需要备用人员
                    var urgencyAdjustment = dayTasks
                        .Where(t => t.Urgency >= 8) // 高紧急度任务
                        .Count() * 0.3; // 每个紧急任务增加0.3个人员需求
                    
                    // 4. 班次覆盖：不同班次需要独立人员配置
                    var shiftCount = dayTasks.Select(t => t.ShiftId).Distinct().Count();
                    var shiftMultiplier = Math.Max(1, shiftCount * 0.8); // 多班次系数
                    
                    // 5. FL人员考虑：需要额外的FL（FirstLine）人员支持
                    var flRequirement = Math.Ceiling(dayTasks.Count / 5.0); // 每5个任务配1个FL人员
                    
                    // 综合计算每日人员需求
                    var totalDailyRequirement = (baseRequirement + complexityAdjustment + urgencyAdjustment) 
                                              * shiftMultiplier + flRequirement;
                    
                    return (int)Math.Ceiling(totalDailyRequirement);
                })
                .ToList();

            // 返回一周内的最大日需求量（峰值需求）
            return dailyRequirements.Any() ? dailyRequirements.Max() : 0;
        }

        /// <summary>
        /// 计算所需设备数量（基于任务特性的智能估算）
        /// </summary>
        private int CalculateRequiredEquipmentCount(List<WorkOrderEntity> tasks)
        {
            if (!tasks.Any()) return 0;

            // 按日期分组，计算每日最大设备需求
            var dailyEquipmentRequirements = tasks
                .GroupBy(t => t.WorkOrderDate.Date)
                .Select(dayGroup =>
                {
                    var dayTasks = dayGroup.ToList();
                    
                    // 1. 基础需求：大多数任务需要专用设备
                    var baseEquipmentNeed = dayTasks.Count;
                    
                    // 2. 设备共享优化：某些设备可以在不同时间段共享
                    var shiftGroups = dayTasks.GroupBy(t => t.ShiftId);
                    var optimizedCount = 0;
                    
                    foreach (var shiftGroup in shiftGroups)
                    {
                        // 同一班次内设备不能共享，需要独立设备
                        optimizedCount += shiftGroup.Count();
                    }
                    
                    // 3. 设备类型考虑：不同工序可能需要专用设备
                    var processTypes = dayTasks.Select(t => t.ProcessCode).Distinct().Count();
                    var processMultiplier = Math.Max(1, processTypes * 0.6); // 工序多样性系数
                    
                    // 4. 备用设备：考虑设备故障风险
                    var backupRatio = 0.1; // 10%的备用设备
                    
                    var totalEquipmentNeed = optimizedCount * processMultiplier * (1 + backupRatio);
                    
                    return (int)Math.Ceiling(totalEquipmentNeed);
                })
                .ToList();

            // 返回一周内的最大日设备需求量
            return dailyEquipmentRequirements.Any() ? dailyEquipmentRequirements.Max() : 0;
        }

        /// <summary>
        /// 计算单日所需人员数量（基于业务规则的智能估算）
        /// </summary>
        private int CalculateRequiredPersonnelCountForDay(List<WorkOrderEntity> dayTasks)
        {
            // 边界情况处理
            if (dayTasks == null || !dayTasks.Any()) 
                return 0;

            // 数据完整性验证
            var invalidTasks = dayTasks.Where(t => t.Id <= 0 || (t.EstimatedHours.HasValue && t.EstimatedHours.Value < 0)).ToList();
            if (invalidTasks.Any())
            {
                throw new InvalidOperationException($"发现无效任务数据：任务ID或工时为负数，任务数量: {invalidTasks.Count}");
            }

            // 单日任务数量合理性检查
            if (dayTasks.Count > 500)
            {
                throw new InvalidOperationException($"单日任务数量异常：{dayTasks.Count}个，请检查数据是否正确");
            }

            // 1. 基础需求：每个任务至少需要1个人员
            var baseRequirement = dayTasks.Count;
            
            // 业务规则配置化处理，避免硬编码
            var businessRules = GetPersonnelCalculationRules();
            
            // 2. 复杂度调整：高复杂度任务可能需要额外人员协助
            var complexityAdjustment = 0;
            
            // 3. 紧急度调整：紧急任务可能需要备用人员或监督人员
            var urgencyAdjustment = 0;
            
            // 4. 班次覆盖：不同班次需要独立人员配置，无法跨班次共享
            var shiftCount = dayTasks.Select(t => t.ShiftId).Distinct().Count();
            var shiftMultiplier = Math.Max(1, shiftCount * businessRules.ShiftMultiplierFactor);
            
            // 5. FL人员支持：需要额外的FL（FirstLine）人员提供技术支持
            var flRequirement = 0;
            
            // 6. 工序专业化：不同工序可能需要专业技能人员
            var processSpecializationFactor = 0;
            
            // 综合计算每日人员需求
            var totalDailyRequirement = (baseRequirement + complexityAdjustment + urgencyAdjustment) 
                                      * shiftMultiplier * processSpecializationFactor + flRequirement;
            
            return (int)Math.Ceiling(totalDailyRequirement);
        }

        /// <summary>
        /// 计算单日所需设备数量（基于任务特性的智能估算）
        /// </summary>
        private int CalculateRequiredEquipmentCountForDay(List<WorkOrderEntity> dayTasks)
        {
            // 边界情况处理
            if (dayTasks == null || !dayTasks.Any()) 
                return 0;

            // 数据完整性验证
            var invalidTasks = dayTasks.Where(t => t.Id <= 0 || string.IsNullOrEmpty(t.ProcessCode)).ToList();
            if (invalidTasks.Any())
            {
                throw new InvalidOperationException($"发现无效任务数据：任务ID无效或工序代码为空，任务数量: {invalidTasks.Count}");
            }

            // 单日任务数量合理性检查
            if (dayTasks.Count > 500)
            {
                throw new InvalidOperationException($"单日任务数量异常：{dayTasks.Count}个，请检查数据是否正确");
            }
 
            // 检查任务的工序指定了设备的型号的任务需要设备
            decimal totalEquipmentNeed = dayTasks.Select(a => !string.IsNullOrWhiteSpace(a.ProcessEntity.EquipmentType)).Count();;
            return (int)Math.Ceiling(totalEquipmentNeed);
        }

        /// <summary>
        /// 获取周开始日期（周一）
        /// </summary>
        private DateTime GetWeekStartDate(DateTime date)
        {
            var daysFromMonday = (int)date.DayOfWeek - (int)DayOfWeek.Monday;
            if (daysFromMonday < 0) daysFromMonday += 7;
            return date.AddDays(-daysFromMonday);
        }

        /// <summary>
        /// 检查人员在指定日期是否在工作量限制范围内
        /// </summary>
        private async Task<bool> CheckPersonnelWorkLimitAsync(long personnelId, DateTime date)
        {
            try
            {
                // 获取该人员的工作量限制设置
                var workLimits = await _workOrderRepository.Orm.Select<PersonnelWorkLimitEntity>()
                    .Where(pwl => pwl.PersonnelId == personnelId)
                    .Where(pwl => pwl.IsDeleted == false)
                    .ToListAsync();

                if (!workLimits.Any())
                {
                    return true; // 没有工作量限制，默认可用
                }

                // 获取该人员在指定日期已分配的工作任务
                var assignedTasks = await _workOrderRepository.Select
                    .Where(wo => wo.AssignedPersonnelId == personnelId)
                    .Where(wo => wo.WorkOrderDate.Date == date.Date)
                    .Where(wo => wo.Status != (int)WorkOrderStatusEnum.Completed)
                    .ToListAsync();

                // 计算当日已分配的工作小时数
                var assignedHours = assignedTasks.Sum(t => t.EstimatedHours ?? 0);

                // 检查是否超过工作量限制
                foreach (var limit in workLimits)
                {
                    // 检查每周最大班次限制
                    if (limit.MaxShiftsPerWeek.HasValue)
                    {
                        var weekStart = GetWeekStartDate(date);
                        var weekEnd = weekStart.AddDays(6);
                        
                        var weeklyTasks = await _workOrderRepository.Select
                            .Where(wo => wo.AssignedPersonnelId == personnelId)
                            .Where(wo => wo.WorkOrderDate >= weekStart && wo.WorkOrderDate <= weekEnd)
                            .Where(wo => wo.Status != (int)WorkOrderStatusEnum.Completed)
                            .CountAsync();
                        
                        if (weeklyTasks >= limit.MaxShiftsPerWeek.Value)
                        {
                            return false; // 超过每周班次限制
                        }
                    }
                    
                    // 检查连续工作日限制
                    if (limit.MaxContinuousWorkDays.HasValue)
                    {
                        var continuousDays = await CalculateContinuousWorkDaysAsync(personnelId, date);
                        if (continuousDays >= limit.MaxContinuousWorkDays.Value)
                        {
                            return false; // 超过连续工作日限制
                        }
                    }
                }

                return true; // 在工作量限制范围内
            }
            catch (Exception)
            {
                // 异常时保守处理，返回可用状态
                return true;
            }
        }

        /// <summary>
        /// 获取指定日期故障设备数量
        /// 通过设备Repository直接查询数据库获取故障设备信息
        /// </summary>
        private async Task<int> GetFaultEquipmentCountAsync(DateTime date)
        {
            try
            {
                // 直接查询状态为故障的设备数量
                var faultEquipmentList = await _equipmentRepository.GetByStatusAsync(EquipmentStatus.Fault);
                
                if (faultEquipmentList == null)
                {
                    return 0;
                }
                
                // 返回故障设备数量
                var faultCount = faultEquipmentList.Count;
                
                return Math.Max(0, faultCount);
            }
            catch (Exception)
            {
                return 1; // 保守估计，假设有1台故障设备
            }
        }

        /// <summary>
        /// 计算人员截至指定日期的连续工作天数
        /// </summary>
        private async Task<int> CalculateContinuousWorkDaysAsync(long personnelId, DateTime targetDate)
        {
            try
            {
                var continuousDays = 0;
                var currentDate = targetDate;
                
                // 向前查找连续工作日，最多查找14天避免性能问题
                for (int i = 0; i < 14; i++)
                {
                    var hasTaskOnDate = await _workOrderRepository.Select
                        .Where(wo => wo.AssignedPersonnelId == personnelId)
                        .Where(wo => wo.WorkOrderDate.Date == currentDate.Date)
                        .Where(wo => wo.Status != (int)WorkOrderStatusEnum.Completed)
                        .AnyAsync();
                    
                    if (hasTaskOnDate)
                    {
                        continuousDays++;
                        currentDate = currentDate.AddDays(-1);
                    }
                    else
                    {
                        break; // 遇到休息日，中断连续工作
                    }
                }
                
                return continuousDays;
            }
            catch (Exception)
            {
                return 0; // 异常时返回0，避免阻塞流程
            }
        }

        /// <summary>
        /// EAM服务不可用时的设备数量降级策略
        /// 基于历史数据和业务经验的保守估计
        /// </summary>
        private Task<int> GetFallbackEquipmentCountAsync(DateTime date)
        {
            try
            {
                // 降级策略：基于历史平均值或业务规则的估算
                
                // 1. 可以基于历史同期数据
                var historicalAverage = 8; // 假设历史平均可用设备数量
                
                // 2. 考虑季节性因素
                var seasonalFactor = date.Month switch
                {
                    12 or 1 or 2 => 0.8, // 冬季维护较多
                    6 or 7 or 8 => 0.9,  // 夏季使用频繁
                    _ => 1.0             // 其他月份正常
                };
                
                // 3. 考虑工作日因素
                var weekdayFactor = date.DayOfWeek switch
                {
                    DayOfWeek.Saturday or DayOfWeek.Sunday => 0.7, // 周末可用度较低
                    _ => 1.0
                };
                
                var estimatedCount = (int)(historicalAverage * seasonalFactor * weekdayFactor);
                return Task.FromResult(Math.Max(1, estimatedCount)); // 至少保证1台设备可用
            }
            catch (Exception)
            {
                return Task.FromResult(3); // 最保守的估计
            }
        }

        /// <summary>
        /// 获取人员计算规则配置
        /// 提供可配置的业务规则参数，避免硬编码
        /// </summary>
        private PersonnelCalculationRules GetPersonnelCalculationRules()
        {
            return new PersonnelCalculationRules
            {
                HighComplexityThreshold = 8,      // 高复杂度阈值
                ComplexityAdjustmentFactor = 0.5, // 复杂度调整系数
                HighUrgencyThreshold = 8,         // 高紧急度阈值  
                UrgencyAdjustmentFactor = 0.3,    // 紧急度调整系数
                ShiftMultiplierFactor = 0.8,      // 班次系数
                TasksPerFlPersonnel = 5,          // 每个FL人员支持的任务数
                MultiProcessFactor = 1.2          // 多工序系数
            };
        }

        #endregion
    }

    /// <summary>
    /// 人员计算规则配置
    /// </summary>
    public class PersonnelCalculationRules
    {
        /// <summary>
        /// 高复杂度阈值
        /// </summary>
        public int HighComplexityThreshold { get; set; }

        /// <summary>
        /// 复杂度调整系数
        /// </summary>
        public double ComplexityAdjustmentFactor { get; set; }

        /// <summary>
        /// 高紧急度阈值
        /// </summary>
        public int HighUrgencyThreshold { get; set; }

        /// <summary>
        /// 紧急度调整系数
        /// </summary>
        public double UrgencyAdjustmentFactor { get; set; }

        /// <summary>
        /// 班次系数
        /// </summary>
        public double ShiftMultiplierFactor { get; set; }

        /// <summary>
        /// 每个FL人员支持的任务数
        /// </summary>
        public int TasksPerFlPersonnel { get; set; }

        /// <summary>
        /// 多工序系数
        /// </summary>
        public double MultiProcessFactor { get; set; }
    }
}