using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using FreeSql.DataAnnotations;
using ZhonTai.Admin.Core.Entities;

namespace NPP.SmartSchedue.Api.Contracts.Domain.Integration
{
    /// <summary>
    /// 智能整合记录实体
    /// 用于记录每次智能任务整合的完整过程和结果
    /// 
    /// 业务思考：
    /// 1. 作为重要的业务审计数据，需要完整记录整合的全过程
    /// 2. 支持多租户模式，确保数据安全隔离
    /// 3. 提供丰富的查询维度，支持历史分析和决策支持
    /// 4. 考虑JSON存储复杂结果数据，平衡存储效率和查询性能
    /// </summary>
    [Table(Name = "sse_integration_record")]
    [Index("idx_integration_batch_code", "IntegrationBatchCode", true)] // 批次编码唯一索引
    [Index("idx_integration_time", "IntegrationTime")] // 时间索引，支持时间范围查询
    [Index("idx_operator", "OperatorUserId")] // 操作员索引
    [Index("idx_tenant_time", "TenantId,IntegrationTime")] // 租户+时间组合索引
    public class IntegrationRecordEntity : EntityTenant
    {
        /// <summary>
        /// 整合批次编码
        /// 格式：INT + yyyyMMddHHmmss + XXX，如：INT20240314143025123
        /// 业务意义：唯一标识一次整合操作，便于追踪和关联
        /// </summary>
        [Column(StringLength = 30)]
        [Required(ErrorMessage = "整合批次编码不能为空")]
        public string IntegrationBatchCode { get; set; } = string.Empty;

        /// <summary>
        /// 整合执行时间
        /// 记录实际执行整合操作的时间点
        /// </summary>
        [Required]
        public DateTime IntegrationTime { get; set; } = DateTime.Now;

        /// <summary>
        /// 操作人员用户ID
        /// 关联到系统用户表，记录执行整合的操作员
        /// </summary>
        [Required(ErrorMessage = "操作人员ID不能为空")]
        public long OperatorUserId { get; set; }

        /// <summary>
        /// 操作人员用户名
        /// 冗余存储，提高查询性能，避免频繁关联用户表
        /// </summary>
        [Column(StringLength = 50)]
        [Required(ErrorMessage = "操作人员用户名不能为空")]
        public string OperatorUserName { get; set; } = string.Empty;

        /// <summary>
        /// 操作人员真实姓名
        /// 用于业务场景下的可读性显示
        /// </summary>
        [Column(StringLength = 50)]
        [Required(ErrorMessage = "操作人员姓名不能为空")]
        public string OperatorRealName { get; set; } = string.Empty;

        /// <summary>
        /// 整合的任务ID列表（JSON格式存储）
        /// 存储格式：[1,2,3,4,5]
        /// 业务意义：记录本次整合涉及的所有任务，支持反向查询
        /// </summary>
        [Column(DbType = "longtext")]
        [Required(ErrorMessage = "任务ID列表不能为空")]
        public string TaskIdsJson { get; set; } = "[]";

        /// <summary>
        /// 整合策略配置（JSON格式存储）
        /// 包含：人员分配策略、设备分配策略、各种配置参数
        /// 业务价值：记录决策依据，支持策略效果分析和优化
        /// </summary>
        [Column(DbType = "json")]
        [Required]
        public string StrategyConfigJson { get; set; } = "{}";

        /// <summary>
        /// 人员分配结果详情（JSON格式存储）
        /// 包含：成功匹配列表、失败原因、工作负载分析等
        /// 存储完整的PersonnelAllocationResult对象
        /// </summary>
        [Column(DbType = "json")]
        public string PersonnelAllocationResultJson { get; set; } = "{}";

        /// <summary>
        /// 设备分配结果详情（JSON格式存储）
        /// 包含：成功匹配列表、失败原因、利用率分析等
        /// 存储完整的EquipmentAllocationResult对象
        /// </summary>
        [Column(DbType = "json")]
        public string EquipmentAllocationResultJson { get; set; } = "{}";

        /// <summary>
        /// 成功分配的任务数量
        /// 统计字段，提高查询性能
        /// </summary>
        [Required]
        public int SuccessTaskCount { get; set; } = 0;

        /// <summary>
        /// 分配失败的任务数量
        /// 统计字段，用于成功率计算和分析
        /// </summary>
        [Required]
        public int FailedTaskCount { get; set; } = 0;

        /// <summary>
        /// 整合执行总耗时（毫秒）
        /// 性能监控指标，用于系统优化分析
        /// </summary>
        [Required]
        public long ElapsedMilliseconds { get; set; } = 0;

        /// <summary>
        /// 人员分配公平性评分（0-100）
        /// 业务指标，评估人员工作负载分配的公平程度
        /// </summary>
        public int PersonnelFairnessScore { get; set; } = 0;

        /// <summary>
        /// 设备整体利用率（百分比，保留1位小数）
        /// 业务指标，评估设备资源利用效率
        /// </summary>
        [Column(DbType = "decimal(5,1)")]
        public decimal EquipmentUtilizationRate { get; set; } = 0.0m;

        /// <summary>
        /// 整合结果摘要描述
        /// 简洁的文本描述，便于快速了解整合结果
        /// 示例：总任务数: 25, 成功: 23, 失败: 2, 成功率: 92%
        /// </summary>
        [Column(StringLength = 500)]
        public string ResultSummary { get; set; } = string.Empty;

        /// <summary>
        /// 失败原因分类统计（JSON格式存储）
        /// 格式：{"PersonnelAllocationFailed": 2, "EquipmentAllocationFailed": 1}
        /// 业务价值：支持失败原因分析和系统改进
        /// </summary>
        [Column(DbType = "json")]
        public string FailureReasonStats { get; set; } = "{}";

        /// <summary>
        /// 涉及的项目编号列表（逗号分隔）
        /// 便于按项目查询整合历史，支持项目级别的数据分析
        /// 示例：PRJ001,PRJ002,PRJ003
        /// </summary>
        [Column(StringLength = 500)]
        public string ProjectNumbers { get; set; } = string.Empty;

        /// <summary>
        /// 整合类型
        /// 标识整合的触发方式：Manual-手动触发, Scheduled-定时触发, Auto-自动触发
        /// </summary>
        [Column(StringLength = 20)]
        [Required]
        public string IntegrationType { get; set; } = "Manual";

        /// <summary>
        /// 业务备注信息
        /// 操作员填写的备注，记录特殊情况或业务背景
        /// </summary>
        [Column(StringLength = 1000)]
        public string Remarks { get; set; } = string.Empty;

        /// <summary>
        /// 是否为测试数据
        /// 区分生产数据和测试数据，便于数据清理和分析
        /// </summary>
        [Required]
        public bool IsTestData { get; set; } = false;

        /// <summary>
        /// 数据版本号
        /// 支持数据结构演进和向后兼容
        /// </summary>
        [Required]
        public int DataVersion { get; set; } = 1;

        /// <summary>
        /// 整合记录发布状态
        /// 控制整合记录的生命周期管理
        /// Draft-草稿, Published-已发布, Completed-已完成, Cancelled-已撤销
        /// </summary>
        [Column(StringLength = 20)]
        [Required]
        public string PublishStatus { get; set; } = IntegrationRecordPublishStatus.Draft;

        /// <summary>
        /// 发布时间
        /// 记录正式发布生效的时间点
        /// </summary>
        public DateTime? PublishedTime { get; set; }

        /// <summary>
        /// 发布操作员用户ID
        /// 记录执行发布操作的用户，可能与创建者不同
        /// </summary>
        public long? PublishedByUserId { get; set; }

        /// <summary>
        /// 发布操作员用户名
        /// </summary>
        [Column(StringLength = 50)]
        public string PublishedByUserName { get; set; } = string.Empty;

        /// <summary>
        /// 发布操作员真实姓名
        /// </summary>
        [Column(StringLength = 50)]
        public string PublishedByRealName { get; set; } = string.Empty;

        /// <summary>
        /// 发布说明
        /// 记录发布时的业务说明或特殊情况备注
        /// </summary>
        [Column(StringLength = 500)]
        public string PublishRemarks { get; set; } = string.Empty;

        /// <summary>
        /// 完成时间
        /// 所有任务执行完毕的时间点
        /// </summary>
        public DateTime? CompletedTime { get; set; }

        /// <summary>
        /// 撤销时间
        /// 记录被撤销的时间点
        /// </summary>
        public DateTime? CancelledTime { get; set; }

        /// <summary>
        /// 撤销操作员用户ID
        /// </summary>
        public long? CancelledByUserId { get; set; }

        /// <summary>
        /// 撤销操作员用户名
        /// </summary>
        [Column(StringLength = 50)]
        public string CancelledByUserName { get; set; } = string.Empty;

        /// <summary>
        /// 撤销原因
        /// 记录撤销的具体原因和说明
        /// </summary>
        [Column(StringLength = 500)]
        public string CancelReason { get; set; } = string.Empty;

        #region 版本管理和变更追踪扩展字段

        /// <summary>
        /// 当前版本号
        /// 每次修改后自增，用于版本管理和冲突检测
        /// </summary>
        [Required]
        public int CurrentVersion { get; set; } = 1;

        /// <summary>
        /// 父版本ID
        /// 指向上一个版本的整合记录，构建版本链
        /// null表示这是初始版本
        /// </summary>
        public long? ParentVersionId { get; set; }

        /// <summary>
        /// 根版本ID  
        /// 指向版本链的根节点，用于快速定位同一整合记录的所有版本
        /// </summary>
        [Required]
        public long RootVersionId { get; set; }

        /// <summary>
        /// 版本创建原因
        /// 记录为什么创建这个新版本：TaskModified-任务修改, ManualAdjustment-手动调整, SystemReallocation-系统重新分配
        /// </summary>
        [Column(StringLength = 50)]
        public string VersionReason { get; set; } = string.Empty;

        /// <summary>
        /// 变更摘要
        /// 简述本版本相对于上一版本的主要变更内容
        /// </summary>
        [Column(StringLength = 1000)]
        public string ChangeSummary { get; set; } = string.Empty;

        /// <summary>
        /// 变更详情JSON
        /// 存储详细的变更信息，包括变更类型、影响的任务、前后对比等
        /// 格式：{"changedTasks": [...], "modifications": [...], "affectedPersonnel": [...]}
        /// </summary>
        [Column(DbType = "json")]
        public string ChangeDetailsJson { get; set; } = "{}";

        /// <summary>
        /// 是否为活跃版本
        /// true表示这是当前生效的版本，每个根版本只能有一个活跃版本
        /// </summary>
        [Required]
        public bool IsActiveVersion { get; set; } = true;

        /// <summary>
        /// 变更触发源
        /// 记录变更的触发来源：TaskChange-任务变更, UserModification-用户修改, SystemOptimization-系统优化
        /// </summary>
        [Column(StringLength = 30)]
        public string ChangeTriggerSource { get; set; } = "Initial";

        /// <summary>
        /// 原始任务数量
        /// 记录初始分配时的任务数量，用于对比分析
        /// </summary>
        public int OriginalTaskCount { get; set; } = 0;

        /// <summary>
        /// 变更影响评分
        /// 0-100分，评估本次变更对整体分配方案的影响程度
        /// </summary>
        public int ChangeImpactScore { get; set; } = 0;

        /// <summary>
        /// 自动重新分配标志
        /// 标记是否可以自动进行重新分配，还是需要人工干预
        /// </summary>
        [Required]
        public bool AllowAutoReallocation { get; set; } = true;

        /// <summary>
        /// 上次检查变更时间
        /// 用于变更检测和增量更新机制
        /// </summary>
        public DateTime? LastChangeCheckTime { get; set; }

        /// <summary>
        /// 快照数据JSON
        /// 存储关键业务数据的快照，用于版本对比和回滚
        /// 包含：任务分配快照、人员工作负载快照、设备利用率快照等
        /// </summary>
        [Column(DbType = "json")]
        public string SnapshotDataJson { get; set; } = "{}";

        #endregion

        #region 计算属性

        /// <summary>
        /// 整合成功率（计算属性）
        /// 返回成功率百分比，保留1位小数
        /// </summary>
        [Navigate(nameof(SuccessTaskCount))]
        public decimal SuccessRate
        {
            get
            {
                var totalTasks = SuccessTaskCount + FailedTaskCount;
                return totalTasks > 0 ? Math.Round((decimal)SuccessTaskCount / totalTasks * 100, 1) : 0;
            }
            set { } // FreeSql需要set访问器，但这是计算属性，所以提供空实现
        }

        /// <summary>
        /// 任务总数（计算属性）
        /// </summary>
        [Navigate(nameof(SuccessTaskCount))]
        public int TotalTaskCount 
        { 
            get => SuccessTaskCount + FailedTaskCount;
            set { } // FreeSql需要set访问器，但这是计算属性，所以提供空实现
        }

        /// <summary>
        /// 整体匹配成功率（计算属性）
        /// </summary>
        public decimal OverallMatchSuccessRate => SuccessRate / 100;

        /// <summary>
        /// 平均任务复杂度（计算属性）
        /// </summary>
        public decimal AverageTaskComplexity => 2.5m; // 暂时使用固定值

        /// <summary>
        /// 平均每任务耗时（计算属性）
        /// 返回毫秒数，用于性能分析
        /// </summary>
        [Navigate(nameof(ElapsedMilliseconds))]
        public long AverageTimePerTask
        {
            get
            {
                var totalTasks = TotalTaskCount;
                return totalTasks > 0 ? ElapsedMilliseconds / totalTasks : 0;
            }
            set { } // FreeSql需要set访问器，但这是计算属性，所以提供空实现
        }

        #endregion

        #region 业务方法

        /// <summary>
        /// 反序列化任务ID列表
        /// 将JSON格式的TaskIdsJson转换为List&lt;long&gt;
        /// </summary>
        public List<long> GetTaskIds()
        {
            try
            {
                if (string.IsNullOrWhiteSpace(TaskIdsJson))
                    return new List<long>();

                // 优先尝试JSON反序列化
                try
                {
                    return System.Text.Json.JsonSerializer.Deserialize<List<long>>(TaskIdsJson) ?? new List<long>();
                }
                catch
                {
                    // 兼容旧格式（逗号分隔）
                    return TaskIdsJson.Split(',', StringSplitOptions.RemoveEmptyEntries)
                                    .Select(p => p.Trim())
                                    .Where(p => !string.IsNullOrEmpty(p))
                                    .Select(long.Parse)
                                    .ToList();
                }
            }
            catch
            {
                return new List<long>();
            }
        }

        /// <summary>
        /// 设置任务ID列表
        /// 将List&lt;long&gt;序列化为JSON存储
        /// </summary>
        public void SetTaskIds(List<long> taskIds)
        {
            TaskIdsJson = System.Text.Json.JsonSerializer.Serialize(taskIds ?? new List<long>());
        }

        /// <summary>
        /// 获取项目编号列表
        /// 将逗号分隔的项目编号字符串转换为列表
        /// </summary>
        public List<string> GetProjectNumbers()
        {
            if (string.IsNullOrWhiteSpace(ProjectNumbers))
                return new List<string>();

            return ProjectNumbers.Split(',', StringSplitOptions.RemoveEmptyEntries)
                                .Select(p => p.Trim())
                                .Where(p => !string.IsNullOrEmpty(p))
                                .ToList();
        }

        /// <summary>
        /// 设置项目编号列表
        /// 将列表转换为逗号分隔的字符串存储
        /// </summary>
        public void SetProjectNumbers(List<string> projectNumbers)
        {
            if (projectNumbers == null || !projectNumbers.Any())
            {
                ProjectNumbers = string.Empty;
                return;
            }

            ProjectNumbers = string.Join(",", projectNumbers.Where(p => !string.IsNullOrWhiteSpace(p)));
        }

        /// <summary>
        /// 更新统计信息
        /// 根据分配结果更新各项统计字段
        /// </summary>
        public void UpdateStatistics(int successCount, int failedCount, long elapsedMs, int fairnessScore, decimal utilizationRate)
        {
            SuccessTaskCount = successCount;
            FailedTaskCount = failedCount;
            ElapsedMilliseconds = elapsedMs;
            PersonnelFairnessScore = fairnessScore;
            EquipmentUtilizationRate = utilizationRate;
            
            ResultSummary = $"总任务数: {TotalTaskCount}, 成功: {SuccessTaskCount}, 失败: {FailedTaskCount}, 成功率: {SuccessRate}%";
        }

        #region 版本管理业务方法

        /// <summary>
        /// 创建新版本
        /// 基于当前版本创建一个新的版本记录，用于变更追踪
        /// </summary>
        /// <param name="reason">版本创建原因</param>
        /// <param name="changeSummary">变更摘要</param>
        /// <param name="operatorUserId">操作员用户ID</param>
        /// <param name="operatorName">操作员姓名</param>
        /// <returns>新版本的整合记录实体</returns>
        public IntegrationRecordEntity CreateNewVersion(string reason, string changeSummary, long operatorUserId, string operatorName)
        {
            var newVersion = new IntegrationRecordEntity
            {
                // 继承基本信息
                IntegrationBatchCode = this.IntegrationBatchCode,
                TenantId = this.TenantId,
                RootVersionId = this.RootVersionId == 0 ? this.Id : this.RootVersionId,
                ParentVersionId = this.Id,
                CurrentVersion = this.CurrentVersion + 1,
                
                // 版本变更信息
                VersionReason = reason,
                ChangeSummary = changeSummary,
                ChangeTriggerSource = reason,
                IsActiveVersion = true, // 新版本为活跃版本
                
                // 操作员信息
                OperatorUserId = operatorUserId,
                OperatorUserName = operatorName,
                OperatorRealName = operatorName,
                IntegrationTime = DateTime.Now,
                
                // 继承配置信息
                StrategyConfigJson = this.StrategyConfigJson,
                IntegrationType = this.IntegrationType,
                
                // 继承发布状态相关信息
                PublishStatus = this.PublishStatus,
                PublishedTime = this.PublishedTime,
                PublishedByUserId = this.PublishedByUserId,
                PublishedByUserName = this.PublishedByUserName,
                PublishedByRealName = this.PublishedByRealName,
                PublishRemarks = this.PublishRemarks,
                
                // 初始化新版本的其他字段
                TaskIdsJson = "[]",
                PersonnelAllocationResultJson = "{}",
                EquipmentAllocationResultJson = "{}",
                FailureReasonStats = "{}",
                ChangeDetailsJson = "{}",
                SnapshotDataJson = "{}",
                DataVersion = this.DataVersion,
                AllowAutoReallocation = true,
                LastChangeCheckTime = DateTime.Now
            };
            
            // 当前版本标记为非活跃
            this.IsActiveVersion = false;
            
            return newVersion;
        }

        /// <summary>
        /// 获取变更详情
        /// 解析ChangeDetailsJson并返回结构化的变更详情
        /// </summary>
        public IntegrationChangeDetails GetChangeDetails()
        {
            try
            {
                if (string.IsNullOrWhiteSpace(ChangeDetailsJson) || ChangeDetailsJson == "{}")
                    return new IntegrationChangeDetails();

                return System.Text.Json.JsonSerializer.Deserialize<IntegrationChangeDetails>(ChangeDetailsJson) 
                       ?? new IntegrationChangeDetails();
            }
            catch
            {
                return new IntegrationChangeDetails();
            }
        }

        /// <summary>
        /// 设置变更详情
        /// 将变更详情对象序列化为JSON存储
        /// </summary>
        public void SetChangeDetails(IntegrationChangeDetails changeDetails)
        {
            ChangeDetailsJson = System.Text.Json.JsonSerializer.Serialize(changeDetails ?? new IntegrationChangeDetails());
        }

        /// <summary>
        /// 获取快照数据
        /// 解析SnapshotDataJson并返回快照数据对象
        /// </summary>
        public IntegrationSnapshot GetSnapshotData()
        {
            try
            {
                if (string.IsNullOrWhiteSpace(SnapshotDataJson) || SnapshotDataJson == "{}")
                    return new IntegrationSnapshot();

                return System.Text.Json.JsonSerializer.Deserialize<IntegrationSnapshot>(SnapshotDataJson) 
                       ?? new IntegrationSnapshot();
            }
            catch
            {
                return new IntegrationSnapshot();
            }
        }

        /// <summary>
        /// 设置快照数据
        /// 将快照数据对象序列化为JSON存储
        /// </summary>
        public void SetSnapshotData(IntegrationSnapshot snapshotData)
        {
            SnapshotDataJson = System.Text.Json.JsonSerializer.Serialize(snapshotData ?? new IntegrationSnapshot());
        }

        /// <summary>
        /// 计算变更影响评分
        /// 基于变更的任务数量、人员影响、设备影响等计算影响评分
        /// </summary>
        public int CalculateChangeImpactScore(IntegrationChangeDetails changeDetails)
        {
            if (changeDetails == null) return 0;

            int score = 0;
            int totalTasks = TotalTaskCount > 0 ? TotalTaskCount : 1;
            
            // 基于变更任务比例计算基础分数 (40%)
            var changedTaskRatio = (double)changeDetails.ChangedTaskIds.Count / totalTasks;
            score += (int)(changedTaskRatio * 40);
            
            // 基于人员变更数量计算分数 (30%)
            var personnelChangeRatio = Math.Min(1.0, (double)changeDetails.AffectedPersonnelIds.Count / 10);
            score += (int)(personnelChangeRatio * 30);
            
            // 基于设备变更数量计算分数 (20%)
            var equipmentChangeRatio = Math.Min(1.0, (double)changeDetails.AffectedEquipmentIds.Count / 10);
            score += (int)(equipmentChangeRatio * 20);
            
            // 基于变更类型的严重程度 (10%)
            var severityScore = changeDetails.ChangeTypes.Contains("TaskTimeConflict") ? 10 : 
                               changeDetails.ChangeTypes.Contains("PersonnelUnavailable") ? 8 :
                               changeDetails.ChangeTypes.Contains("EquipmentUnavailable") ? 6 : 2;
            score += severityScore;
            
            return Math.Min(100, Math.Max(0, score));
        }

        /// <summary>
        /// 检查是否需要重新分配
        /// 基于变更影响评分和业务规则判断是否需要重新分配
        /// </summary>
        public bool ShouldTriggerReallocation()
        {
            // 如果不允许自动重新分配，返回false
            if (!AllowAutoReallocation) return false;
            
            // 如果变更影响评分超过阈值，需要重新分配
            if (ChangeImpactScore >= 30) return true;
            
            // 如果有任务时间冲突，必须重新分配
            var changeDetails = GetChangeDetails();
            if (changeDetails.ChangeTypes.Contains("TaskTimeConflict")) return true;
            
            // 如果有关键人员不可用，需要重新分配
            if (changeDetails.ChangeTypes.Contains("PersonnelUnavailable")) return true;
            
            return false;
        }

        #endregion

        #endregion
    }

    /// <summary>
    /// 整合类型枚举
    /// </summary>
    public static class IntegrationType
    {
        /// <summary>
        /// 手动触发
        /// </summary>
        public const string Manual = "Manual";

        /// <summary>
        /// 定时触发
        /// </summary>
        public const string Scheduled = "Scheduled";

        /// <summary>
        /// 自动触发
        /// </summary>
        public const string Auto = "Auto";
    }

    /// <summary>
    /// 整合记录发布状态枚举
    /// 定义整合记录的生命周期状态
    /// </summary>
    public static class IntegrationRecordPublishStatus
    {
        /// <summary>
        /// 草稿状态 - 刚生成的整合记录，未正式生效
        /// </summary>
        public const string Draft = "Draft";

        /// <summary>
        /// 已发布状态 - 已发布生效，任务开始执行
        /// </summary>
        public const string Published = "Published";

        /// <summary>
        /// 已完成状态 - 所有任务执行完毕
        /// </summary>
        public const string Completed = "Completed";

        /// <summary>
        /// 已撤销状态 - 发布后被撤销
        /// </summary>
        public const string Cancelled = "Cancelled";
    }
}