using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Haoliang.Core.Services;
using Haoliang.Models.System;

namespace Haoliang.Api.Controllers
{
    [ApiController]
    [Route("api/v1/[controller]")]
    public class SystemController : ControllerBase
    {
        private readonly ISystemConfigService _configService;
        private readonly ILoggingService _loggingService;
        private readonly ISchedulerService _schedulerService;

        public SystemController(
            ISystemConfigService configService,
            ILoggingService loggingService,
            ISchedulerService schedulerService)
        {
            _configService = configService;
            _loggingService = loggingService;
            _schedulerService = schedulerService;
        }

        [HttpGet("config")]
        public async Task<IActionResult> GetAllConfigs()
        {
            try
            {
                var configs = await _configService.GetAllConfigsAsync();
                return Ok(ApiResponse.Success(configs));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to get system configs", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get system configs"));
            }
        }

        [HttpGet("config/{key}")]
        public async Task<IActionResult> GetConfig(string key)
        {
            try
            {
                var config = await _configService.GetConfigAsync(key);
                if (config == null)
                {
                    return NotFound(ApiResponse.NotFound($"Config '{key}' not found"));
                }
                return Ok(ApiResponse.Success(config));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to get config '{key}'", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get config"));
            }
        }

        [HttpPost("config/{key}")]
        public async Task<IActionResult> SetConfig(string key, [FromBody] SetConfigRequest request)
        {
            try
            {
                var config = await _configService.SetConfigAsync(key, request.Value);
                return Ok(ApiResponse.Success(config, "Config updated successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to set config '{key}'", ex);
                return StatusCode(500, ApiResponse.Error("Failed to set config"));
            }
        }

        [HttpDelete("config/{key}")]
        public async Task<IActionResult> DeleteConfig(string key)
        {
            try
            {
                var result = await _configService.DeleteConfigAsync(key);
                if (!result)
                {
                    return NotFound(ApiResponse.NotFound($"Config '{key}' not found"));
                }
                return Ok(ApiResponse.Success(null, "Config deleted successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to delete config '{key}'", ex);
                return StatusCode(500, ApiResponse.Error("Failed to delete config"));
            }
        }

        [HttpGet("config/{key}/exists")]
        public async Task<IActionResult> ConfigExists(string key)
        {
            try
            {
                var exists = await _configService.ConfigExistsAsync(key);
                return Ok(ApiResponse.Success(exists));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to check if config '{key}' exists", ex);
                return StatusCode(500, ApiResponse.Error("Failed to check config existence"));
            }
        }

        [HttpGet("config/category/{category}")]
        public async Task<IActionResult> GetConfigsByCategory(string category)
        {
            try
            {
                var configs = await _configService.GetConfigsByCategoryAsync(category);
                return Ok(ApiResponse.Success(configs));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to get configs by category '{category}'", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get configs by category"));
            }
        }

        [HttpPost("config/refresh")]
        public async Task<IActionResult> RefreshConfigCache()
        {
            try
            {
                await _configService.RefreshConfigCacheAsync();
                return Ok(ApiResponse.Success(null, "Config cache refreshed successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to refresh config cache", ex);
                return StatusCode(500, ApiResponse.Error("Failed to refresh config cache"));
            }
        }

        [HttpGet("logs")]
        public async Task<IActionResult> GetLogs(
            [FromQuery] LogLevel? logLevel = null,
            [FromQuery] DateTime? startDate = null,
            [FromQuery] DateTime? endDate = null,
            [FromQuery] string category = null)
        {
            try
            {
                var logs = await _loggingService.GetLogsAsync(logLevel, startDate, endDate, category);
                return Ok(ApiResponse.Success(logs));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to get logs", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get logs"));
            }
        }

        [HttpGet("logs/error")]
        public async Task<IActionResult> GetErrorLogs([FromQuery] DateTime? startDate = null, [FromQuery] DateTime? endDate = null)
        {
            try
            {
                var logs = await _loggingService.GetErrorLogsAsync(startDate, endDate);
                return Ok(ApiResponse.Success(logs));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to get error logs", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get error logs"));
            }
        }

        [HttpGet("logs/count")]
        public async Task<IActionResult> GetLogCount(
            [FromQuery] LogLevel? logLevel = null,
            [FromQuery] DateTime? startDate = null,
            [FromQuery] DateTime? endDate = null)
        {
            try
            {
                var count = await _loggingService.GetLogCountAsync(logLevel, startDate, endDate);
                return Ok(ApiResponse.Success(count));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to get log count", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get log count"));
            }
        }

        [HttpPost("logs/archive")]
        public async Task<IActionResult> ArchiveLogs([FromQuery] int daysToKeep = 30)
        {
            try
            {
                await _loggingService.ArchiveLogsAsync(daysToKeep);
                return Ok(ApiResponse.Success(null, "Logs archived successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to archive logs", ex);
                return StatusCode(500, ApiResponse.Error("Failed to archive logs"));
            }
        }

        [HttpPost("logs/clear")]
        public async Task<IActionResult> ClearLogs()
        {
            try
            {
                await _loggingService.ClearLogsAsync();
                return Ok(ApiResponse.Success(null, "Logs cleared successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to clear logs", ex);
                return StatusCode(500, ApiResponse.Error("Failed to clear logs"));
            }
        }

        [HttpGet("scheduler/tasks")]
        public async Task<IActionResult> GetScheduledTasks()
        {
            try
            {
                var tasks = await _schedulerService.GetAllScheduledTasksAsync();
                return Ok(ApiResponse.Success(tasks));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to get scheduled tasks", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get scheduled tasks"));
            }
        }

        [HttpGet("scheduler/tasks/{taskId}")]
        public async Task<IActionResult> GetScheduledTask(string taskId)
        {
            try
            {
                var task = await _schedulerService.GetTaskByIdAsync(taskId);
                if (task == null)
                {
                    return NotFound(ApiResponse.NotFound("Task not found"));
                }
                return Ok(ApiResponse.Success(task));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to get task {taskId}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get task"));
            }
        }

        [HttpPost("scheduler/tasks")]
        public async Task<IActionResult> CreateScheduledTask([FromBody] ScheduledTask task)
        {
            try
            {
                await _schedulerService.ScheduleTaskAsync(task);
                return Ok(ApiResponse.Success(task, "Task scheduled successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to create scheduled task", ex);
                return StatusCode(500, ApiResponse.Error("Failed to create scheduled task"));
            }
        }

        [HttpPost("scheduler/tasks/{taskId}/execute")]
        public async Task<IActionResult> ExecuteTask(string taskId)
        {
            try
            {
                await _schedulerService.ExecuteTaskAsync(taskId);
                return Ok(ApiResponse.Success(null, "Task execution started"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to execute task {taskId}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to execute task"));
            }
        }

        [HttpPost("scheduler/tasks/{taskId}/remove")]
        public async Task<IActionResult> RemoveTask(string taskId)
        {
            try
            {
                var result = await _schedulerService.RemoveTaskAsync(taskId);
                if (!result)
                {
                    return NotFound(ApiResponse.NotFound("Task not found"));
                }
                return Ok(ApiResponse.Success(null, "Task removed successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync($"Failed to remove task {taskId}", ex);
                return StatusCode(500, ApiResponse.Error("Failed to remove task"));
            }
        }

        [HttpPost("scheduler/start")]
        public async Task<IActionResult> StartScheduler()
        {
            try
            {
                await _schedulerService.StartSchedulerAsync();
                return Ok(ApiResponse.Success(null, "Scheduler started successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to start scheduler", ex);
                return StatusCode(500, ApiResponse.Error("Failed to start scheduler"));
            }
        }

        [HttpPost("scheduler/stop")]
        public async Task<IActionResult> StopScheduler()
        {
            try
            {
                await _schedulerService.StopSchedulerAsync();
                return Ok(ApiResponse.Success(null, "Scheduler stopped successfully"));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to stop scheduler", ex);
                return StatusCode(500, ApiResponse.Error("Failed to stop scheduler"));
            }
        }

        [HttpGet("status")]
        public async Task<IActionResult> GetSystemStatus()
        {
            try
            {
                var status = new SystemStatus
                {
                    Timestamp = DateTime.Now,
                    Uptime = DateTime.Now - new DateTime(2024, 1, 1),
                    MemoryUsage = GetMemoryUsage(),
                    CpuUsage = GetCpuUsage(),
                    DatabaseConnections = GetDatabaseConnections(),
                    ActiveConnections = GetActiveConnections(),
                    LastBackupTime = GetLastBackupTime(),
                    SystemVersion = "1.0.0",
                    IsHealthy = IsSystemHealthy()
                };

                return Ok(ApiResponse.Success(status));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to get system status", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get system status"));
            }
        }

        [HttpGet("health")]
        public async Task<IActionResult> GetSystemHealth()
        {
            try
            {
                var health = new SystemHealth
                {
                    Status = IsSystemHealthy() ? "Healthy" : "Unhealthy",
                    Checks = await PerformHealthChecksAsync(),
                    Timestamp = DateTime.Now
                };

                return Ok(ApiResponse.Success(health));
            }
            catch (Exception ex)
            {
                await _loggingService.LogErrorAsync("Failed to get system health", ex);
                return StatusCode(500, ApiResponse.Error("Failed to get system health"));
            }
        }

        private double GetMemoryUsage()
        {
            // 简化的内存使用率获取
            return 65.5; // 示例值
        }

        private double GetCpuUsage()
        {
            // 简化的CPU使用率获取
            return 25.3; // 示例值
        }

        private int GetDatabaseConnections()
        {
            // 简化的数据库连接数获取
            return 15; // 示例值
        }

        private int GetActiveConnections()
        {
            // 简化的活跃连接数获取
            return 8; // 示例值
        }

        private DateTime? GetLastBackupTime()
        {
            // 简化的最后备份时间获取
            return DateTime.Now.AddDays(-1); // 示例值
        }

        private bool IsSystemHealthy()
        {
            // 简化的系统健康检查
            return true;
        }

        private async Task<IEnumerable<HealthCheck>> PerformHealthChecksAsync()
        {
            var checks = new List<HealthCheck>();

            // 数据库连接检查
            checks.Add(new HealthCheck
            {
                Name = "Database",
                Status = "Healthy",
                Message = "Database connection is normal"
            });

            // 磁盘空间检查
            checks.Add(new HealthCheck
            {
                Name = "Disk Space",
                Status = "Healthy",
                Message = "Disk space is sufficient"
            });

            // 内存使用检查
            checks.Add(new HealthCheck
            {
                Name = "Memory",
                Status = "Healthy",
                Message = "Memory usage is normal"
            });

            // 服务状态检查
            checks.Add(new HealthCheck
            {
                Name = "Services",
                Status = "Healthy",
                Message = "All services are running"
            });

            return checks;
        }
    }

    public class SetConfigRequest
    {
        public string Value { get; set; }
    }

    public class SystemStatus
    {
        public DateTime Timestamp { get; set; }
        public TimeSpan Uptime { get; set; }
        public double MemoryUsage { get; set; }
        public double CpuUsage { get; set; }
        public int DatabaseConnections { get; set; }
        public int ActiveConnections { get; set; }
        public DateTime? LastBackupTime { get; set; }
        public string SystemVersion { get; set; }
        public bool IsHealthy { get; set; }
    }

    public class SystemHealth
    {
        public string Status { get; set; }
        public IEnumerable<HealthCheck> Checks { get; set; }
        public DateTime Timestamp { get; set; }
    }

    public class HealthCheck
    {
        public string Name { get; set; }
        public string Status { get; set; }
        public string Message { get; set; }
    }
}