using System;
using System.Collections.Generic;
using System.Linq;
using NPP.SmartSchedue.Api.Contracts.Services.Integration.Models;
using NPP.SmartSchedue.Api.Contracts.Services.Integration.Output;

namespace NPP.SmartSchedue.Api.Contracts.Services.Integration.Output
{
    /// <summary>
    /// 人员分配推荐结果
    /// 智能推荐系统生成的最优人员分配方案
    /// 包含推荐列表、最优分配、置信度评估、冲突检测等全面信息
    /// </summary>
    public class PersonnelAllocationRecommendation
    {
        #region 核心推荐数据

        /// <summary>
        /// 推荐批次标识
        /// 用于关联和追踪推荐过程
        /// </summary>
        public string RecommendationBatchId { get; set; } = string.Empty;

        /// <summary>
        /// 推荐生成时间
        /// </summary>
        public DateTime GeneratedAt { get; set; } = DateTime.Now;

        /// <summary>
        /// 推荐策略
        /// 生成推荐时使用的分配策略
        /// </summary>
        public string Strategy { get; set; } = string.Empty;

        /// <summary>
        /// 推荐任务总数
        /// </summary>
        public int TotalTaskCount { get; set; }

        /// <summary>
        /// 成功推荐任务数
        /// </summary>
        public int SuccessfulRecommendationCount { get; set; }

        /// <summary>
        /// 推荐成功率
        /// </summary>
        public double SuccessRate => TotalTaskCount > 0 ? (double)SuccessfulRecommendationCount / TotalTaskCount * 100 : 0;

        #endregion

        #region 详细推荐结果

        /// <summary>
        /// 任务推荐映射
        /// Key: 任务ID, Value: 推荐人员列表（按评分排序）
        /// </summary>
        public Dictionary<long, List<PersonnelCandidate>> Recommendations { get; set; } = new();

        /// <summary>
        /// 最优分配方案
        /// Key: 任务ID, Value: 最优推荐人员
        /// </summary>
        public Dictionary<long, PersonnelCandidate> OptimalAssignments { get; set; } = new();

        /// <summary>
        /// 替代分配方案
        /// 当最优方案不可行时的备选方案
        /// </summary>
        public Dictionary<long, List<PersonnelCandidate>> AlternativeAssignments { get; set; } = new();

        #endregion

        #region 质量评估指标

        /// <summary>
        /// 推荐置信度 (0-100)
        /// 对推荐结果准确性的整体信心程度
        /// </summary>
        public double RecommendationConfidence { get; set; }

        /// <summary>
        /// 推荐质量评分 (0-100)
        /// 综合评估推荐结果的质量水平
        /// </summary>
        public double QualityScore { get; set; }

        /// <summary>
        /// 平均匹配分数
        /// 所有推荐人员的平均匹配分数
        /// </summary>
        public double AverageMatchScore { get; set; }

        /// <summary>
        /// 最低匹配分数
        /// 所有推荐人员中的最低匹配分数
        /// </summary>
        public double MinimumMatchScore { get; set; }

        /// <summary>
        /// 最高匹配分数
        /// 所有推荐人员中的最高匹配分数
        /// </summary>
        public double MaximumMatchScore { get; set; }

        #endregion

        #region 风险评估和冲突检测

        /// <summary>
        /// 潜在冲突警告
        /// 检测到的分配冲突和风险提示
        /// </summary>
        public List<ConflictWarning> ConflictWarnings { get; set; } = new();

        /// <summary>
        /// 风险评估结果
        /// 整体风险评估和风险分布
        /// </summary>
        public RiskAssessment RiskAssessment { get; set; } = new();

        /// <summary>
        /// 合规性检查结果
        /// 推荐方案的合规性评估
        /// </summary>
        public ComplianceCheckResult ComplianceCheck { get; set; } = new();

        #endregion

        #region 统计和分析数据

        /// <summary>
        /// 人员利用率统计
        /// 推荐方案中的人员工作负载分布
        /// </summary>
        public Dictionary<long, PersonnelUtilizationStats> PersonnelUtilization { get; set; } = new();

        /// <summary>
        /// 技能匹配统计
        /// 推荐方案的整体技能匹配情况
        /// </summary>
        public SkillMatchStatistics SkillMatchStats { get; set; } = new();

        /// <summary>
        /// 负载均衡评估
        /// 推荐方案的工作负载均衡程度
        /// </summary>
        public LoadBalanceAssessment LoadBalanceAssessment { get; set; } = new();

        #endregion

        #region 推荐摘要和说明

        /// <summary>
        /// 推荐摘要
        /// 推荐结果的简要总结
        /// </summary>
        public string RecommendationSummary { get; set; } = string.Empty;

        /// <summary>
        /// 推荐依据
        /// 生成推荐的具体理由和依据
        /// </summary>
        public string RecommendationBasis { get; set; } = string.Empty;

        /// <summary>
        /// 执行建议
        /// 实施推荐方案的具体建议和注意事项
        /// </summary>
        public List<string> ExecutionAdvice { get; set; } = new();

        /// <summary>
        /// 改进建议
        /// 提高推荐质量的改进建议
        /// </summary>
        public List<string> ImprovementSuggestions { get; set; } = new();

        #endregion

        #region 性能指标

        /// <summary>
        /// 推荐生成耗时（毫秒）
        /// </summary>
        public long GenerationTimeMs { get; set; }

        /// <summary>
        /// 推荐算法版本
        /// </summary>
        public string AlgorithmVersion { get; set; } = string.Empty;

        /// <summary>
        /// 使用的权重配置
        /// </summary>
        public Dictionary<string, double> UsedWeights { get; set; } = new();

        #endregion

        #region 构造函数

        public PersonnelAllocationRecommendation()
        {
            Recommendations = new Dictionary<long, List<PersonnelCandidate>>();
            OptimalAssignments = new Dictionary<long, PersonnelCandidate>();
            AlternativeAssignments = new Dictionary<long, List<PersonnelCandidate>>();
            ConflictWarnings = new List<ConflictWarning>();
            ExecutionAdvice = new List<string>();
            ImprovementSuggestions = new List<string>();
            PersonnelUtilization = new Dictionary<long, PersonnelUtilizationStats>();
            UsedWeights = new Dictionary<string, double>();
        }

        #endregion

        #region 辅助方法

        /// <summary>
        /// 获取指定任务的推荐人员数量
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <returns>推荐人员数量</returns>
        public int GetRecommendationCount(long taskId)
        {
            return Recommendations.TryGetValue(taskId, out var candidates) ? candidates.Count : 0;
        }

        /// <summary>
        /// 获取指定任务的最优推荐人员
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <returns>最优推荐人员，如果不存在则返回null</returns>
        public PersonnelCandidate? GetOptimalCandidate(long taskId)
        {
            return OptimalAssignments.TryGetValue(taskId, out var candidate) ? candidate : null;
        }

        /// <summary>
        /// 检查是否有冲突警告
        /// </summary>
        /// <returns>是否存在冲突警告</returns>
        public bool HasConflicts => ConflictWarnings.Any();

        /// <summary>
        /// 获取高风险的冲突警告
        /// </summary>
        /// <returns>高风险冲突警告列表</returns>
        public List<ConflictWarning> GetHighRiskConflicts()
        {
            return ConflictWarnings.Where(c => c.RiskLevel == RiskLevel.High).ToList();
        }

        /// <summary>
        /// 计算整体推荐质量
        /// </summary>
        /// <returns>推荐质量评分</returns>
        public double CalculateOverallQuality()
        {
            if (!OptimalAssignments.Any())
                return 0;

            var scores = OptimalAssignments.Values.Select(c => c.TotalScore);
            return scores.Average();
        }

        #endregion
    }

    #region 相关数据模型

    /// <summary>
    /// 冲突警告
    /// </summary>
    public class ConflictWarning
    {
        /// <summary>
        /// 冲突描述
        /// </summary>
        public string Description { get; set; } = string.Empty;

        /// <summary>
        /// 涉及的任务ID
        /// </summary>
        public List<long> AffectedTaskIds { get; set; } = new();

        /// <summary>
        /// 涉及的人员ID
        /// </summary>
        public List<long> AffectedPersonnelIds { get; set; } = new();

        /// <summary>
        /// 风险等级
        /// </summary>
        public RiskLevel RiskLevel { get; set; } = RiskLevel.Medium;

        /// <summary>
        /// 建议解决方案
        /// </summary>
        public List<string> SuggestedSolutions { get; set; } = new();

        /// <summary>
        /// 冲突发生时间
        /// </summary>
        public DateTime ConflictTime { get; set; } = DateTime.Now;
    }

    /// <summary>
    /// 合规性检查结果
    /// </summary>
    public class ComplianceCheckResult
    {
        /// <summary>
        /// 是否合规
        /// </summary>
        public bool IsCompliant { get; set; } = true;

        /// <summary>
        /// 合规性评分 (0-100)
        /// </summary>
        public double ComplianceScore { get; set; }

        /// <summary>
        /// 合规检查项目
        /// </summary>
        public List<ComplianceCheckItem> CheckItems { get; set; } = new();

        /// <summary>
        /// 不合规项目
        /// </summary>
        public List<ComplianceViolation> Violations { get; set; } = new();

        /// <summary>
        /// 合规性建议
        /// </summary>
        public List<string> ComplianceSuggestions { get; set; } = new();
    }

    /// <summary>
    /// 人员利用率统计
    /// </summary>
    public class PersonnelUtilizationStats
    {
        /// <summary>
        /// 人员ID
        /// </summary>
        public long PersonnelId { get; set; }

        /// <summary>
        /// 人员姓名
        /// </summary>
        public string PersonnelName { get; set; } = string.Empty;

        /// <summary>
        /// 已分配任务数
        /// </summary>
        public int AssignedTaskCount { get; set; }

        /// <summary>
        /// 工作负载百分比
        /// </summary>
        public double WorkloadPercentage { get; set; }

        /// <summary>
        /// 是否超负荷
        /// </summary>
        public bool IsOverloaded => WorkloadPercentage > 100;

        /// <summary>
        /// 剩余可分配容量
        /// </summary>
        public double RemainingCapacity { get; set; }
    }

    /// <summary>
    /// 技能匹配统计
    /// </summary>
    public class SkillMatchStatistics
    {
        /// <summary>
        /// 平均技能匹配分数
        /// </summary>
        public double AverageSkillMatchScore { get; set; }

        /// <summary>
        /// 技能匹配分布
        /// 各分数段的分布情况
        /// </summary>
        public Dictionary<string, int> ScoreDistribution { get; set; } = new();

        /// <summary>
        /// 技能匹配率
        /// </summary>
        public double SkillMatchRate { get; set; }

        /// <summary>
        /// 技能提升建议
        /// </summary>
        public List<string> SkillImprovementSuggestions { get; set; } = new();
    }

    /// <summary>
    /// 负载均衡评估
    /// </summary>
    public class LoadBalanceAssessment
    {
        /// <summary>
        /// 负载均衡评分 (0-100)
        /// </summary>
        public double LoadBalanceScore { get; set; }

        /// <summary>
        /// 负载分布情况
        /// </summary>
        public Dictionary<string, double> LoadDistribution { get; set; } = new();

        /// <summary>
        /// 负载不均衡程度
        /// </summary>
        public double LoadImbalanceDegree { get; set; }

        /// <summary>
        /// 负载均衡建议
        /// </summary>
        public List<string> LoadBalanceSuggestions { get; set; } = new();
    }

    /// <summary>
    /// 合规检查项目
    /// </summary>
    public class ComplianceCheckItem
    {
        /// <summary>
        /// 检查项目名称
        /// </summary>
        public string ItemName { get; set; } = string.Empty;

        /// <summary>
        /// 检查结果
        /// </summary>
        public bool IsPassed { get; set; }

        /// <summary>
        /// 检查详情
        /// </summary>
        public string Details { get; set; } = string.Empty;

        /// <summary>
        /// 检查时间
        /// </summary>
        public DateTime CheckTime { get; set; } = DateTime.Now;
    }

    /// <summary>
    /// 合规违规
    /// </summary>
    public class ComplianceViolation
    {
        /// <summary>
        /// 违规类型
        /// </summary>
        public string ViolationType { get; set; } = string.Empty;

        /// <summary>
        /// 违规描述
        /// </summary>
        public string Description { get; set; } = string.Empty;

        /// <summary>
        /// 违规严重程度
        /// </summary>
        public ViolationSeverity Severity { get; set; } = ViolationSeverity.Warning;

        /// <summary>
        /// 涉及的任务ID
        /// </summary>
        public List<long> AffectedTaskIds { get; set; } = new();

        /// <summary>
        /// 涉及的人员ID
        /// </summary>
        public List<long> AffectedPersonnelIds { get; set; } = new();
    }

    #endregion
}
