/*
 * <copyright>
        Company="公司"
        2020-2025
        Author=JCH
        Path=XiaoZhiSharp.Utils.SystemMonitor.cs
 * <copyright>
 * --------------------------------------------------------------
 * 机器名称：JCH
 * 文件名：SystemMonitor.cs
 * 版本号：V1.0.0.0
 * 创建人：JCH
 * 创建时间：2025/9/27 9:33:01
 * 描述：
 * --------------------------------------------------------------
 * 修改时间：2025/9/27 9:33:01
 * 修改人：JCH
 * 版本号：V1.0.0.0
 * 描述：
 * --------------------------------------------------------------
 */

using LibreHardwareMonitor.Hardware;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace XiaoZhiSharp.Utils
{
    public class SystemMonitor : IDisposable
    {
        private Computer _computer;
        private readonly Dictionary<SensorType, List<ISensor>> _sensors;
        private bool _isMonitoring;
        private Task _monitoringTask;
        private CancellationTokenSource _cancellationTokenSource;

        public SystemMonitor()
        {
            _sensors = new Dictionary<SensorType, List<ISensor>>();
            InitializeComputer();
        }

        private void InitializeComputer()
        {
            _computer = new Computer
            {
                //IsCpuEnabled = true,
                IsGpuEnabled = true,
                //IsMemoryEnabled = true,
                //IsMotherboardEnabled = true,
                //IsControllerEnabled = true,
                //IsNetworkEnabled = true,
                //IsStorageEnabled = true
            };

            _computer.Open();
            _computer.Accept(new UpdateVisitor());
        }

        public HardwareInfo GetHardwareInfo()
        {
            UpdateAllSensors();

            return new HardwareInfo
            {
                //CpuUsage = GetCpuUsage(),
                GpuUsage = GetGpuUsage(),
                //MemoryUsage = GetMemoryUsage(),
                //DiskUsage = GetDiskUsage(),
                Timestamp = DateTime.Now
            };
        }

        private void UpdateAllSensors()
        {
            foreach (var hardware in _computer.Hardware)
            {
                hardware.Update();
            }
        }

        private float GetCpuUsage()
        {
            foreach (var hardware in _computer.Hardware)
            {
                if (hardware.HardwareType == HardwareType.Cpu)
                {
                    var loadSensor = hardware.Sensors
                        .FirstOrDefault(s => s.SensorType == SensorType.Load && s.Name.Contains("CPU Total"));

                    if (loadSensor != null && loadSensor.Value.HasValue)
                    {
                        return loadSensor.Value.Value;
                    }
                }
            }
            return 0;
        }

        private float GetGpuUsage()
        {
            // 检查NVIDIA GPU
            foreach (var hardware in _computer.Hardware)
            {
                if (hardware.HardwareType == HardwareType.GpuNvidia)
                {
                    var loadSensor = hardware.Sensors
                        .FirstOrDefault(s => s.SensorType == SensorType.Load);

                    if (loadSensor != null && loadSensor.Value.HasValue)
                    {
                        return loadSensor.Value.Value;
                    }
                }
            }

            // 检查AMD GPU
            foreach (var hardware in _computer.Hardware)
            {
                if (hardware.HardwareType == HardwareType.GpuAmd)
                {
                    var loadSensor = hardware.Sensors
                        .FirstOrDefault(s => s.SensorType == SensorType.Load);

                    if (loadSensor != null && loadSensor.Value.HasValue)
                    {
                        return loadSensor.Value.Value;
                    }
                }
            }

            // 检查Intel集成显卡
            foreach (var hardware in _computer.Hardware)
            {
                if (hardware.HardwareType == HardwareType.GpuIntel)
                {
                    var loadSensor = hardware.Sensors
                        .FirstOrDefault(s => s.SensorType == SensorType.Load);

                    if (loadSensor != null && loadSensor.Value.HasValue)
                    {
                        return loadSensor.Value.Value;
                    }
                }
            }

            return 0;
        }

        private MemoryInfo GetMemoryUsage()
        {
            foreach (var hardware in _computer.Hardware)
            {
                if (hardware.HardwareType == HardwareType.Memory)
                {
                    var memoryInfo = new MemoryInfo();

                    // 获取已使用内存
                    var usedMemorySensor = hardware.Sensors
                        .FirstOrDefault(s => s.SensorType == SensorType.Data && s.Name.Contains("Used"));

                    // 获取可用内存
                    var availableMemorySensor = hardware.Sensors
                        .FirstOrDefault(s => s.SensorType == SensorType.Data && s.Name.Contains("Available"));

                    if (usedMemorySensor != null && usedMemorySensor.Value.HasValue)
                    {
                        memoryInfo.UsedGB = usedMemorySensor.Value.Value / 1024; // 转换为GB
                    }

                    if (availableMemorySensor != null && availableMemorySensor.Value.HasValue)
                    {
                        memoryInfo.AvailableGB = availableMemorySensor.Value.Value / 1024;
                    }

                    memoryInfo.UsagePercentage = memoryInfo.TotalGB > 0 ?
                        (memoryInfo.UsedGB / memoryInfo.TotalGB) * 100 : 0;

                    return memoryInfo;
                }
            }
            return new MemoryInfo();
        }

        private DiskInfo GetDiskUsage()
        {
            var diskInfo = new DiskInfo();

            foreach (var hardware in _computer.Hardware)
            {
                if (hardware.HardwareType == HardwareType.Storage)
                {
                    // 获取磁盘负载
                    var loadSensor = hardware.Sensors
                        .FirstOrDefault(s => s.SensorType == SensorType.Load);

                    if (loadSensor != null && loadSensor.Value.HasValue)
                    {
                        diskInfo.LoadPercentage = loadSensor.Value.Value;
                    }

                    // 获取磁盘读写速度
                    var readRateSensor = hardware.Sensors
                        .FirstOrDefault(s => s.SensorType == SensorType.Throughput && s.Name.Contains("Read"));

                    var writeRateSensor = hardware.Sensors
                        .FirstOrDefault(s => s.SensorType == SensorType.Throughput && s.Name.Contains("Write"));

                    if (readRateSensor != null && readRateSensor.Value.HasValue)
                    {
                        diskInfo.ReadRateMBs = readRateSensor.Value.Value / 1024 / 1024;
                    }

                    if (writeRateSensor != null && writeRateSensor.Value.HasValue)
                    {
                        diskInfo.WriteRateMBs = writeRateSensor.Value.Value / 1024 / 1024;
                    }

                    break; // 只获取第一个存储设备的信息
                }
            }
            return diskInfo;
        }

        public void StartContinuousMonitoring(Action<HardwareInfo> updateCallback, int intervalMs = 1000)
        {
            if (_isMonitoring) return;

            _isMonitoring = true;
            _cancellationTokenSource = new CancellationTokenSource();

            _monitoringTask = Task.Run(async () =>
            {
                while (_isMonitoring && !_cancellationTokenSource.Token.IsCancellationRequested)
                {
                    var info = GetHardwareInfo();
                    updateCallback?.Invoke(info);

                    await Task.Delay(intervalMs, _cancellationTokenSource.Token);
                }
            });
        }

        public void StopContinuousMonitoring()
        {
            _isMonitoring = false;
            _cancellationTokenSource?.Cancel();
            _monitoringTask?.Wait(1000);
        }

        public void Dispose()
        {
            StopContinuousMonitoring();
            _computer?.Close();
        }
    }

    // 更新访问器类
    public class UpdateVisitor : IVisitor
    {
        public void VisitComputer(IComputer computer)
        {
            computer.Traverse(this);
        }

        public void VisitHardware(IHardware hardware)
        {
            hardware.Update();
            foreach (var subHardware in hardware.SubHardware)
            {
                subHardware.Accept(this);
            }
        }

        public void VisitSensor(ISensor sensor) { }

        public void VisitParameter(IParameter parameter) { }
    }

    // 数据模型类
    public class HardwareInfo
    {
        public float CpuUsage { get; set; } // CPU使用率百分比
        public float GpuUsage { get; set; } // GPU使用率百分比
        public MemoryInfo MemoryUsage { get; set; } // 内存使用信息
        public DiskInfo DiskUsage { get; set; } // 磁盘使用信息
        public DateTime Timestamp { get; set; }
    }

    public class MemoryInfo
    {
        public float UsedGB { get; set; }
        public float AvailableGB { get; set; }
        public float TotalGB => UsedGB + AvailableGB;
        public float UsagePercentage { get; set; }
    }

    public class DiskInfo
    {
        public float LoadPercentage { get; set; } // 磁盘负载百分比
        public float ReadRateMBs { get; set; } // 读取速度 MB/s
        public float WriteRateMBs { get; set; } // 写入速度 MB/s
    }
}
