using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using CNCSystem.Core.Helpers;
using CNCSystem.Models.Device;
using Newtonsoft.Json;

namespace CNCSystem.Core.Schedule
{
    public class DataCollectionTask
    {
        private readonly HttpClient _httpClient;
        private readonly int _timeoutSeconds = 30;

        public DataCollectionTask()
        {
            _httpClient = new HttpClient();
            _httpClient.Timeout = TimeSpan.FromSeconds(_timeoutSeconds);
        }

        public async Task<bool> CollectDataAsync(DeviceCurrentStatus device)
        {
            try
            {
                var startTime = DateTime.Now;
                
                // 检查设备连通性
                if (!await CheckDeviceConnectivity(device))
                {
                    Logger.LogDeviceCollection(device.DeviceId, device.DeviceCode, false, "设备无法连通");
                    return false;
                }

                // 发送HTTP请求获取数据
                var rawData = await FetchDeviceDataAsync(device);
                if (rawData == null)
                {
                    Logger.LogDeviceCollection(device.DeviceId, device.DeviceCode, false, "获取数据失败");
                    return false;
                }

                // 解析和处理数据
                var processingTime = DateTime.Now - startTime;
                Logger.LogDeviceCollection(device.DeviceId, device.DeviceCode, true, 
                    $"采集成功，耗时: {processingTime.TotalMilliseconds}ms");

                return true;
            }
            catch (Exception ex)
            {
                Logger.LogError($"采集设备 {device.DeviceId} 数据时发生错误: {ex.Message}", ex);
                return false;
            }
        }

        private async Task<bool> CheckDeviceConnectivity(DeviceCurrentStatus device)
        {
            try
            {
                // Ping检查
                using (var ping = new System.Net.NetworkInformation.Ping())
                {
                    var reply = await ping.SendPingAsync(device.IPAddress, 5000);
                    if (reply.Status != System.Net.NetworkInformation.IPStatus.Success)
                    {
                        return false;
                    }
                }

                // HTTP服务检查
                var healthCheckUrl = $"{device.HttpUrl.TrimEnd('/')}/health";
                var response = await _httpClient.GetAsync(healthCheckUrl);
                
                return response.IsSuccessStatusCode;
            }
            catch (Exception ex)
            {
                Logger.LogWarning($"设备 {device.DeviceId} 连通性检查失败: {ex.Message}");
                return false;
            }
        }

        private async Task<Dictionary<string, object>> FetchDeviceDataAsync(DeviceCurrentStatus device)
        {
            try
            {
                var requestUrl = $"{device.HttpUrl.TrimEnd('/')}/data";
                
                var request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
                
                // 添加必要的请求头
                request.Headers.Add("User-Agent", "CNCSystem/1.0");
                request.Headers.Add("Accept", "application/json");
                
                var response = await _httpClient.SendAsync(request);
                response.EnsureSuccessStatusCode();
                
                var content = await response.Content.ReadAsStringAsync();
                var rawData = JsonConvert.DeserializeObject<Dictionary<string, object>>(content);
                
                return rawData;
            }
            catch (HttpRequestException ex)
            {
                Logger.LogError($"HTTP请求失败: {ex.Message}", ex);
                throw;
            }
            catch (JsonException ex)
            {
                Logger.LogError($"JSON解析失败: {ex.Message}", ex);
                throw;
            }
            catch (Exception ex)
            {
                Logger.LogError($"获取设备数据时发生错误: {ex.Message}", ex);
                throw;
            }
        }
    }

    public class ScheduledTaskService
    {
        private readonly Timer _collectionTimer;
        private readonly Timer _cleanupTimer;
        private readonly Timer _healthTimer;
        private readonly DataCollectionTask _collectionTask;
        private readonly object _lock = new object();
        private bool _isRunning = false;

        public ScheduledTaskService()
        {
            _collectionTask = new DataCollectionTask();
            
            // 数据采集定时器（每60秒执行一次）
            _collectionTimer = new Timer(PerformDataCollection, null, 
                TimeSpan.Zero, TimeSpan.FromMinutes(1));
            
            // 数据清理定时器（每天凌晨2点执行）
            var cleanupTime = DateTime.Today.AddDays(1).AddHours(2);
            var timeToCleanup = cleanupTime - DateTime.Now;
            if (timeToCleanup < TimeSpan.Zero)
            {
                timeToCleanup += TimeSpan.FromDays(1);
            }
            
            _cleanupTimer = new Timer(PerformDataCleanup, null, 
                timeToCleanup, TimeSpan.FromDays(1));
            
            // 健康检查定时器（每5分钟执行一次）
            _healthTimer = new Timer(PerformHealthCheck, null, 
                TimeSpan.Zero, TimeSpan.FromMinutes(5));
        }

        public void Start()
        {
            lock (_lock)
            {
                if (_isRunning) return;
                
                _isRunning = true;
                Logger.LogInfo("定时任务服务已启动", "Schedule");
            }
        }

        public void Stop()
        {
            lock (_lock)
            {
                if (!_isRunning) return;
                
                _isRunning = false;
                _collectionTimer?.Dispose();
                _cleanupTimer?.Dispose();
                _healthTimer?.Dispose();
                Logger.LogInfo("定时任务服务已停止", "Schedule");
            }
        }

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

            try
            {
                Logger.LogInfo("开始执行数据采集任务", "Schedule");
                
                var startTime = DateTime.Now;
                var successCount = 0;
                var failureCount = 0;
                
                // 获取所有设备
                var deviceService = new DeviceCurrentStatusRepository(new CNCBusinessDbContext());
                var devices = deviceService.GetAllDeviceCurrentStatuses();
                
                // 过滤出在线且可用的设备
                var onlineDevices = devices.Where(d => d.IsOnline && d.IsAvailable).ToList();
                
                if (!onlineDevices.Any())
                {
                    Logger.LogInfo("没有在线且可用的设备", "Schedule");
                    return;
                }

                Logger.LogInfo($"开始采集 {onlineDevices.Count} 台设备的数据", "Schedule");
                
                // 并发采集（限制并发数）
                var semaphore = new Semaphore(10, 10); // 最多10个并发
                var tasks = new List<Task>();

                foreach (var device in onlineDevices)
                {
                    await semaphore.WaitAsync();
                    
                    tasks.Add(Task.Run(async () =>
                    {
                        try
                        {
                            var success = await _collectionTask.CollectDataAsync(device);
                            if (success)
                            {
                                Interlocked.Increment(ref successCount);
                            }
                            else
                            {
                                Interlocked.Increment(ref failureCount);
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.LogError($"采集设备 {device.DeviceId} 数据时发生错误: {ex.Message}", ex);
                            Interlocked.Increment(ref failureCount);
                        }
                        finally
                        {
                            semaphore.Release();
                        }
                    }));
                }

                await Task.WhenAll(tasks);
                
                var duration = DateTime.Now - startTime;
                Logger.LogInfo($"数据采集任务完成，成功: {successCount}, 失败: {failureCount}, " +
                    $"耗时: {duration.TotalMilliseconds}ms", "Schedule");
            }
            catch (Exception ex)
            {
                Logger.LogError($"数据采集任务执行失败: {ex.Message}", ex, "Schedule");
            }
        }

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

            try
            {
                Logger.LogInfo("开始执行数据清理任务", "Schedule");
                
                var retentionDays = 30; // 保留30天的数据
                var cutoffDate = DateTime.Now.AddDays(-retentionDays);
                
                Logger.LogInfo($"清理 {cutoffDate:yyyy-MM-dd} 之前的数据", "Schedule");
                
                // 这里应该调用相应的数据清理方法
                // 清理生产记录、告警日志、系统日志等
                
                Logger.LogInfo("数据清理任务完成", "Schedule");
            }
            catch (Exception ex)
            {
                Logger.LogError($"数据清理任务执行失败: {ex.Message}", ex, "Schedule");
            }
        }

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

            try
            {
                Logger.LogInfo("开始执行健康检查任务", "Schedule");
                
                var healthy = true;
                var issues = new List<string>();
                
                // 检查数据库连接
                if (!CheckDatabaseConnection())
                {
                    healthy = false;
                    issues.Add("数据库连接失败");
                }
                
                // 检查磁盘空间
                if (!CheckDiskSpace())
                {
                    healthy = false;
                    issues.Add("磁盘空间不足");
                }
                
                // 检查内存使用
                if (!CheckMemoryUsage())
                {
                    healthy = false;
                    issues.Add("内存使用过高");
                }
                
                // 检查服务状态
                if (!CheckServiceStatus())
                {
                    healthy = false;
                    issues.Add("服务状态异常");
                }
                
                Logger.LogSystemHealthCheck(DateTime.Now, healthy, 
                    healthy ? null : string.Join(", ", issues));
                
                if (!healthy)
                {
                    Logger.LogWarning("系统健康检查发现问题", "Schedule");
                }
            }
            catch (Exception ex)
            {
                Logger.LogError($"健康检查任务执行失败: {ex.Message}", ex, "Schedule");
            }
        }

        private bool CheckDatabaseConnection()
        {
            try
            {
                using (var context = new CNCBusinessDbContext())
                {
                    context.Database.Connection.Open();
                    context.Database.Connection.Close();
                    return true;
                }
            }
            catch (Exception ex)
            {
                Logger.LogError($"数据库连接检查失败: {ex.Message}", ex);
                return false;
            }
        }

        private bool CheckDiskSpace()
        {
            try
            {
                var drive = DriveInfo.GetDrives()[0];
                var freeSpace = drive.TotalFreeSpace;
                var totalSpace = drive.TotalSize;
                var freeSpacePercent = (double)freeSpace / totalSpace * 100;
                
                return freeSpacePercent > 10; // 空闲空间大于10%
            }
            catch (Exception ex)
            {
                Logger.LogError($"磁盘空间检查失败: {ex.Message}", ex);
                return false;
            }
        }

        private bool CheckMemoryUsage()
        {
            try
            {
                var process = System.Diagnostics.Process.GetCurrentProcess();
                var memoryUsage = process.PrivateMemorySize64;
                var totalMemory = new System.Management.ManagementClass("Win32_ComputerSystem")
                    .Properties["TotalPhysicalMemory"].Value;
                
                var memoryPercent = (double)memoryUsage / (long)totalMemory * 100;
                
                return memoryPercent < 90; // 内存使用率小于90%
            }
            catch (Exception ex)
            {
                Logger.LogError($"内存使用检查失败: {ex.Message}", ex);
                return false;
            }
        }

        private bool CheckServiceStatus()
        {
            try
            {
                // 检查关键服务是否正常运行
                var services = new List<string>
                {
                    "数据采集服务",
                    "告警服务",
                    "API服务"
                };
                
                foreach (var service in services)
                {
                    // 这里应该检查实际的服务状态
                    // 简化实现，假设服务都正常
                }
                
                return true;
            }
            catch (Exception ex)
            {
                Logger.LogError($"服务状态检查失败: {ex.Message}", ex);
                return false;
            }
        }
    }
}