use crate::config::{AppConfig, Environment, ServiceType};
use crate::error::Result;
use crate::output::{create_table, is_json_output, output_success, print_title, Timer};
use clap::{Args, Subcommand};
use colored::*;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use std::time::Instant;

// DEBUG_KEY - 从 Infisical 共享配置
const DEBUG_KEY: &str = "7eede5747b6c50f1c8f2358b98462f74696cdef9bfeab85eaf7ea41166788b5c";

#[derive(Args)]
pub struct ObserveCommand {
    #[command(subcommand)]
    command: ObserveSubcommand,
}

#[derive(Subcommand)]
enum ObserveSubcommand {
    /// Enhanced health check (optima-core endpoints)
    Health(HealthCommand),
    /// Get service debug info (/debug/info)
    Info(InfoCommand),
    /// Get service config info (/debug/config)
    Config(ConfigCommand),
}

#[derive(Args)]
struct HealthCommand {
    /// Environment (ec2-prod/ecs-stage/ecs-prod)
    #[arg(long)]
    env: Option<String>,

    /// Specific service name
    #[arg(long)]
    service: Option<String>,

    /// Service type filter (core/mcp/all)
    #[arg(long, default_value = "core")]
    r#type: String,

    /// Output in JSON format
    #[arg(long)]
    json: bool,
}

#[derive(Args)]
struct InfoCommand {
    /// Environment (ec2-prod/ecs-stage/ecs-prod)
    #[arg(long)]
    env: Option<String>,

    /// Specific service name
    #[arg(long)]
    service: Option<String>,

    /// Service type filter (core/mcp/all)
    #[arg(long, default_value = "core")]
    r#type: String,

    /// Output in JSON format
    #[arg(long)]
    json: bool,
}

#[derive(Args)]
struct ConfigCommand {
    /// Service name (required)
    #[arg(long)]
    service: String,

    /// Environment (ec2-prod/ecs-stage/ecs-prod)
    #[arg(long)]
    env: Option<String>,

    /// Custom DEBUG_KEY
    #[arg(long)]
    key: Option<String>,

    /// Filter config items (regex)
    #[arg(long)]
    filter: Option<String>,

    /// Output in JSON format
    #[arg(long)]
    json: bool,
}

#[derive(Debug, Serialize, Deserialize)]
struct DebugInfo {
    build: Option<BuildInfo>,
    runtime: Option<RuntimeInfo>,
    startup_time: Option<String>,
    uptime_seconds: Option<f64>,
}

#[derive(Debug, Serialize, Deserialize)]
struct BuildInfo {
    git_commit: Option<String>,
    git_branch: Option<String>,
    build_date: Option<String>,
    version: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
struct RuntimeInfo {
    python_version: Option<String>,
    node_version: Option<String>,
    environment: Option<String>,
    debug_mode: Option<bool>,
    log_level: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
struct DebugConfig {
    config: Option<std::collections::HashMap<String, String>>,
    infisical_enabled: Option<bool>,
    config_source: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
struct HealthResponse {
    status: Option<String>,
    service: Option<String>,
    version: Option<String>,
    git_commit: Option<String>,
    git_branch: Option<String>,
    environment: Option<String>,
    uptime_seconds: Option<f64>,
    timestamp: Option<String>,
    checks: Option<std::collections::HashMap<String, serde_json::Value>>,
}

impl ObserveCommand {
    pub async fn execute(&self, config: &AppConfig) -> Result<()> {
        match &self.command {
            ObserveSubcommand::Health(cmd) => cmd.execute(config).await,
            ObserveSubcommand::Info(cmd) => cmd.execute(config).await,
            ObserveSubcommand::Config(cmd) => cmd.execute(config).await,
        }
    }
}

impl HealthCommand {
    async fn execute(&self, config: &AppConfig) -> Result<()> {
        let mut timer = Timer::new();

        let env = self
            .env
            .as_ref()
            .and_then(|e| Environment::from_str(e))
            .unwrap_or_else(|| config.get_environment());

        // 获取服务列表
        let services = if let Some(service_name) = &self.service {
            vec![config.get_service(service_name).ok_or_else(|| {
                crate::error::OpsCLIError::Validation(format!("未知服务: {}", service_name))
            })?]
        } else {
            match self.r#type.as_str() {
                "core" => config.get_services_by_type(ServiceType::Core),
                "mcp" => config.get_services_by_type(ServiceType::MCP),
                _ => config.get_all_services(),
            }
        };

        timer.step("加载配置");

        if !is_json_output() && !self.json {
            print_title(&format!("🔍 增强健康检查 - {} 环境", env.as_str()));
            println!("{}", "调用 /health 端点获取详细信息\n".white());
        }

        let client = Client::builder()
            .timeout(std::time::Duration::from_secs(10))
            .build()?;

        let mut results = Vec::new();

        for service in &services {
            let start_time = Instant::now();
            let health_url = &service.health_endpoint;

            if !is_json_output() && !self.json {
                println!("{}", service.name.cyan());
                println!("{}", "─".repeat(40).white());
            }

            match client.get(health_url).send().await {
                Ok(response) => {
                    let response_time = start_time.elapsed();
                    let status_code = response.status().as_u16();

                    if status_code == 200 {
                        if let Ok(health_data) = response.json::<HealthResponse>().await {
                            let mut result = serde_json::json!({
                                "service": service.name,
                                "url": health_url,
                                "status": "ok",
                                "response_time": format!("{}ms", response_time.as_millis()),
                            });

                            // 合并健康响应数据
                            if let Some(version) = &health_data.version {
                                result["version"] = serde_json::json!(version);
                            }
                            if let Some(git_commit) = &health_data.git_commit {
                                result["git_commit"] = serde_json::json!(git_commit);
                            }
                            if let Some(git_branch) = &health_data.git_branch {
                                result["git_branch"] = serde_json::json!(git_branch);
                            }
                            if let Some(uptime) = health_data.uptime_seconds {
                                result["uptime_seconds"] = serde_json::json!(uptime);
                            }
                            if let Some(checks) = &health_data.checks {
                                result["checks"] = serde_json::json!(checks);
                            }

                            results.push(result.clone());

                            if !is_json_output() && !self.json {
                                println!("  {} 健康", "✓".green());
                                if let Some(version) = &health_data.version {
                                    println!("  版本: {}", version.green());
                                }
                                if let Some(git_commit) = &health_data.git_commit {
                                    println!("  Commit: {}", git_commit[..7.min(git_commit.len())].yellow());
                                }
                                if let Some(git_branch) = &health_data.git_branch {
                                    println!("  分支: {}", git_branch.cyan());
                                }
                                if let Some(uptime) = health_data.uptime_seconds {
                                    println!("  运行时长: {}", format_uptime(uptime).green());
                                }
                                if let Some(checks) = &health_data.checks {
                                    println!("  依赖检查:");
                                    for (name, status) in checks {
                                        let status_str = status.get("status")
                                            .and_then(|s| s.as_str())
                                            .unwrap_or("unknown");
                                        let status_colored = if status_str == "healthy" {
                                            format!("✓ {}", status_str).green().to_string()
                                        } else {
                                            format!("✗ {}", status_str).red().to_string()
                                        };
                                        println!("    {}: {}", name, status_colored);
                                    }
                                }
                                println!("  响应时间: {}ms", response_time.as_millis());
                                println!();
                            }
                        } else {
                            // 无法解析响应，但状态码是 200
                            results.push(serde_json::json!({
                                "service": service.name,
                                "url": health_url,
                                "status": "ok",
                                "response_time": format!("{}ms", response_time.as_millis()),
                                "note": "响应格式不是 optima-core 格式",
                            }));

                            if !is_json_output() && !self.json {
                                println!("  {} 健康 (基础响应)", "✓".green());
                                println!("  响应时间: {}ms", response_time.as_millis());
                                println!("  {}", "提示: 服务未集成 optima-core".yellow());
                                println!();
                            }
                        }
                    } else {
                        results.push(serde_json::json!({
                            "service": service.name,
                            "url": health_url,
                            "status": "unhealthy",
                            "http_status": status_code,
                            "response_time": format!("{}ms", response_time.as_millis()),
                        }));

                        if !is_json_output() && !self.json {
                            println!("  {} HTTP {}", "✗".red(), status_code);
                            println!();
                        }
                    }
                }
                Err(e) => {
                    let response_time = start_time.elapsed();
                    results.push(serde_json::json!({
                        "service": service.name,
                        "url": health_url,
                        "status": "error",
                        "response_time": format!("{}ms", response_time.as_millis()),
                        "error": e.to_string(),
                    }));

                    if !is_json_output() && !self.json {
                        println!("  {} {}", "✗".red(), e);
                        println!();
                    }
                }
            }
        }

        timer.step("健康检查");

        if is_json_output() || self.json {
            let ok_count = results.iter().filter(|r| r.get("status").and_then(|s| s.as_str()) == Some("ok")).count();
            output_success(serde_json::json!({
                "environment": env.as_str(),
                "services": results,
                "summary": {
                    "total": results.len(),
                    "ok": ok_count,
                    "error": results.len() - ok_count,
                },
            }))?;
        } else {
            timer.print_summary();
        }

        Ok(())
    }
}

impl InfoCommand {
    async fn execute(&self, config: &AppConfig) -> Result<()> {
        let env = self
            .env
            .as_ref()
            .and_then(|e| Environment::from_str(e))
            .unwrap_or_else(|| config.get_environment());

        // 获取服务列表
        let services = if let Some(service_name) = &self.service {
            vec![config.get_service(service_name).ok_or_else(|| {
                crate::error::OpsCLIError::Validation(format!("未知服务: {}", service_name))
            })?]
        } else {
            match self.r#type.as_str() {
                "core" => config.get_services_by_type(ServiceType::Core),
                "mcp" => config.get_services_by_type(ServiceType::MCP),
                _ => config.get_all_services(),
            }
        };

        if !is_json_output() && !self.json {
            print_title(&format!("📋 服务调试信息 - {} 环境", env.as_str()));
            println!("{}", "调用 /debug/info 端点\n".white());
        }

        let client = Client::builder()
            .timeout(std::time::Duration::from_secs(10))
            .build()?;

        let mut results = Vec::new();

        for service in &services {
            let start_time = Instant::now();
            let base_url = service.health_endpoint.replace("/health", "");
            let info_url = format!("{}/debug/info", base_url);

            if !is_json_output() && !self.json {
                println!("{}", service.name.cyan());
                println!("{}", "─".repeat(40).white());
            }

            match client.get(&info_url).send().await {
                Ok(response) => {
                    let response_time = start_time.elapsed();
                    let status_code = response.status().as_u16();

                    if status_code == 200 {
                        if let Ok(info_data) = response.json::<DebugInfo>().await {
                            let mut result = serde_json::json!({
                                "service": service.name,
                                "url": info_url,
                                "status": "ok",
                                "response_time": format!("{}ms", response_time.as_millis()),
                            });

                            if let Some(build) = &info_data.build {
                                result["build"] = serde_json::json!(build);
                            }
                            if let Some(runtime) = &info_data.runtime {
                                result["runtime"] = serde_json::json!(runtime);
                            }
                            if let Some(uptime) = info_data.uptime_seconds {
                                result["uptime_seconds"] = serde_json::json!(uptime);
                            }

                            results.push(result);

                            if !is_json_output() && !self.json {
                                // 构建信息
                                if let Some(build) = &info_data.build {
                                    println!("  {}", "构建信息:".white());
                                    if let Some(version) = &build.version {
                                        println!("    版本: {}", version.green());
                                    }
                                    if let Some(commit) = &build.git_commit {
                                        println!("    Commit: {}", commit[..7.min(commit.len())].yellow());
                                    }
                                    if let Some(branch) = &build.git_branch {
                                        println!("    分支: {}", branch.cyan());
                                    }
                                    if let Some(date) = &build.build_date {
                                        println!("    构建时间: {}", to_beijing_time(date));
                                    }
                                }

                                // 运行时信息
                                if let Some(runtime) = &info_data.runtime {
                                    println!("  {}", "运行时:".white());
                                    if let Some(py_ver) = &runtime.python_version {
                                        println!("    Python: {}", py_ver);
                                    }
                                    if let Some(node_ver) = &runtime.node_version {
                                        println!("    Node.js: {}", node_ver);
                                    }
                                    if let Some(env) = &runtime.environment {
                                        println!("    环境: {}", env);
                                    }
                                    if let Some(log_level) = &runtime.log_level {
                                        println!("    日志级别: {}", log_level);
                                    }
                                    if let Some(debug_mode) = runtime.debug_mode {
                                        let status = if debug_mode { "开启".yellow() } else { "关闭".green() };
                                        println!("    调试模式: {}", status);
                                    }
                                }

                                // 运行时长
                                if let Some(uptime) = info_data.uptime_seconds {
                                    println!("  运行时长: {}", format_uptime(uptime).green());
                                }

                                println!("  响应时间: {}ms", response_time.as_millis());
                                println!();
                            }
                        } else {
                            results.push(serde_json::json!({
                                "service": service.name,
                                "url": info_url,
                                "status": "ok",
                                "response_time": format!("{}ms", response_time.as_millis()),
                                "note": "响应格式无法解析",
                            }));

                            if !is_json_output() && !self.json {
                                println!("  {} 端点可用但格式未知", "⚠".yellow());
                                println!();
                            }
                        }
                    } else if status_code == 404 {
                        results.push(serde_json::json!({
                            "service": service.name,
                            "url": info_url,
                            "status": "not_available",
                            "response_time": format!("{}ms", response_time.as_millis()),
                            "error": "端点不存在 (未集成 optima-core)",
                        }));

                        if !is_json_output() && !self.json {
                            println!("  {} 端点不存在 - 未集成 optima-core", "⚠".yellow());
                            println!();
                        }
                    } else {
                        results.push(serde_json::json!({
                            "service": service.name,
                            "url": info_url,
                            "status": "error",
                            "http_status": status_code,
                            "response_time": format!("{}ms", response_time.as_millis()),
                        }));

                        if !is_json_output() && !self.json {
                            println!("  {} HTTP {}", "✗".red(), status_code);
                            println!();
                        }
                    }
                }
                Err(e) => {
                    let response_time = start_time.elapsed();
                    results.push(serde_json::json!({
                        "service": service.name,
                        "url": info_url,
                        "status": "error",
                        "response_time": format!("{}ms", response_time.as_millis()),
                        "error": e.to_string(),
                    }));

                    if !is_json_output() && !self.json {
                        println!("  {} {}", "✗".red(), e);
                        println!();
                    }
                }
            }
        }

        if is_json_output() || self.json {
            let ok_count = results.iter().filter(|r| r.get("status").and_then(|s| s.as_str()) == Some("ok")).count();
            let not_available = results.iter().filter(|r| r.get("status").and_then(|s| s.as_str()) == Some("not_available")).count();
            output_success(serde_json::json!({
                "environment": env.as_str(),
                "services": results,
                "summary": {
                    "total": results.len(),
                    "ok": ok_count,
                    "not_available": not_available,
                    "error": results.len() - ok_count - not_available,
                },
            }))?;
        } else {
            // 打印总结
            println!("{}", "─".repeat(60).white());
            let ok_count = results.iter().filter(|r| r.get("status").and_then(|s| s.as_str()) == Some("ok")).count();
            let not_available = results.iter().filter(|r| r.get("status").and_then(|s| s.as_str()) == Some("not_available")).count();
            let error_count = results.len() - ok_count - not_available;

            println!("{}", "总结:".white());
            println!("  {} 可用: {}", "✓".green(), ok_count);
            if not_available > 0 {
                println!("  {} 未集成: {}", "⚠".yellow(), not_available);
            }
            if error_count > 0 {
                println!("  {} 错误: {}", "✗".red(), error_count);
            }
            println!();
        }

        Ok(())
    }
}

impl ConfigCommand {
    async fn execute(&self, config: &AppConfig) -> Result<()> {
        let env = self
            .env
            .as_ref()
            .and_then(|e| Environment::from_str(e))
            .unwrap_or_else(|| config.get_environment());

        // 验证服务存在
        let service = config.get_service(&self.service).ok_or_else(|| {
            crate::error::OpsCLIError::Validation(format!("未知服务: {}", self.service))
        })?;

        let base_url = service.health_endpoint.replace("/health", "");
        let config_url = format!("{}/debug/config", base_url);

        let debug_key = self.key.as_deref().unwrap_or(DEBUG_KEY);

        if !is_json_output() && !self.json {
            print_title(&format!("🔧 服务配置 - {} ({})", self.service, env.as_str()));
            println!("{}", format!("URL: {}", config_url).white());
            println!("{}", format!("使用 DEBUG_KEY: {}...", &debug_key[..8]).white());
            println!();
        }

        let client = Client::builder()
            .timeout(std::time::Duration::from_secs(10))
            .build()?;

        let start_time = Instant::now();

        match client
            .get(&config_url)
            .header("X-Debug-Key", debug_key)
            .send()
            .await
        {
            Ok(response) => {
                let response_time = start_time.elapsed();
                let status_code = response.status().as_u16();

                if status_code == 200 {
                    if let Ok(config_data) = response.json::<DebugConfig>().await {
                        if is_json_output() || self.json {
                            output_success(serde_json::json!({
                                "environment": env.as_str(),
                                "service": self.service,
                                "url": config_url,
                                "status": "ok",
                                "response_time": format!("{}ms", response_time.as_millis()),
                                "config": config_data.config,
                                "infisical_enabled": config_data.infisical_enabled,
                                "config_source": config_data.config_source,
                            }))?;
                        } else {
                            // 配置来源
                            if let Some(source) = &config_data.config_source {
                                println!("{} {}", "配置来源:".white(), source.cyan());
                            }
                            if let Some(enabled) = config_data.infisical_enabled {
                                let status = if enabled { "已启用".green() } else { "未启用".yellow() };
                                println!("{} {}", "Infisical:".white(), status);
                            }

                            // 配置项
                            if let Some(configs) = &config_data.config {
                                println!("\n{}", "配置项:".white());
                                println!("{}", "─".repeat(60).white());

                                let mut sorted_configs: Vec<_> = configs.iter().collect();
                                sorted_configs.sort_by(|a, b| a.0.cmp(b.0));

                                // 过滤
                                let filtered: Vec<_> = if let Some(filter) = &self.filter {
                                    let regex = regex::Regex::new(filter).unwrap_or_else(|_| regex::Regex::new(".*").unwrap());
                                    sorted_configs.into_iter().filter(|(k, _)| regex.is_match(k)).collect()
                                } else {
                                    sorted_configs
                                };

                                for (key, value) in &filtered {
                                    // 高亮敏感配置
                                    let is_sensitive = key.to_lowercase().contains("key")
                                        || key.to_lowercase().contains("secret")
                                        || key.to_lowercase().contains("password")
                                        || key.to_lowercase().contains("token");

                                    let key_display = if is_sensitive {
                                        format!("{:35}", key).yellow()
                                    } else {
                                        format!("{:35}", key).white()
                                    };

                                    let value_display = if is_sensitive {
                                        value.white()
                                    } else {
                                        value.green()
                                    };

                                    println!("  {} {}", key_display, value_display);
                                }

                                println!("{}", "─".repeat(60).white());
                                println!("{}", format!("共 {} 项配置", filtered.len()).white());
                            }

                            println!("{}", format!("\n响应时间: {}ms", response_time.as_millis()).white());
                        }
                    } else {
                        if !is_json_output() && !self.json {
                            println!("{}", "无法解析配置响应".yellow());
                        }
                    }
                } else if status_code == 401 || status_code == 403 {
                    if is_json_output() || self.json {
                        output_success(serde_json::json!({
                            "environment": env.as_str(),
                            "service": self.service,
                            "url": config_url,
                            "status": "unauthorized",
                            "response_time": format!("{}ms", response_time.as_millis()),
                            "error": "DEBUG_KEY 无效或未提供",
                        }))?;
                    } else {
                        println!("{}", "✗ 认证失败: DEBUG_KEY 无效或未提供".red());
                        println!("{}", "\n提示: 使用 --key <DEBUG_KEY> 指定正确的密钥".white());
                    }
                } else if status_code == 404 {
                    if is_json_output() || self.json {
                        output_success(serde_json::json!({
                            "environment": env.as_str(),
                            "service": self.service,
                            "url": config_url,
                            "status": "not_available",
                            "response_time": format!("{}ms", response_time.as_millis()),
                            "error": "端点不存在 (未集成 optima-core)",
                        }))?;
                    } else {
                        println!("{}", "⚠ 端点不存在 - 服务未集成 optima-core".yellow());
                    }
                } else {
                    if is_json_output() || self.json {
                        output_success(serde_json::json!({
                            "environment": env.as_str(),
                            "service": self.service,
                            "url": config_url,
                            "status": "error",
                            "http_status": status_code,
                            "response_time": format!("{}ms", response_time.as_millis()),
                        }))?;
                    } else {
                        println!("{}", format!("✗ HTTP {}", status_code).red());
                    }
                }
            }
            Err(e) => {
                if is_json_output() || self.json {
                    output_success(serde_json::json!({
                        "environment": env.as_str(),
                        "service": self.service,
                        "url": config_url,
                        "status": "error",
                        "error": e.to_string(),
                    }))?;
                } else {
                    println!("{}", format!("✗ 错误: {}", e).red());
                }
            }
        }

        Ok(())
    }
}

/// 格式化运行时长
fn format_uptime(seconds: f64) -> String {
    let secs = seconds as u64;
    let days = secs / 86400;
    let hours = (secs % 86400) / 3600;
    let minutes = (secs % 3600) / 60;
    let remaining_secs = secs % 60;

    let mut parts = Vec::new();
    if days > 0 {
        parts.push(format!("{}天", days));
    }
    if hours > 0 {
        parts.push(format!("{}小时", hours));
    }
    if minutes > 0 {
        parts.push(format!("{}分钟", minutes));
    }
    if parts.is_empty() {
        parts.push(format!("{}秒", remaining_secs));
    }

    parts.join(" ")
}

/// 将 UTC 时间转换为北京时间
fn to_beijing_time(utc_time_str: &str) -> String {
    use chrono::{DateTime, FixedOffset, Utc};

    if let Ok(dt) = DateTime::parse_from_rfc3339(utc_time_str) {
        let beijing_offset = FixedOffset::east_opt(8 * 3600).unwrap();
        let beijing_time = dt.with_timezone(&beijing_offset);
        format!("{} (北京时间)", beijing_time.format("%Y-%m-%d %H:%M:%S"))
    } else {
        utc_time_str.to_string()
    }
}
