using IpcLibrary.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IpcLibrary.Server {
    /// <summary>
    /// 服务器状态监控器
    /// </summary>
    public class ServerMonitor : IDisposable {
        private readonly IPCServer _server;
        private readonly System.Timers.Timer _monitorTimer;
        private readonly Dictionary<string, DateTime> _processLastSeen;
        private bool _disposed;

        public event EventHandler<ServerStatistics> StatisticsUpdated;

        public ServerMonitor(IPCServer server, TimeSpan monitorInterval) {
            _server = server ?? throw new ArgumentNullException(nameof(server));
            _processLastSeen = new Dictionary<string, DateTime>();

            _monitorTimer = new System.Timers.Timer(monitorInterval.TotalMilliseconds);
            _monitorTimer.Elapsed += OnMonitorTimer;
            _monitorTimer.Start();

            _server.ProcessConnected += OnProcessConnected;
            _server.ProcessDisconnected += OnProcessDisconnected;
        }

        private void OnProcessConnected(object sender, ProcessInfo processInfo) {
            lock (_processLastSeen) {
                _processLastSeen[processInfo.ProcessId] = DateTime.UtcNow;
            }
        }

        private void OnProcessDisconnected(object sender, ProcessInfo processInfo) {
            lock (_processLastSeen) {
                _processLastSeen.Remove(processInfo.ProcessId);
            }
        }

        private void OnMonitorTimer(object sender, System.Timers.ElapsedEventArgs e) {
            try {
                var statistics = GatherStatistics();
                StatisticsUpdated?.Invoke(this, statistics);
            } catch (Exception ex) {
                Console.WriteLine($"收集统计信息时发生错误: {ex.Message}");
            }
        }

        private ServerStatistics GatherStatistics() {
            var connectedProcesses = _server.ConnectedProcesses;
            var now = DateTime.UtcNow;

            return new ServerStatistics {
                Timestamp = now,
                TotalConnectedProcesses = connectedProcesses.Count,
                OnlineProcesses = connectedProcesses.Count(p => p.Status == ProcessStatus.Connected),
                DisconnectedProcesses = connectedProcesses.Count(p => p.Status == ProcessStatus.Disconnected),
                ReconnectingProcesses = connectedProcesses.Count(p => p.Status == ProcessStatus.Reconnecting),
                AverageHeartbeatDelay = CalculateAverageHeartbeatDelay(connectedProcesses, now),
                ServerUptime = now - _server.StartTime // 需要在IPCServer中添加StartTime属性
            };
        }

        private TimeSpan CalculateAverageHeartbeatDelay(IReadOnlyList<ProcessInfo> processes, DateTime now) {
            var delays = processes
                .Where(p => p.Status == ProcessStatus.Connected)
                .Select(p => now - p.LastHeartbeat)
                .Where(delay => delay.TotalSeconds >= 0);

            if (!delays.Any())
                return TimeSpan.Zero;

            var averageTicks = delays.Select(d => d.Ticks).Average();
            return new TimeSpan((long)averageTicks);
        }

        public void Dispose() {
            if (_disposed)
                return;

            _disposed = true;
            _monitorTimer?.Stop();
            _monitorTimer?.Dispose();
        }
    }
}
