using System;
using System.Collections.Generic;

namespace CncSimulator.Core
{
    /// <summary>日志条目</summary>
    public class LogEntry
    {
        /// <summary>时间戳</summary>
        public DateTime Timestamp { get; set; }

        /// <summary>地址端口</summary>
        public int AddressPort { get; set; }

        /// <summary>设备数量</summary>
        public int DeviceCount { get; set; }

        /// <summary>关键数据摘要</summary>
        public string KeyData { get; set; }

        /// <summary>完整JSON</summary>
        public string FullJson { get; set; }

        /// <summary>响应耗时（毫秒）</summary>
        public long Duration { get; set; }
    }

    /// <summary>异常记录条目</summary>
    public class ErrorRecord
    {
        /// <summary>时间戳</summary>
        public DateTime Timestamp { get; set; }
        /// <summary>异常类型: http500, timeout, empty, malformed, refuse</summary>
        public string ErrorType { get; set; }
        /// <summary>异常描述</summary>
        public string Description { get; set; }
        /// <summary>影响设备数</summary>
        public int AffectedDevices { get; set; }
    }

    /// <summary>
    /// 日志记录器。同时写入内存环形缓冲和log4net文件。
    /// </summary>
    public class LogRecorder
    {
        private readonly int _capacity;
        private readonly LogEntry[] _buffer;
        private int _writeIndex;
        private int _count;
        private readonly object _lock = new object();
        private readonly log4net.ILog _log;

        // 异常记录列表（独立于请求日志）
        private readonly List<ErrorRecord> _errors = new List<ErrorRecord>();
        private readonly object _errorLock = new object();

        public LogRecorder(int capacity = 200)
        {
            _capacity = capacity;
            _buffer = new LogEntry[capacity];
            _writeIndex = 0;
            _count = 0;
            _log = log4net.LogManager.GetLogger(typeof(LogRecorder));
        }

        /// <summary>记录一次返回</summary>
        public void Record(int addressPort, int deviceCount, string keyData, string fullJson, long durationMs)
        {
            var entry = new LogEntry
            {
                Timestamp = DateTime.Now,
                AddressPort = addressPort,
                DeviceCount = deviceCount,
                KeyData = keyData,
                FullJson = fullJson,
                Duration = durationMs
            };

            lock (_lock)
            {
                _buffer[_writeIndex] = entry;
                _writeIndex = (_writeIndex + 1) % _capacity;
                if (_count < _capacity) _count++;
            }

            // 写文件日志
            _log.Info($"[{addressPort}] 返回{deviceCount}台设备, 耗时{durationMs}ms");
            _log.Info($"[{addressPort}] 关键数据: {keyData}");
        }

        /// <summary>记录一次异常</summary>
        public void RecordError(string errorType, string description, int affectedDevices)
        {
            var record = new ErrorRecord
            {
                Timestamp = DateTime.Now,
                ErrorType = errorType,
                Description = description,
                AffectedDevices = affectedDevices
            };
            lock (_errorLock)
            {
                _errors.Add(record);
                // 限制数量
                if (_errors.Count > 1000) _errors.RemoveAt(0);
            }
            _log.Warn($"[异常] 类型={errorType}, 影响{affectedDevices}台设备: {description}");
        }

        /// <summary>获取所有异常记录</summary>
        public List<ErrorRecord> GetErrors()
        {
            lock (_errorLock)
            {
                return new List<ErrorRecord>(_errors);
            }
        }

        /// <summary>获取异常次数统计</summary>
        public int GetErrorCount()
        {
            lock (_errorLock) { return _errors.Count; }
        }

        /// <summary>获取最近的日志</summary>
        public List<LogEntry> GetRecentLogs(int count)
        {
            var result = new List<LogEntry>();
            lock (_lock)
            {
                int toRead = Math.Min(count, _count);
                // 从最新到最旧
                for (int i = 0; i < toRead; i++)
                {
                    int idx = (_writeIndex - 1 - i + _capacity) % _capacity;
                    result.Add(_buffer[idx]);
                }
            }
            return result;
        }

        /// <summary>获取最新一条日志</summary>
        public LogEntry GetLatest()
        {
            lock (_lock)
            {
                if (_count == 0) return null;
                int idx = (_writeIndex - 1 + _capacity) % _capacity;
                return _buffer[idx];
            }
        }
    }
}
