using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Haoliang.Models.DataCollection;
using Haoliang.Models.Device;
using Haoliang.Models.System;
using Haoliang.Models.User;
using Haoliang.Models.Template;
using Haoliang.Models.Production;
using Haoliang.Data.Repositories;

namespace Haoliang.Core.Services
{
    // 完整的仓储接口定义（确保所有服务都能编译）
    public interface IAlarmRepository : IRepository<Alarm>
    {
        Task<IEnumerable<Alarm>> GetByDeviceIdAsync(int deviceId);
        Task<IEnumerable<Alarm>> GetByAlarmTypeAsync(AlarmType type);
        Task<IEnumerable<Alarm>> GetByStatusAsync(AlarmStatus status);
        Task<IEnumerable<Alarm>> GetByDateRangeAsync(DateTime startDate, DateTime endDate);
        Task<AlarmStatistics> GetAlarmStatisticsAsync(DateTime date);
        Task<IEnumerable<Alarm>> GetBySeverityAsync(AlarmSeverity severity);
        Task<IEnumerable<Alarm>> GetByDeviceAndDateRangeAsync(int deviceId, DateTime startDate, DateTime endDate);
    }

    public interface ISystemConfigRepository : IRepository<SystemConfig>
    {
        Task<SystemConfig> GetByKeyAsync(string configKey);
        Task<bool> DeleteByKeyAsync(string configKey);
        Task<bool> KeyExistsAsync(string configKey);
        Task<IEnumerable<SystemConfig>> GetByCategoryAsync(string category);
        SystemConfig UpsertAsync(SystemConfig config);
    }

    public interface ILogRepository : IRepository<LogEntry>
    {
        Task<IEnumerable<LogEntry>> GetLogsAsync(LogLevel? logLevel = null, DateTime? startDate = null, DateTime? endDate = null, string category = null);
        Task<int> GetLogCountAsync(LogLevel? logLevel = null, DateTime? startDate = null, DateTime? endDate = null);
        Task ArchiveLogsAsync(DateTime cutoffDate);
        Task ClearLogsAsync();
    }

    public interface IScheduledTaskRepository : IRepository<ScheduledTask>
    {
        Task<IEnumerable<ScheduledTask>> GetActiveTasksAsync();
        Task<IEnumerable<ScheduledTask>> GetTasksByStatusAsync(TaskStatus status);
        Task<TaskExecutionResult> GetLastExecutionResultAsync(string taskId);
    }

    public interface IProgramProductionSummaryRepository : IRepository<ProgramProductionSummary>
    {
        Task<ProgramProductionSummary> GetByDeviceAndDateAsync(int deviceId, DateTime date);
        Task<IEnumerable<ProgramProductionSummary>> GetByDateAsync(DateTime date);
        Task<IEnumerable<ProgramProductionSummary>> GetByDeviceAsync(int deviceId);
    }

    public interface IUserRepository : IRepository<User>
    {
        Task<User> GetByUsernameAsync(string username);
        Task<User> GetByEmailAsync(string email);
        Task<bool> IsUsernameExistsAsync(string username);
        Task<bool> IsEmailExistsAsync(string email);
        Task<IEnumerable<User>> GetByRoleAsync(string roleName);
        Task<IEnumerable<User>> GetByDepartmentAsync(string department);
    }

    // 增强的仓储接口
    public interface IDeviceRepository : IRepository<CNCDevice>
    {
        Task<IEnumerable<CNCDevice>> GetOnlineDevicesAsync();
        Task<IEnumerable<CNCDevice>> GetOfflineDevicesAsync();
        Task<CNCDevice> GetByDeviceCodeAsync(string deviceCode);
        Task<bool> IsDeviceOnlineAsync(int deviceId);
        Task<IEnumerable<CNCDevice>> GetByTemplateAsync(int templateId);
        Task UpdateDeviceStatusAsync(int deviceId, DeviceStatus status);
        Task<DeviceStatistics> GetDeviceStatisticsAsync(int deviceId);
    }

    public interface ITemplateRepository : IRepository<CNCBrandTemplate>
    {
        Task<IEnumerable<CNCBrandTemplate>> GetByBrandAsync(string brandName);
        Task<IEnumerable<CNCBrandTemplate>> GetActiveTemplatesAsync();
        Task<bool> IsTemplateInUseAsync(int templateId);
        Task<CNCBrandTemplate> GetByNameAsync(string templateName);
    }

    public interface IProductionRepository : IRepository<ProductionRecord>
    {
        Task<ProductionRecord> GetByDeviceAndDateAsync(int deviceId, DateTime date);
        Task<IEnumerable<ProductionRecord>> GetByDateRangeAsync(int deviceId, DateTime startDate, DateTime endDate);
        Task<ProductionStatistics> GetStatisticsAsync(int deviceId, DateTime date);
        Task<ProductionSummary> GetSummaryAsync(DateTime date);
        Task<bool> HasProductionDataAsync(int deviceId, DateTime date);
        Task ArchiveProductionDataAsync(int daysToKeep = 90);
    }

    public interface ICollectionTaskRepository : IRepository<CollectionTask>
    {
        Task<IEnumerable<CollectionTask>> GetPendingTasksAsync();
        Task<IEnumerable<CollectionTask>> GetFailedTasksAsync();
        Task<CollectionTask> GetByDeviceAsync(int deviceId);
        Task<bool> MarkTaskCompletedAsync(int taskId, bool isSuccess, string result);
    }

    public interface ICollectionResultRepository : IRepository<CollectionResult>
    {
        Task<IEnumerable<CollectionResult>> GetByDeviceAsync(int deviceId);
        Task<IEnumerable<CollectionResult>> GetByDateRangeAsync(int deviceId, DateTime startDate, DateTime endDate);
        Task<CollectionStatistics> GetStatisticsAsync(DateTime date);
        Task<CollectionHealth> GetHealthAsync();
        Task ArchiveResultsAsync(int daysToKeep = 30);
    }

    public interface ICollectionLogRepository : IRepository<CollectionLog>
    {
        Task<IEnumerable<CollectionLog>> GetByDeviceAsync(int deviceId);
        Task<IEnumerable<CollectionLog>> GetByLogLevelAsync(LogLevel logLevel);
        Task<int> GetErrorCountAsync(int deviceId);
        Task ArchiveLogsAsync(int daysToKeep = 30);
        Task ClearLogsAsync();
    }

    public interface IProductionSummaryRepository : IRepository<ProductionSummary>
    {
        Task<ProductionSummary> GetByDateAsync(DateTime date);
        Task<IEnumerable<ProductionSummary>> GetByDateRangeAsync(DateTime startDate, DateTime endDate);
        Task<ProductionSummary> GetByDeviceAndDateAsync(int deviceId, DateTime date);
        Task<ProductionSummary> GetTodaySummaryAsync();
    }

    // 背景任务管理器
    public class BackgroundTaskManager : ISchedulerService
    {
        private readonly IScheduledTaskRepository _taskRepository;
        private readonly IProductionService _productionService;
        private readonly ILoggingService _loggingService;
        private readonly ConcurrentDictionary<string, Task> _runningTasks = new();
        private readonly ConcurrentDictionary<string, bool> _taskStatus = new();
        private System.Threading.Timer _schedulerTimer;

        public BackgroundTaskManager(
            IScheduledTaskRepository taskRepository,
            IProductionService productionService,
            ILoggingService loggingService)
        {
            _taskRepository = taskRepository;
            _productionService = productionService;
            _loggingService = loggingService;
        }

        public async Task StartSchedulerAsync()
        {
            _schedulerTimer = new System.Threading.Timer(
                async _ => await CheckAndExecuteTasksAsync(),
                null,
                TimeSpan.Zero,
                TimeSpan.FromMinutes(1));

            await _loggingService.LogInfoAsync("Background task scheduler started");
        }

        public async Task StopSchedulerAsync()
        {
            _schedulerTimer?.Dispose();
            _schedulerTimer = null;
            
            foreach (var task in _runningTasks.Values)
            {
                if (!task.IsCompleted)
                {
                    await Task.WhenAny(task, Task.Delay(TimeSpan.FromSeconds(5)));
                }
            }

            await _loggingService.LogInfoAsync("Background task scheduler stopped");
        }

        public async Task ScheduleTaskAsync(ScheduledTask task)
        {
            task.TaskStatus = TaskStatus.Pending;
            task.CreatedAt = DateTime.Now;
            task.LastRunAt = null;
            
            await _taskRepository.AddAsync(task);
            await _loggingService.LogInfoAsync($"Task {task.TaskName} scheduled");
        }

        public async Task<bool> RemoveTaskAsync(string taskId)
        {
            var task = await _taskRepository.GetByIdAsync(taskId);
            if (task == null)
            {
                return false;
            }

            // 如果任务正在运行，等待完成
            if (_runningTasks.ContainsKey(taskId))
            {
                var runningTask = _runningTasks[taskId];
                await Task.WhenAny(runningTask, Task.Delay(TimeSpan.FromSeconds(5)));
            }

            return await _taskRepository.DeleteAsync(taskId);
        }

        public async Task<IEnumerable<ScheduledTask>> GetAllScheduledTasksAsync()
        {
            return await _taskRepository.GetAllAsync();
        }

        public async Task<ScheduledTask> GetTaskByIdAsync(string taskId)
        {
            return await _taskRepository.GetByIdAsync(taskId);
        }

        public async Task ExecuteTaskAsync(string taskId)
        {
            if (_runningTasks.ContainsKey(taskId))
            {
                await _loggingService.LogWarningAsync($"Task {taskId} is already running");
                return;
            }

            var task = await _taskRepository.GetByIdAsync(taskId);
            if (task == null)
            {
                await _loggingService.LogErrorAsync($"Task {taskId} not found");
                return;
            }

            var taskExecution = Task.Run(async () =>
            {
                try
                {
                    _taskStatus[taskId] = true;
                    task.TaskStatus = TaskStatus.Running;
                    task.LastRunAt = DateTime.Now;
                    await _taskRepository.UpdateAsync(task);

                    await _loggingService.LogInfoAsync($"Executing task: {task.TaskName}");

                    // 执行任务逻辑
                    switch (task.TaskName)
                    {
                        case "ProductionCalculation":
                            await _productionService.CalculateAllProductionAsync();
                            break;
                        case "DataCollection":
                            // 数据采集逻辑
                            break;
                        case "LogArchival":
                            await _loggingService.ArchiveLogsAsync(30);
                            break;
                        case "DataCleanup":
                            // 数据清理逻辑
                            break;
                        default:
                            await _loggingService.LogWarningAsync($"Unknown task type: {task.TaskName}");
                            break;
                    }

                    task.TaskStatus = TaskStatus.Completed;
                    task.CompletedAt = DateTime.Now;
                    await _taskRepository.UpdateAsync(task);

                    await _loggingService.LogInfoAsync($"Task {task.TaskName} completed successfully");
                }
                catch (Exception ex)
                {
                    task.TaskStatus = TaskStatus.Failed;
                    task.ErrorMessage = ex.Message;
                    task.CompletedAt = DateTime.Now;
                    await _taskRepository.UpdateAsync(task);

                    await _loggingService.LogErrorAsync($"Task {task.TaskName} failed: {ex.Message}", ex);
                }
                finally
                {
                    _runningTasks.TryRemove(taskId, out _);
                    _taskStatus.TryRemove(taskId, out _);
                }
            });

            _runningTasks[taskId] = taskExecution;
        }

        public async Task<TaskExecutionResult> GetTaskExecutionResultAsync(string taskId)
        {
            return await _taskRepository.GetLastExecutionResultAsync(taskId);
        }

        public async Task<bool> IsTaskRunningAsync(string taskId)
        {
            return _runningTasks.ContainsKey(taskId) && _taskStatus.ContainsKey(taskId) && _taskStatus[taskId];
        }

        public async Task<string> ScheduleRecurringTaskAsync(string taskName, Action taskAction, TimeSpan interval)
        {
            var task = new ScheduledTask
            {
                TaskId = Guid.NewGuid().ToString(),
                TaskName = taskName,
                CronExpression = $"*/{interval.TotalMinutes} * * * *",
                TaskStatus = TaskStatus.Pending,
                IsActive = true,
                CreatedAt = DateTime.Now,
                Description = $"Recurring task: {taskName}"
            };

            await ScheduleTaskAsync(task);
            return task.TaskId;
        }

        private async Task CheckAndExecuteTasksAsync()
        {
            var pendingTasks = await _taskRepository.GetActiveTasksAsync();
            var now = DateTime.Now;

            foreach (var task in pendingTasks)
            {
                if (await ShouldExecuteTaskAsync(task, now))
                {
                    await ExecuteTaskAsync(task.TaskId);
                }
            }
        }

        private async Task<bool> ShouldExecuteTaskAsync(ScheduledTask task, DateTime now)
        {
            if (task.TaskStatus == TaskStatus.Running || !task.IsActive)
            {
                return false;
            }

            // 简单的时间检查（实际应该使用CRON表达式解析器）
            if (task.LastRunAt == null)
            {
                return true;
            }

            var timeSinceLastRun = now - task.LastRunAt.Value;
            return timeSinceLastRun.TotalMinutes >= 1; // 每分钟执行一次
        }
    }

    // 缓存服务实现
    public class CacheManager : ICachingService
    {
        private readonly ConcurrentDictionary<string, CacheItem> _cache = new();
        private readonly System.Threading.Timer _cleanupTimer;

        public CacheManager()
        {
            _cleanupTimer = new System.ThreadingTimer(
                _ => CleanupExpiredItems(),
                null,
                TimeSpan.FromMinutes(5),
                TimeSpan.FromMinutes(5));
        }

        public async Task<T> GetAsync<T>(string key)
        {
            if (_cache.TryGetValue(key, out var item))
            {
                if (item.ExpirationTime > DateTime.Now)
                {
                    return (T)item.Value;
                }
                _cache.TryRemove(key, out _);
            }
            return default;
        }

        public async Task SetAsync<T>(string key, T value, TimeSpan? expiration = null)
        {
            var item = new CacheItem
            {
                Value = value,
                ExpirationTime = DateTime.Now + (expiration ?? TimeSpan.FromMinutes(30))
            };

            _cache[key] = item;
        }

        public async Task<bool> RemoveAsync(string key)
        {
            return _cache.TryRemove(key, out _);
        }

        public async Task<bool> ExistsAsync(string key)
        {
            if (_cache.TryGetValue(key, out var item))
            {
                if (item.ExpirationTime > DateTime.Now)
                {
                    return true;
                }
                _cache.TryRemove(key, out _);
            }
            return false;
        }

        public async Task ClearAsync()
        {
            _cache.Clear();
        }

        public async Task<T> GetOrCreateAsync<T>(string key, Func<Task<T>> factory, TimeSpan? expiration = null)
        {
            var value = await GetAsync<T>(key);
            if (value == null)
            {
                value = await factory();
                await SetAsync(key, value, expiration);
            }
            return value;
        }

        public async Task<IEnumerable<string>> GetAllKeysAsync()
        {
            return _cache.Keys;
        }

        public async Task<bool> RefreshAsync<T>(string key)
        {
            if (_cache.TryGetValue(key, out var item))
            {
                item.ExpirationTime = DateTime.Now + TimeSpan.FromMinutes(30);
                return true;
            }
            return false;
        }

        private void CleanupExpiredItems()
        {
            var now = DateTime.Now;
            var expiredKeys = _cache
                .Where(kvp => kvp.Value.ExpirationTime <= now)
                .Select(kvp => kvp.Key)
                .ToList();

            foreach (var key in expiredKeys)
            {
                _cache.TryRemove(key, out _);
            }
        }

        private class CacheItem
        {
            public object Value { get; set; }
            public DateTime ExpirationTime { get; set; }
        }
    }

    // 简化的JWT认证中间件
    public class JwtAuthMiddleware : IWebSocketAuthMiddleware
    {
        private readonly IAuthService _authService;
        private readonly ConcurrentDictionary<string, string> _connectionUsers = new();

        public JwtAuthMiddleware(IAuthService authService)
        {
            _authService = authService;
        }

        public async Task AuthenticateAsync(string connectionId, string token)
        {
            try
            {
                var isValid = await _authService.ValidateTokenAsync(token);
                if (isValid)
                {
                    var claims = await _authService.GetUserClaimsAsync(int.Parse(token));
                    _connectionUsers[connectionId] = claims.UserId.ToString();
                }
            }
            catch (Exception ex)
            {
                // 认证失败
            }
        }

        public async Task<string> GetUserIdAsync(string connectionId)
        {
            _connectionUsers.TryGetValue(connectionId, out var userId);
            return userId;
        }

        public async Task<string> GetConnectionIdAsync(string userId)
        {
            foreach (var kvp in _connectionUsers)
            {
                if (kvp.Value == userId)
                {
                    return kvp.Key;
                }
            }
            return null;
        }

        public async Task<bool> IsAuthenticatedAsync(string connectionId)
        {
            return _connectionUsers.ContainsKey(connectionId);
        }

        public async Task<bool> HasPermissionAsync(string connectionId, string permission)
        {
            var userId = await GetUserIdAsync(connectionId);
            if (string.IsNullOrEmpty(userId))
            {
                return false;
            }

            // 这里应该检查用户权限
            return true; // 简化实现
        }
    }
}