using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CNCSystem.Data.Repositories;
using CNCSystem.Models.Device;

namespace CNCSystem.Core.Services
{
    public class DeviceCollectionService : IDisposable
    {
        private readonly DeviceCurrentStatusRepository _deviceStatusRepository;
        private readonly ProductionCollectionService _productionCollectionService;
        private readonly System.Threading.Timer _collectionTimer;
        private readonly Timer _healthCheckTimer;
        private readonly object _lock = new object();
        private bool _isRunning = false;
        private readonly int _collectionInterval;
        private readonly int _maxConcurrentCollections;
        private readonly int _maxRetryCount;
        private readonly int _retryInterval;

        public DeviceCollectionService()
        {
            var context = new CNCBusinessDbContext();
            _deviceStatusRepository = new DeviceCurrentStatusRepository(context);
            _productionCollectionService = new ProductionCollectionService(
                new ProductionRepository(context),
                _deviceStatusRepository,
                new TemplateMappingService(new TemplateRepository(context), null),
                new CNCLLogDbContext()
            );

            // 从配置中读取设置
            _collectionInterval = int.Parse(ConfigurationManager.AppSettings["CollectionInterval"] ?? "60");
            _maxConcurrentCollections = int.Parse(ConfigurationManager.AppSettings["MaxConcurrentCollections"] ?? "100");
            _maxRetryCount = int.Parse(ConfigurationManager.AppSettings["MaxRetryCount"] ?? "3");
            _retryInterval = int.Parse(ConfigurationManager.AppSettings["RetryInterval"] ?? "30");

            // 初始化定时器
            _collectionTimer = new Timer(CollectDataFromDevices, null, 
                TimeSpan.Zero, TimeSpan.FromSeconds(_collectionInterval));
            
            _healthCheckTimer = new Timer(PerformHealthCheck, null, 
                TimeSpan.Zero, TimeSpan.FromMinutes(5));
        }

        public void Start()
        {
            lock (_lock)
            {
                if (_isRunning) return;
                
                _isRunning = true;
                LogInfo("设备数据采集服务已启动");
            }
        }

        public void Stop()
        {
            lock (_lock)
            {
                if (!_isRunning) return;
                
                _isRunning = false;
                _collectionTimer?.Dispose();
                _healthCheckTimer?.Dispose();
                LogInfo("设备数据采集服务已停止");
            }
        }

        private async void CollectDataFromDevices(object state)
        {
            if (!_isRunning) return;

            try
            {
                var devices = _deviceStatusRepository.GetAllDeviceCurrentStatuses();
                var onlineDevices = devices.Where(d => d.IsOnline && d.IsAvailable).ToList();

                if (!onlineDevices.Any())
                {
                    LogInfo("没有在线且可用的设备");
                    return;
                }

                // 并发采集控制
                var semaphore = new Semaphore(_maxConcurrentCollections, _maxConcurrentCollections);
                var tasks = new List<Task>();

                foreach (var device in onlineDevices)
                {
                    await semaphore.WaitAsync();
                    
                    tasks.Add(Task.Run(async () =>
                    {
                        try
                        {
                            await CollectDataFromDeviceAsync(device);
                        }
                        catch (Exception ex)
                        {
                            LogError($"采集设备 {device.DeviceId} 数据时发生错误: {ex.Message}");
                        }
                        finally
                        {
                            semaphore.Release();
                        }
                    }));
                }

                await Task.WhenAll(tasks);
            }
            catch (Exception ex)
            {
                LogError($"采集任务执行失败: {ex.Message}");
            }
        }

        private async Task CollectDataFromDeviceAsync(DeviceCurrentStatus device)
        {
            var attempt = 0;
            var success = false;

            while (attempt < _maxRetryCount && !success)
            {
                try
                {
                    // 模拟HTTP请求采集数据
                    var rawData = await SimulateHttpRequest(device);
                    
                    if (rawData != null)
                    {
                        // 处理采集到的数据
                        _productionCollectionService.ProcessDeviceData(device.DeviceId, rawData);
                        success = true;
                        
                        LogInfo($"设备 {device.DeviceId} ({device.DeviceCode}) 数据采集成功");
                    }
                    else
                    {
                        throw new Exception("HTTP请求返回空数据");
                    }
                }
                catch (Exception ex)
                {
                    attempt++;
                    LogWarning($"设备 {device.DeviceId} 采集失败 (尝试 {attempt}/{_maxRetryCount}): {ex.Message}");
                    
                    if (attempt < _maxRetryCount)
                    {
                        await Task.Delay(TimeSpan.FromSeconds(_retryInterval));
                    }
                }
            }

            if (!success)
            {
                LogError($"设备 {device.DeviceId} 达到最大重试次数，采集失败");
                
                // 创建采集失败告警
                // AlarmService.CreateCollectionFailureAlarm(device.DeviceId, "达到最大重试次数");
            }
        }

        private async Task<Dictionary<string, object>> SimulateHttpRequest(DeviceCurrentStatus device)
        {
            // 这里应该实现真实的HTTP请求逻辑
            // 模拟返回测试数据
            await Task.Delay(100); // 模拟网络延迟

            var random = new Random();
            var isRunning = random.Next(0, 10) > 2; // 70%概率在运行
            
            return new Dictionary<string, object>
            {
                ["device"] = device.DeviceCode,
                ["desc"] = device.DeviceName,
                ["tags"] = new List<Dictionary<string, object>>
                {
                    new Dictionary<string, object>
                    {
                        ["id"] = "_io_status",
                        ["desc"] = "设备状态",
                        ["quality"] = "Good",
                        ["value"] = isRunning ? "1" : "0",
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    new Dictionary<string, object>
                    {
                        ["id"] = "Tag5",
                        ["desc"] = "NC程序名",
                        ["quality"] = "Good",
                        ["value"] = $"PROG_{random.Next(1000, 9999)}",
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    new Dictionary<string, object>
                    {
                        ["id"] = "Tag8",
                        ["desc"] = "累计数量",
                        ["quality"] = "Good",
                        ["value"] = random.Next(1000, 10000).ToString(),
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    new Dictionary<string, object>
                    {
                        ["id"] = "Tag9",
                        ["desc"] = "运行状态",
                        ["quality"] = "Good",
                        ["value"] = isRunning ? "1" : "0",
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    new Dictionary<string, object>
                    {
                        ["id"] = "Tag11",
                        ["desc"] = "操作模式",
                        ["quality"] = "Good",
                        ["value"] = "MDI",
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    new Dictionary<string, object>
                    {
                        ["id"] = "Tag14",
                        ["desc"] = "主轴倍率",
                        ["quality"] = "Good",
                        ["value"] = "100",
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    new Dictionary<string, object>
                    {
                        ["id"] = "Tag17",
                        ["desc"] = "主轴转速",
                        ["quality"] = "Good",
                        ["value"] = random.Next(1000, 5000).ToString(),
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    new Dictionary<string, object>
                    {
                        ["id"] = "Tag18",
                        ["desc"] = "进给速度",
                        ["quality"] = "Good",
                        ["value"] = random.Next(10, 100).ToString(),
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    new Dictionary<string, object>
                    {
                        ["id"] = "Tag19",
                        ["desc"] = "负载率",
                        ["quality"] = "Good",
                        ["value"] = random.Next(30, 90).ToString(),
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    new Dictionary<string, object>
                    {
                        ["id"] = "Tag20",
                        ["desc"] = "切削负载",
                        ["quality"] = "Good",
                        ["value"] = random.Next(20, 80).ToString(),
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    new Dictionary<string, object>
                    {
                        ["id"] = "Tag21",
                        ["desc"] = "功率",
                        ["quality"] = "Good",
                        ["value"] = random.Next(5, 50).ToString(),
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    new Dictionary<string, object>
                    {
                        ["id"] = "Tag22",
                        ["desc"] = "运行时间",
                        ["quality"] = "Good",
                        ["value"] = random.Next(100, 1000).ToString(),
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    new Dictionary<string, object>
                    {
                        ["id"] = "Tag23",
                        ["desc"] = "加工时间",
                        ["quality"] = "Good",
                        ["value"] = random.Next(50, 500).ToString(),
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    new Dictionary<string, object>
                    {
                        ["id"] = "Tag24",
                        ["desc"] = "准备时间",
                        ["quality"] = "Good",
                        ["value"] = random.Next(10, 100).ToString(),
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    new Dictionary<string, object>
                    {
                        ["id"] = "Tag25",
                        ["desc"] = "停机时间",
                        ["quality"] = "Good",
                        ["value"] = random.Next(0, 50).ToString(),
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    },
                    new Dictionary<string, object>
                    {
                        ["id"] = "Tag26",
                        ["desc"] = "加工状态",
                        ["quality"] = "Good",
                        ["value"] = isRunning ? "1" : "0",
                        ["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    }
                }
            };
        }

        private void PerformHealthCheck(object state)
        {
            if (!_isRunning) return;

            try
            {
                // 执行系统健康检查
                LogInfo("执行系统健康检查...");
                
                // 检查数据库连接
                CheckDatabaseConnection();
                
                // 检查设备状态
                CheckDeviceHealth();
                
                // 清理过期数据
                CleanupOldData();
                
                LogInfo("系统健康检查完成");
            }
            catch (Exception ex)
            {
                LogError($"健康检查失败: {ex.Message}");
            }
        }

        private void CheckDatabaseConnection()
        {
            try
            {
                using (var context = new CNCBusinessDbContext())
                {
                    context.Database.Connection.Open();
                    context.Database.Connection.Close();
                }
                LogInfo("数据库连接正常");
            }
            catch (Exception ex)
            {
                LogError($"数据库连接失败: {ex.Message}");
                throw;
            }
        }

        private void CheckDeviceHealth()
        {
            var devices = _deviceStatusRepository.GetAllDeviceCurrentStatuses();
            var offlineDevices = devices.Where(d => !d.IsOnline).ToList();
            
            if (offlineDevices.Any())
            {
                LogWarning($"发现 {offlineDevices.Count} 台离线设备");
                
                foreach (var device in offlineDevices)
                {
                    LogWarning($"设备 {device.DeviceId} ({device.DeviceCode}) 已离线");
                    // 这里可以创建离线告警
                }
            }
        }

        private void CleanupOldData()
        {
            try
            {
                var retentionDays = int.Parse(ConfigurationManager.AppSettings["DataRetentionDays"] ?? "30");
                LogInfo($"清理 {retentionDays} 天前的数据...");
                
                // 这里应该调用相应的清理方法
                LogInfo("数据清理完成");
            }
            catch (Exception ex)
            {
                LogError($"数据清理失败: {ex.Message}");
            }
        }

        private void LogInfo(string message)
        {
            Log("INFO", message);
        }

        private void LogWarning(string message)
        {
            Log("WARNING", message);
        }

        private void LogError(string message)
        {
            Log("ERROR", message);
        }

        private void Log(string level, string message)
        {
            try
            {
                var logPath = System.Web.HttpContext.Current?.Server.MapPath("~/App_Data/Logs/CollectionService.log");
                if (logPath != null)
                {
                    var logMessage = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [{level}] {message}\n";
                    System.IO.File.AppendAllText(logPath, logMessage);
                }
            }
            catch
            {
                // 如果日志记录失败，忽略错误
            }
        }

        public void Dispose()
        {
            Stop();
            _collectionTimer?.Dispose();
            _healthCheckTimer?.Dispose();
        }
    }
}