using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Haoliang.Models.System;

namespace Haoliang.Core.Services
{
    public interface ISystemConfigService
    {
        Task<SystemConfig> GetConfigAsync(string configKey);
        Task<Dictionary<string, string>> GetAllConfigsAsync();
        Task<SystemConfig> SetConfigAsync(string configKey, string configValue);
        Task<bool> DeleteConfigAsync(string configKey);
        Task<bool> ConfigExistsAsync(string configKey);
        Task<IEnumerable<SystemConfig>> GetConfigsByCategoryAsync(string category);
        Task<bool> ValidateConfigAsync(SystemConfig config);
        Task RefreshConfigCacheAsync();
        Task<T> GetConfigValueAsync<T>(string configKey, T defaultValue = default);
    }

    public interface ILoggingService
    {
        Task LogAsync(LogLevel logLevel, string message, Exception exception = null, Dictionary<string, object> properties = null);
        Task LogErrorAsync(string message, Exception exception = null, Dictionary<string, object> properties = null);
        Task LogWarningAsync(string message, Dictionary<string, object> properties = null);
        Task LogInfoAsync(string message, Dictionary<string, object> properties = null);
        Task LogDebugAsync(string message, Dictionary<string, object> properties = null);
        Task LogTraceAsync(string message, Dictionary<string, object> properties = null);
        Task<IEnumerable<LogEntry>> GetLogsAsync(LogLevel? logLevel = null, DateTime? startDate = null, DateTime? endDate = null, string category = null);
        Task<IEnumerable<LogEntry>> GetErrorLogsAsync(DateTime? startDate = null, DateTime? endDate = null);
        Task<int> GetLogCountAsync(LogLevel? logLevel = null, DateTime? startDate = null, DateTime? endDate = null);
        Task ArchiveLogsAsync(int daysToKeep = 30);
        Task ClearLogsAsync();
    }

    public interface ISchedulerService
    {
        Task StartSchedulerAsync();
        Task StopSchedulerAsync();
        Task ScheduleTaskAsync(ScheduledTask task);
        Task<bool> RemoveTaskAsync(string taskId);
        Task<IEnumerable<ScheduledTask>> GetAllScheduledTasksAsync();
        Task<ScheduledTask> GetTaskByIdAsync(string taskId);
        Task ExecuteTaskAsync(string taskId);
        Task<TaskExecutionResult> GetTaskExecutionResultAsync(string taskId);
        Task<bool> IsTaskRunningAsync(string taskId);
        Task<string> ScheduleRecurringTaskAsync(string taskName, Action taskAction, TimeSpan interval);
    }

    public interface ICachingService
    {
        Task<T> GetAsync<T>(string key);
        Task SetAsync<T>(string key, T value, TimeSpan? expiration = null);
        Task<bool> RemoveAsync(string key);
        Task<bool> ExistsAsync(string key);
        Task ClearAsync();
        Task<T> GetOrCreateAsync<T>(string key, Func<Task<T>> factory, TimeSpan? expiration = null);
        Task<IEnumerable<string>> GetAllKeysAsync();
        Task<bool> RefreshAsync<T>(string key);
    }

    public class SystemConfigManager : ISystemConfigService
    {
        private readonly ISystemConfigRepository _configRepository;
        private readonly ICachingService _cachingService;

        public SystemConfigManager(
            ISystemConfigRepository configRepository,
            ICachingService cachingService)
        {
            _configRepository = configRepository;
            _cachingService = cachingService;
        }

        public async Task<SystemConfig> GetConfigAsync(string configKey)
        {
            // 先从缓存获取
            var cachedConfig = await _cachingService.GetAsync<SystemConfig>($"config_{configKey}");
            if (cachedConfig != null)
            {
                return cachedConfig;
            }

            // 缓存未命中，从数据库获取
            var config = await _configRepository.GetByKeyAsync(configKey);
            if (config != null)
            {
                // 存入缓存
                await _cachingService.SetAsync($"config_{configKey}", config, TimeSpan.FromMinutes(30));
            }

            return config;
        }

        public async Task<Dictionary<string, string>> GetAllConfigsAsync()
        {
            var configs = await _configRepository.GetAllAsync();
            var configDict = new Dictionary<string, string>();

            foreach (var config in configs)
            {
                configDict[config.ConfigKey] = config.ConfigValue;
            }

            return configDict;
        }

        public async Task<SystemConfig> SetConfigAsync(string configKey, string configValue)
        {
            // 验证配置
            var config = new SystemConfig
            {
                ConfigKey = configKey,
                ConfigValue = configValue,
                Category = "General",
                LastUpdated = DateTime.Now
            };

            var validationErrors = await ValidateConfigAsync(config);
            if (validationErrors.Count > 0)
            {
                throw new InvalidOperationException($"Config validation failed: {string.Join(", ", validationErrors)}");
            }

            // 检查配置是否已存在
            var existingConfig = await _configRepository.GetByKeyAsync(configKey);
            if (existingConfig != null)
            {
                config.ConfigId = existingConfig.ConfigId;
                config.CreateTime = existingConfig.CreateTime;
            }

            config.LastUpdated = DateTime.Now;
            var updatedConfig = await _configRepository.UpsertAsync(config);

            // 更新缓存
            await _cachingService.SetAsync($"config_{configKey}", updatedConfig, TimeSpan.FromMinutes(30));
            await _cachingService.RemoveAsync("all_configs");

            return updatedConfig;
        }

        public async Task<bool> DeleteConfigAsync(string configKey)
        {
            var result = await _configRepository.DeleteByKeyAsync(configKey);
            if (result)
            {
                // 清除缓存
                await _cachingService.RemoveAsync($"config_{configKey}");
                await _cachingService.RemoveAsync("all_configs");
            }

            return result;
        }

        public async Task<bool> ConfigExistsAsync(string configKey)
        {
            // 先检查缓存
            var existsInCache = await _cachingService.ExistsAsync($"config_{configKey}");
            if (existsInCache)
            {
                return true;
            }

            return await _configRepository.KeyExistsAsync(configKey);
        }

        public async Task<IEnumerable<SystemConfig>> GetConfigsByCategoryAsync(string category)
        {
            return await _configRepository.GetByCategoryAsync(category);
        }

        public async Task<bool> ValidateConfigAsync(SystemConfig config)
        {
            var errors = new List<string>();

            // 验证配置键
            if (string.IsNullOrWhiteSpace(config.ConfigKey))
            {
                errors.Add("Config key cannot be empty");
            }

            // 验证配置值
            if (config.ConfigValue == null)
            {
                errors.Add("Config value cannot be null");
            }

            // 根据不同的配置键进行特定验证
            switch (config.ConfigKey)
            {
                case "Database.ConnectionString":
                    if (!IsValidConnectionString(config.ConfigValue))
                    {
                        errors.Add("Invalid database connection string");
                    }
                    break;

                case "Logging.Level":
                    if (!IsValidLogLevel(config.ConfigValue))
                    {
                        errors.Add("Invalid log level");
                    }
                    break;

                case "Collection.Interval":
                    if (!IsValidInterval(config.ConfigValue))
                    {
                        errors.Add("Invalid collection interval");
                    }
                    break;

                case "Security.JwtSecret":
                    if (string.IsNullOrWhiteSpace(config.ConfigValue) || config.ConfigValue.Length < 16)
                    {
                        errors.Add("JWT secret must be at least 16 characters long");
                    }
                    break;
            }

            return errors.Count == 0;
        }

        public async Task RefreshConfigCacheAsync()
        {
            // 清除所有配置缓存
            await _cachingService.RemoveAsync("all_configs");
            
            // 重新加载常用配置
            var commonKeys = new[] { "Database.ConnectionString", "Logging.Level", "Collection.Interval" };
            foreach (var key in commonKeys)
            {
                await GetConfigAsync(key);
            }
        }

        public async Task<T> GetConfigValueAsync<T>(string configKey, T defaultValue = default)
        {
            var config = await GetConfigAsync(configKey);
            if (config == null)
            {
                return defaultValue;
            }

            try
            {
                return (T)Convert.ChangeType(config.ConfigValue, typeof(T));
            }
            catch
            {
                return defaultValue;
            }
        }

        private bool IsValidConnectionString(string connectionString)
        {
            // 简单的连接字符串验证
            return !string.IsNullOrWhiteSpace(connectionString) && 
                   (connectionString.Contains("Server=") || connectionString.Contains("Host="));
        }

        private bool IsValidLogLevel(string logLevel)
        {
            var validLevels = new[] { "Trace", "Debug", "Information", "Warning", "Error", "Critical", "None" };
            return Array.Exists(validLevels, level => level.Equals(logLevel, StringComparison.OrdinalIgnoreCase));
        }

        private bool IsValidInterval(string interval)
        {
            if (int.TryParse(interval, out int seconds))
            {
                return seconds >= 5 && seconds <= 3600; // 5秒到1小时
            }
            return false;
        }
    }

    public class LoggingManager : ILoggingService
    {
        private readonly ILogRepository _logRepository;
        private readonly ICachingService _cachingService;

        public LoggingManager(
            ILogRepository logRepository,
            ICachingService cachingService)
        {
            _logRepository = logRepository;
            _cachingService = cachingService;
        }

        public async Task LogAsync(LogLevel logLevel, string message, Exception exception = null, Dictionary<string, object> properties = null)
        {
            var logEntry = new LogEntry
            {
                LogLevel = logLevel,
                Message = message,
                ExceptionMessage = exception?.Message,
                StackTrace = exception?.StackTrace,
                Properties = properties,
                Timestamp = DateTime.Now,
                Category = "General"
            };

            // 异步保存到数据库
            await _logRepository.AddAsync(logEntry);

            // 控制台输出（开发环境）
            if (IsDevelopmentEnvironment())
            {
                Console.WriteLine($"[{logLevel}] {message}");
                if (exception != null)
                {
                    Console.WriteLine(exception.ToString());
                }
            }
        }

        public async Task LogErrorAsync(string message, Exception exception = null, Dictionary<string, object> properties = null)
        {
            await LogAsync(LogLevel.Error, message, exception, properties);
        }

        public async Task LogWarningAsync(string message, Dictionary<string, object> properties = null)
        {
            await LogAsync(LogLevel.Warning, message, null, properties);
        }

        public async Task LogInfoAsync(string message, Dictionary<string, object> properties = null)
        {
            await LogAsync(LogLevel.Information, message, null, properties);
        }

        public async Task LogDebugAsync(string message, Dictionary<string, object> properties = null)
        {
            await LogAsync(LogLevel.Debug, message, null, properties);
        }

        public async Task LogTraceAsync(string message, Dictionary<string, object> properties = null)
        {
            await LogAsync(LogLevel.Trace, message, null, properties);
        }

        public async Task<IEnumerable<LogEntry>> GetLogsAsync(LogLevel? logLevel = null, DateTime? startDate = null, DateTime? endDate = null, string category = null)
        {
            return await _logRepository.GetLogsAsync(logLevel, startDate, endDate, category);
        }

        public async Task<IEnumerable<LogEntry>> GetErrorLogsAsync(DateTime? startDate = null, DateTime? endDate = null)
        {
            return await _logRepository.GetLogsAsync(LogLevel.Error, startDate, endDate, null);
        }

        public async Task<int> GetLogCountAsync(LogLevel? logLevel = null, DateTime? startDate = null, DateTime? endDate = null)
        {
            return await _logRepository.GetLogCountAsync(logLevel, startDate, endDate);
        }

        public async Task ArchiveLogsAsync(int daysToKeep = 30)
        {
            var cutoffDate = DateTime.Now.AddDays(-daysToKeep);
            await _logRepository.ArchiveLogsAsync(cutoffDate);
        }

        public async Task ClearLogsAsync()
        {
            await _logRepository.ClearLogsAsync();
        }

        private bool IsDevelopmentEnvironment()
        {
            // 简单判断是否为开发环境
            return Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development";
        }
    }
}