using ScottPlot;
using SWRIS.Enums;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Windows;

namespace SWRIS.Models
{
    public class EquipmentDataModel : INotifyPropertyChanged
    {
        private int ropeNumber;
        private string ropeName;
        private string ipAddress;
        private string serialNo;
        private bool isConnect = false;
        private int sensorCount = 4;
        private double liftHightRatio = 1;
        private double ropeLength = 100f; // 默认长度为100米
        private RunningStatus runningStatus = RunningStatus.Stopped;
        private DirectionState direction;
        private FaultType? faultType;
        private double speed;
        private double position;
        private double absolutePosition;
        private double liftHeight;
        private double maxDamageValue;
        private double avgDamageValue;
        private int damageCount;
        private int mildCount;
        private int lightCount;
        private int moderateCount;
        private int severeCount;
        private int criticalCount;
        private int extremeCount;
        private DetectionDataModel detectionData;
        private RiskLevel riskLevel = RiskLevel.Normal;
        private Socket clientSocket;
        private double samplingStep;
        private DebugMessageModel debugMessage = new DebugMessageModel(string.Empty);
        private bool isAlerting = false;
        private bool isSpeedStable = true;
        private double variationThreshold = 0.25;
        private bool isHeartbeatReceived;
        private uint detectionNo;
        private bool disableAlarm;
        private int[] inUseSensor = new int[] { 1, 2, 3, 4 };
        /// <summary>
        /// 钢丝绳绳号
        /// </summary>
        public int RopeNumber
        {
            get => ropeNumber;
            set { ropeNumber = value; OnPropertyChanged(nameof(RopeNumber)); }
        }
        /// <summary>
        /// 钢丝绳名称
        /// </summary>
        public string RopeName
        {
            get => ropeName;
            set { ropeName = value; OnPropertyChanged(nameof(RopeName)); }
        }
        /// <summary>
        /// 设备Ip地址
        /// </summary>
        public string IpAddress
        {
            get => ipAddress;
            set { ipAddress = value; OnPropertyChanged(nameof(IpAddress)); }
        }
        /// <summary>
        /// 设备序列号
        /// </summary>
        public string SerialNo
        {
            get => serialNo;
            set { serialNo = value; OnPropertyChanged(nameof(SerialNo)); }
        }
        /// <summary>
        /// 连接状态
        /// </summary>
        public bool IsConnect
        {
            get => isConnect;
            set { isConnect = value; OnPropertyChanged(nameof(IsConnect)); }
        }
        /// <summary>
        /// 传感器数量
        /// </summary>
        public int SensorCount
        {
            get => sensorCount;
            set { sensorCount = value; OnPropertyChanged(nameof(SensorCount)); }
        }
        /// <summary>
        /// 钢丝绳绳长
        /// </summary>
        public double RopeLength
        {
            get => ropeLength;
            set { ropeLength = value; OnPropertyChanged(nameof(RopeLength)); }
        }
        public double LiftHightRatio
        {
            get => liftHightRatio;
            set { liftHightRatio = value; OnPropertyChanged(nameof(LiftHightRatio)); }
        }
        /// <summary>
        /// 采样步长
        /// </summary>
        public double SamplingStep
        {
            get => samplingStep;
            set { samplingStep = value; OnPropertyChanged(nameof(SamplingStep)); }
        }
        /// <summary>
        /// 运行状态
        /// </summary>
        public RunningStatus RunningStatus
        {
            get => runningStatus;
            set { runningStatus = value; OnPropertyChanged(nameof(RunningStatus)); }
        }
        /// <summary>
        /// 运行方向
        /// </summary>
        public DirectionState Direction
        {
            get => direction;
            set { direction = value; OnPropertyChanged(nameof(Direction)); }
        }
        /// <summary>
        /// 故障类型
        /// </summary>
        public FaultType? FaultType
        {
            get => faultType;
            set { faultType = value; OnPropertyChanged(nameof(FaultType)); }
        }

        /// <summary>
        /// 速度
        /// </summary>
        public double Speed
        {
            get => speed;
            set { speed = value; OnPropertyChanged(nameof(Speed)); }
        }
        /// <summary>
        /// 速度变化率阈值
        /// </summary>
        public double VariationThreshold
        {
            get => variationThreshold;
            set { variationThreshold = value; OnPropertyChanged(nameof(VariationThreshold)); }
        }
        /// <summary>
        /// 速度是否稳定
        /// </summary>
        public bool IsSpeedStable
        {
            get => isSpeedStable;
            set { isSpeedStable = value; OnPropertyChanged(nameof(IsSpeedStable)); }
        }
        /// <summary>
        /// 位置
        /// </summary>
        public double Position
        {
            get => position;
            set { position = value; OnPropertyChanged(nameof(Position)); }
        }
        /// <summary>
        /// 绝对位置
        /// </summary>
        public double AbsolutePosition
        {
            get => absolutePosition;
            set { absolutePosition = value; OnPropertyChanged(nameof(AbsolutePosition)); }
        }
        /// <summary>
        /// 起升高度
        /// </summary>
        public double LiftHeight
        {
            get => liftHeight;
            set { liftHeight = value; OnPropertyChanged(nameof(LiftHeight)); }
        }
        /// <summary>
        /// 健康程度
        /// </summary>
        public RiskLevel RiskLevel
        {
            get => riskLevel;
            set { riskLevel = value; OnPropertyChanged(nameof(RiskLevel)); }
        }
        /// <summary>
        /// 平均损伤值
        /// </summary>
        public double AvgDamageValue
        {
            get => avgDamageValue;
            set { avgDamageValue = value; OnPropertyChanged(nameof(AvgDamageValue)); }
        }
        /// <summary>
        /// 最大损伤值
        /// </summary>
        public double MaxDamageValue
        {
            get => maxDamageValue;
            set { maxDamageValue = value; OnPropertyChanged(nameof(MaxDamageValue)); }
        }
        /// <summary>
        /// 损伤报警数量
        /// </summary>
        public int DamageCount
        {
            get => damageCount;
            set { damageCount = value; OnPropertyChanged(nameof(DamageCount)); }
        }
        /// <summary>
        /// 轻微损伤数量
        /// </summary>
        public int MildCount
        {
            get => mildCount;
            set { mildCount = value; OnPropertyChanged(nameof(MildCount)); }
        }
        /// <summary>
        /// 轻度损伤数量
        /// </summary>
        public int LightCount
        {
            get => lightCount;
            set { lightCount = value; OnPropertyChanged(nameof(LightCount)); }
        }
        /// <summary>
        /// 中度损伤数量
        /// </summary>
        public int ModerateCount
        {
            get => moderateCount;
            set { moderateCount = value; OnPropertyChanged(nameof(ModerateCount)); }
        }
        /// <summary>
        /// 较重损伤数量
        /// </summary>
        public int SevereCount
        {
            get => severeCount;
            set { severeCount = value; OnPropertyChanged(nameof(SevereCount)); }
        }
        /// <summary>
        /// 严重损伤数量
        /// </summary>
        public int CriticalCount
        {
            get => criticalCount;
            set { criticalCount = value; OnPropertyChanged(nameof(CriticalCount)); }
        }
        /// <summary>
        /// 超限损伤数量
        /// </summary>
        public int ExtremeCount
        {
            get => extremeCount;
            set { extremeCount = value; OnPropertyChanged(nameof(ExtremeCount)); }
        }
        /// <summary>
        /// 最后一次的检测数据
        /// </summary>
        public DetectionDataModel DetectionData
        {
            get => detectionData;
            set { detectionData = value; OnPropertyChanged(nameof(DetectionData)); }
        }
        /// <summary>
        /// 调试信息
        /// </summary>
        public DebugMessageModel DebugMessage
        {
            get => debugMessage;
            set { debugMessage = value; OnPropertyChanged(nameof(DebugMessage)); }
        }
        /// <summary>
        /// TCP 客户端
        /// </summary>
        public Socket ClientSocket
        {
            get => clientSocket;
            set { clientSocket = value; OnPropertyChanged(nameof(ClientSocket)); }
        }
        /// <summary>
        /// 是否报警中
        /// </summary>
        public bool IsAlerting
        {
            get => isAlerting;
            set { isAlerting = value; OnPropertyChanged(nameof(IsAlerting)); }
        }
        public bool IsHeartbeatReceived
        {
            get => isHeartbeatReceived;
            set
            {
                isHeartbeatReceived = value;
                OnPropertyChanged(nameof(IsHeartbeatReceived));

                if (value)
                {
                    // 延迟一段时间后重置，以便动画可以重复触发
                    Task.Delay(600).ContinueWith(_ =>
                    {
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            IsHeartbeatReceived = false;
                        });
                    });
                }
            }
        }
        /// <summary>
        /// 检测编号
        /// </summary>
        public uint DetectionNo
        {
            get => detectionNo;
            set { detectionNo = value; OnPropertyChanged(nameof(DetectionNo)); }
        }
        /// <summary>
        /// 禁用报警
        /// </summary>
        public bool DisableAlarm
        {
            get => disableAlarm;
            set { disableAlarm = value; OnPropertyChanged(nameof(DisableAlarm)); }
        }
        /// <summary>
        /// 在用传感器
        /// </summary>
        public int[] InUseSensor
        {
            get => inUseSensor;
            set { inUseSensor = value; OnPropertyChanged(nameof(InUseSensor)); }
        }
        public ObservableCollection<AlarmDataModel> Alarms { get; set; } = new ObservableCollection<AlarmDataModel>();
        public ObservableCollection<FaultDataModel> Faults { get; set; } = new ObservableCollection<FaultDataModel>();
        public ObservableCollection<LimitModel> Limits { get; set; } = new ObservableCollection<LimitModel>();
        public ObservableCollection<string> Messages { get; set; } = new ObservableCollection<string>();
        public Coordinates[] ChartSource { get; internal set; }
        public Queue<double> RecentSpeeds { get; internal set; } = new Queue<double>();
        public void AddSpeedData(double speed)
        {
            // 更新数据窗口
            RecentSpeeds.Enqueue(speed);
            if (RecentSpeeds.Count > 3)
                RecentSpeeds.Dequeue();

            if (RecentSpeeds.Count < 2)
                return;

            double avgSpeed = RecentSpeeds.Average();
            if (avgSpeed == 0)
            {
                IsSpeedStable = true;
                return;
            }
            // 计算当前速度相对于平均值的偏差
            bool _isStable = (Math.Abs(speed - avgSpeed) / avgSpeed) <= VariationThreshold;
            if (IsSpeedStable != _isStable)
            {
                IsSpeedStable = _isStable;
            }
        }
        public void AddAlarm(AlarmDataModel alarm)
        {
            DamageCount++;
            MaxDamageValue = alarm.DamageValue > MaxDamageValue ? alarm.DamageValue : MaxDamageValue;
            AvgDamageValue = (AvgDamageValue * (DamageCount - 1) + alarm.DamageValue) / DamageCount;

            switch (alarm.DamageLevel)
            {
                case DamageLevel.Mild:
                    MildCount++;
                    break;
                case DamageLevel.Light:
                    LightCount++;
                    break;
                case DamageLevel.Moderate:
                    ModerateCount++;
                    break;
                case DamageLevel.Severe:
                    SevereCount++;
                    break;
                case DamageLevel.Critical:
                    CriticalCount++;
                    break;
                case DamageLevel.ExceededLimit:
                    ExtremeCount++;
                    break;
            }
            Alarms.Add(alarm);
            RiskLevel = Alarms.Any() ? (RiskLevel)Alarms.Max(c => (int)c.DamageLevel) : RiskLevel.Normal;

            IsAlerting = true;
            Task.Run(() =>
            {
                Task.Delay(3000).Wait();
                IsAlerting = false;
            });
        }

        public void ClearData()
        {
            Speed = 0;
            MaxDamageValue = 0;
            AvgDamageValue = 0;
            DamageCount = 0;
            MildCount = 0;
            LightCount = 0;
            ModerateCount = 0;
            SevereCount = 0;
            CriticalCount = 0;
            ExtremeCount = 0;
            ChartSource = null;
            RiskLevel = RiskLevel.Normal;
            DetectionNo += 1;
            Application.Current.Dispatcher.Invoke(() => Alarms.Clear());
            Task.Run(async () =>
            {
                // 持续监控直到条件满足
                while (DetectionData?.RawDataReceiving == true)
                {
                    await Task.Delay(100); // 避免CPU占用过高
                }
                // 条件满足时执行
                DetectionData = null;
            });
        }
        public event PropertyChangedEventHandler PropertyChanged;
        protected internal virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
