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

namespace NPP.SmartSchedue.Api.Contracts.Domain.Integration
{
    /// <summary>
    /// 任务变更事件实体
    /// 记录任务变更事件，用于变更感知和自动触发机制
    /// 
    /// 业务思考：
    /// 1. 事件驱动架构：基于事件的变更检测和处理机制
    /// 2. 变更溯源：完整记录变更的前因后果和处理过程
    /// 3. 批量处理：支持批量变更事件的聚合处理
    /// 4. 性能优化：通过事件队列机制避免实时处理对系统性能的影响
    /// </summary>
    [Table(Name = "sse_task_change_event")]
    [Index("idx_task_id", "TaskId")] // 任务ID索引
    [Index("idx_integration_record", "IntegrationRecordId")] // 整合记录索引
    [Index("idx_event_time", "EventTime")] // 事件时间索引
    [Index("idx_processing_status", "ProcessingStatus")] // 处理状态索引
    [Index("idx_tenant_time", "TenantId,EventTime")] // 租户+时间组合索引
    public class TaskChangeEventEntity : EntityTenant
    {
        /// <summary>
        /// 任务ID
        /// 发生变更的任务ID
        /// </summary>
        [Required]
        public long TaskId { get; set; }

        /// <summary>
        /// 任务代码
        /// 冗余存储，提高查询性能
        /// </summary>
        [Column(StringLength = 50)]
        [Required]
        public string TaskCode { get; set; } = string.Empty;

        /// <summary>
        /// 关联的整合记录ID
        /// 指向受影响的整合记录
        /// </summary>
        public long? IntegrationRecordId { get; set; }

        /// <summary>
        /// 根版本整合记录ID
        /// 指向版本链的根节点，用于快速定位整个版本链
        /// </summary>
        public long? RootIntegrationRecordId { get; set; }

        /// <summary>
        /// 事件类型
        /// TaskModified, TaskDeleted, TaskStatusChanged, TaskPriorityChanged, 
        /// TaskTimeChanged, TaskPersonnelChanged, TaskEquipmentChanged, TaskCompleted
        /// </summary>
        [Column(StringLength = 50)]
        [Required]
        public string EventType { get; set; } = string.Empty;

        /// <summary>
        /// 变更字段名称
        /// 具体发生变更的字段名，多个字段用逗号分隔
        /// </summary>
        [Column(StringLength = 200)]
        public string ChangedFields { get; set; } = string.Empty;

        /// <summary>
        /// 变更前的值（JSON格式）
        /// 存储变更前的字段值快照
        /// </summary>
        [Column(DbType = "json")]
        public string BeforeValueJson { get; set; } = "{}";

        /// <summary>
        /// 变更后的值（JSON格式）
        /// 存储变更后的字段值快照
        /// </summary>
        [Column(DbType = "json")]
        public string AfterValueJson { get; set; } = "{}";

        /// <summary>
        /// 事件发生时间
        /// 任务实际发生变更的时间
        /// </summary>
        [Required]
        public DateTime EventTime { get; set; } = DateTime.Now;

        /// <summary>
        /// 变更触发用户ID
        /// 执行变更操作的用户ID
        /// </summary>
        public long? TriggeredByUserId { get; set; }

        /// <summary>
        /// 变更触发用户名
        /// </summary>
        [Column(StringLength = 50)]
        public string TriggeredByUserName { get; set; } = string.Empty;

        /// <summary>
        /// 变更触发用户真实姓名
        /// </summary>
        [Column(StringLength = 50)]
        public string TriggeredByRealName { get; set; } = string.Empty;

        /// <summary>
        /// 事件来源
        /// Manual-手动操作, System-系统自动, Import-数据导入, API-API调用, Sync-同步操作
        /// </summary>
        [Column(StringLength = 20)]
        [Required]
        public string EventSource { get; set; } = "Manual";

        /// <summary>
        /// 事件优先级
        /// 1-9，9为最高优先级，影响处理顺序
        /// </summary>
        [Required]
        public int EventPriority { get; set; } = 5;

        /// <summary>
        /// 影响评估评分
        /// 0-100分，评估该变更对整合记录的潜在影响
        /// </summary>
        public int ImpactAssessmentScore { get; set; } = 0;

        /// <summary>
        /// 处理状态
        /// Pending-待处理, Processing-处理中, Completed-已完成, Failed-处理失败, Ignored-已忽略
        /// </summary>
        [Column(StringLength = 20)]
        [Required]
        public string ProcessingStatus { get; set; } = "Pending";

        /// <summary>
        /// 处理开始时间
        /// </summary>
        public DateTime? ProcessingStartTime { get; set; }

        /// <summary>
        /// 处理完成时间
        /// </summary>
        public DateTime? ProcessingCompletedTime { get; set; }

        /// <summary>
        /// 处理人员用户ID
        /// 实际处理该事件的用户ID
        /// </summary>
        public long? ProcessedByUserId { get; set; }

        /// <summary>
        /// 处理人员用户名
        /// </summary>
        [Column(StringLength = 50)]
        public string ProcessedByUserName { get; set; } = string.Empty;

        /// <summary>
        /// 处理结果摘要
        /// 简述处理结果和采取的行动
        /// </summary>
        [Column(StringLength = 500)]
        public string ProcessingResultSummary { get; set; } = string.Empty;

        /// <summary>
        /// 处理详情JSON
        /// 存储详细的处理过程和结果信息
        /// </summary>
        [Column(DbType = "json")]
        public string ProcessingDetailsJson { get; set; } = "{}";

        /// <summary>
        /// 是否触发了重新分配
        /// </summary>
        [Required]
        public bool TriggeredReallocation { get; set; } = false;

        /// <summary>
        /// 创建的新版本ID
        /// 如果该事件导致创建了新版本
        /// </summary>
        public long? CreatedNewVersionId { get; set; }

        /// <summary>
        /// 事件分组ID
        /// 用于将相关的多个事件分组处理，如批量修改
        /// </summary>
        public long? EventGroupId { get; set; }

        /// <summary>
        /// 事件分组序号
        /// 在同一分组内的事件序号
        /// </summary>
        public int EventGroupSequence { get; set; } = 1;

        /// <summary>
        /// 是否需要通知
        /// 标记该事件是否需要发送通知给相关人员
        /// </summary>
        [Required]
        public bool RequiresNotification { get; set; } = true;

        /// <summary>
        /// 通知状态
        /// NotSent-未发送, Sent-已发送, Failed-发送失败, NotRequired-无需发送
        /// </summary>
        [Column(StringLength = 20)]
        [Required]
        public string NotificationStatus { get; set; } = "NotSent";

        /// <summary>
        /// 通知发送时间
        /// </summary>
        public DateTime? NotificationSentTime { get; set; }

        /// <summary>
        /// 重试次数
        /// 处理失败后的重试次数
        /// </summary>
        [Required]
        public int RetryCount { get; set; } = 0;

        /// <summary>
        /// 最大重试次数
        /// </summary>
        [Required]
        public int MaxRetryCount { get; set; } = 3;

        /// <summary>
        /// 下次重试时间
        /// </summary>
        public DateTime? NextRetryTime { get; set; }

        /// <summary>
        /// 错误信息
        /// 记录处理过程中的错误信息
        /// </summary>
        [Column(StringLength = 1000)]
        public string ErrorMessage { get; set; } = string.Empty;

        /// <summary>
        /// 事件标签
        /// 用于事件分类和筛选，多个标签用逗号分隔
        /// </summary>
        [Column(StringLength = 200)]
        public string EventTags { get; set; } = string.Empty;

        /// <summary>
        /// 业务备注
        /// </summary>
        [Column(StringLength = 500)]
        public string Remarks { get; set; } = string.Empty;

        /// <summary>
        /// 是否为测试事件
        /// </summary>
        [Required]
        public bool IsTestEvent { get; set; } = false;

        /// <summary>
        /// 数据版本
        /// </summary>
        [Required]
        public int DataVersion { get; set; } = 1;

        #region 计算属性

        /// <summary>
        /// 处理耗时（毫秒）
        /// </summary>
        [Navigate(nameof(ProcessingStartTime))]
        public long ProcessingElapsedMilliseconds
        {
            get
            {
                if (ProcessingStartTime.HasValue && ProcessingCompletedTime.HasValue)
                {
                    return (long)(ProcessingCompletedTime.Value - ProcessingStartTime.Value).TotalMilliseconds;
                }
                return 0;
            }
            set { } // FreeSql需要set访问器，但这是计算属性，所以提供空实现
        }

        /// <summary>
        /// 事件年龄（自事件发生到现在的分钟数）
        /// </summary>
        [Navigate(nameof(EventTime))]
        public int EventAgeMinutes
        {
            get
            {
                return (int)(DateTime.Now - EventTime).TotalMinutes;
            }
            set { } // FreeSql需要set访问器，但这是计算属性，所以提供空实现
        }

        /// <summary>
        /// 是否超时
        /// 判断事件是否长时间未处理
        /// </summary>
        [Navigate(nameof(EventTime))]
        public bool IsOverdue
        {
            get
            {
                if (ProcessingStatus == "Completed" || ProcessingStatus == "Ignored")
                    return false;
                
                var timeoutMinutes = EventPriority >= 8 ? 30 : EventPriority >= 5 ? 120 : 480; // 高优先级30分钟，中等2小时，低优先级8小时
                return EventAgeMinutes > timeoutMinutes;
            }
            set { } // FreeSql需要set访问器，但这是计算属性，所以提供空实现
        }

        #endregion

        #region 业务方法

        /// <summary>
        /// 获取变更前的值
        /// 将JSON反序列化为字典
        /// </summary>
        public Dictionary<string, object> GetBeforeValues()
        {
            try
            {
                if (string.IsNullOrWhiteSpace(BeforeValueJson) || BeforeValueJson == "{}")
                    return new Dictionary<string, object>();

                return System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(BeforeValueJson) 
                       ?? new Dictionary<string, object>();
            }
            catch
            {
                return new Dictionary<string, object>();
            }
        }

        /// <summary>
        /// 获取变更后的值
        /// 将JSON反序列化为字典
        /// </summary>
        public Dictionary<string, object> GetAfterValues()
        {
            try
            {
                if (string.IsNullOrWhiteSpace(AfterValueJson) || AfterValueJson == "{}")
                    return new Dictionary<string, object>();

                return System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(AfterValueJson) 
                       ?? new Dictionary<string, object>();
            }
            catch
            {
                return new Dictionary<string, object>();
            }
        }

        /// <summary>
        /// 设置变更前的值
        /// </summary>
        public void SetBeforeValues(Dictionary<string, object> values)
        {
            BeforeValueJson = System.Text.Json.JsonSerializer.Serialize(values ?? new Dictionary<string, object>());
        }

        /// <summary>
        /// 设置变更后的值
        /// </summary>
        public void SetAfterValues(Dictionary<string, object> values)
        {
            AfterValueJson = System.Text.Json.JsonSerializer.Serialize(values ?? new Dictionary<string, object>());
        }

        /// <summary>
        /// 获取处理详情
        /// </summary>
        public Dictionary<string, object> GetProcessingDetails()
        {
            try
            {
                if (string.IsNullOrWhiteSpace(ProcessingDetailsJson) || ProcessingDetailsJson == "{}")
                    return new Dictionary<string, object>();

                return System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(ProcessingDetailsJson) 
                       ?? new Dictionary<string, object>();
            }
            catch
            {
                return new Dictionary<string, object>();
            }
        }

        /// <summary>
        /// 设置处理详情
        /// </summary>
        public void SetProcessingDetails(Dictionary<string, object> details)
        {
            ProcessingDetailsJson = System.Text.Json.JsonSerializer.Serialize(details ?? new Dictionary<string, object>());
        }

        /// <summary>
        /// 开始处理事件
        /// 设置处理开始时间和状态
        /// </summary>
        public void StartProcessing(long processedByUserId, string processedByUserName)
        {
            ProcessingStatus = "Processing";
            ProcessingStartTime = DateTime.Now;
            ProcessedByUserId = processedByUserId;
            ProcessedByUserName = processedByUserName;
        }

        /// <summary>
        /// 完成处理事件
        /// 设置处理完成时间和状态
        /// </summary>
        public void CompleteProcessing(string resultSummary, bool triggeredReallocation = false, long? createdVersionId = null)
        {
            ProcessingStatus = "Completed";
            ProcessingCompletedTime = DateTime.Now;
            ProcessingResultSummary = resultSummary;
            TriggeredReallocation = triggeredReallocation;
            CreatedNewVersionId = createdVersionId;
        }

        /// <summary>
        /// 处理失败
        /// 设置失败状态和错误信息
        /// </summary>
        public void FailProcessing(string errorMessage)
        {
            ProcessingStatus = "Failed";
            ProcessingCompletedTime = DateTime.Now;
            ErrorMessage = errorMessage;
            RetryCount++;
            
            // 计算下次重试时间（指数退避）
            if (RetryCount <= MaxRetryCount)
            {
                var delayMinutes = Math.Pow(2, RetryCount) * 5; // 5, 10, 20 分钟
                NextRetryTime = DateTime.Now.AddMinutes(delayMinutes);
                ProcessingStatus = "Pending"; // 重置为待处理状态以便重试
            }
        }

        /// <summary>
        /// 忽略事件
        /// 设置忽略状态，不再处理
        /// </summary>
        public void IgnoreEvent(string reason)
        {
            ProcessingStatus = "Ignored";
            ProcessingCompletedTime = DateTime.Now;
            ProcessingResultSummary = $"事件已忽略: {reason}";
        }

        /// <summary>
        /// 判断是否可以重试
        /// </summary>
        public bool CanRetry()
        {
            return ProcessingStatus == "Pending" && 
                   RetryCount < MaxRetryCount && 
                   (!NextRetryTime.HasValue || NextRetryTime.Value <= DateTime.Now);
        }

        /// <summary>
        /// 计算影响评估评分
        /// 基于变更类型、字段和业务规则计算影响评分
        /// </summary>
        public int CalculateImpactScore()
        {
            int score = 0;
            
            // 基于事件类型的基础分数
            score += EventType switch
            {
                "TaskDeleted" => 90,
                "TaskStatusChanged" => 80,
                "TaskTimeChanged" => 70,
                "TaskPriorityChanged" => 60,
                "TaskPersonnelChanged" => 75,
                "TaskEquipmentChanged" => 75,
                "TaskModified" => 50,
                "TaskCompleted" => 30,
                _ => 20
            };
            
            // 基于变更字段的影响调整
            if (ChangedFields.Contains("WorkOrderDate")) score += 20;
            if (ChangedFields.Contains("ShiftId")) score += 15;
            if (ChangedFields.Contains("Priority")) score += 10;
            if (ChangedFields.Contains("AssignedPersonnelId")) score += 15;
            if (ChangedFields.Contains("AssignedEquipmentId")) score += 15;
            if (ChangedFields.Contains("Status")) score += 25;
            
            // 基于事件优先级调整
            score += EventPriority * 2;
            
            return Math.Min(100, Math.Max(0, score));
        }

        #endregion
    }

    /// <summary>
    /// 事件处理状态枚举
    /// </summary>
    public static class TaskChangeEventProcessingStatus
    {
        /// <summary>
        /// 待处理
        /// </summary>
        public const string Pending = "Pending";

        /// <summary>
        /// 处理中
        /// </summary>
        public const string Processing = "Processing";

        /// <summary>
        /// 已完成
        /// </summary>
        public const string Completed = "Completed";

        /// <summary>
        /// 处理失败
        /// </summary>
        public const string Failed = "Failed";

        /// <summary>
        /// 已忽略
        /// </summary>
        public const string Ignored = "Ignored";
    }

    /// <summary>
    /// 事件类型枚举
    /// </summary>
    public static class TaskChangeEventType
    {
        /// <summary>
        /// 任务修改
        /// </summary>
        public const string TaskModified = "TaskModified";

        /// <summary>
        /// 任务删除
        /// </summary>
        public const string TaskDeleted = "TaskDeleted";

        /// <summary>
        /// 任务状态变更
        /// </summary>
        public const string TaskStatusChanged = "TaskStatusChanged";

        /// <summary>
        /// 任务优先级变更
        /// </summary>
        public const string TaskPriorityChanged = "TaskPriorityChanged";

        /// <summary>
        /// 任务时间变更
        /// </summary>
        public const string TaskTimeChanged = "TaskTimeChanged";

        /// <summary>
        /// 任务人员变更
        /// </summary>
        public const string TaskPersonnelChanged = "TaskPersonnelChanged";

        /// <summary>
        /// 任务设备变更
        /// </summary>
        public const string TaskEquipmentChanged = "TaskEquipmentChanged";

        /// <summary>
        /// 任务完成
        /// </summary>
        public const string TaskCompleted = "TaskCompleted";
    }
}