//! init 模块 - 初始化配置和凭证
//!
//! 从 AWS SSM Parameter Store 拉取凭证到本地

use crate::config::AppConfig;
use crate::error::Result;
use crate::output::{print_section, print_title, Timer};
use anyhow::Context;
use clap::Args;
use colored::Colorize;
use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::path::PathBuf;
use std::process::Command;

/// init 命令 - 初始化本地配置
#[derive(Args)]
pub struct InitCommand {
    /// 强制覆盖已有配置
    #[arg(long, short = 'f')]
    force: bool,

    /// 跳过 SSH 密钥设置
    #[arg(long)]
    skip_ssh: bool,

    /// 指定用户名 (用于个人 SSH 密钥)
    #[arg(long)]
    user: Option<String>,
}

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

        print_title("🚀 初始化 Optima Ops CLI");
        println!();

        // 检查 AWS CLI 是否可用
        self.check_aws_cli()?;
        timer.step("检查 AWS CLI");

        // 1. 创建配置目录
        let config_dir = self.setup_config_dir()?;
        timer.step("创建配置目录");

        // 2. 拉取 SSH 密钥
        if !self.skip_ssh {
            self.setup_ssh_key()?;
            timer.step("配置 SSH 密钥");
        }

        // 3. 生成配置文件 (如果不存在)
        self.generate_config(&config_dir)?;
        timer.step("生成配置文件");

        // 4. 验证配置
        self.verify_setup()?;
        timer.step("验证配置");

        println!();
        print_section("✓ 初始化完成");
        println!();
        println!("{}", "现在可以使用以下命令:".green());
        println!("  {} - 查看服务健康状态", "oor services health".cyan());
        println!("  {} - 查看 EC2 状态", "oor infra ec2".cyan());
        println!("  {} - 查看帮助", "oor --help".cyan());
        println!();

        timer.print_summary();

        Ok(())
    }

    fn check_aws_cli(&self) -> Result<()> {
        print_section("检查 AWS CLI");

        // 检查 aws 命令是否存在
        let output = Command::new("aws")
            .arg("--version")
            .output()
            .context("AWS CLI 未安装，请先安装: https://aws.amazon.com/cli/")?;

        if !output.status.success() {
            return Err(anyhow::anyhow!("AWS CLI 未正确安装").into());
        }

        let version = String::from_utf8_lossy(&output.stdout);
        println!("  AWS CLI: {}", version.trim().green());

        // 检查是否已配置凭证
        let creds_output = Command::new("aws")
            .args(["sts", "get-caller-identity", "--query", "Account", "--output", "text"])
            .output()
            .context("无法验证 AWS 凭证")?;

        if !creds_output.status.success() {
            println!(
                "  {}",
                "警告: AWS 凭证未配置，请先运行 'aws configure'".yellow()
            );
            return Err(anyhow::anyhow!(
                "请先配置 AWS 凭证: aws configure"
            ).into());
        }

        let account = String::from_utf8_lossy(&creds_output.stdout);
        println!("  AWS 账号: {}", account.trim().green());

        Ok(())
    }

    fn setup_config_dir(&self) -> Result<PathBuf> {
        print_section("创建配置目录");

        let home = dirs::home_dir().context("无法获取用户目录")?;
        let config_dir = home.join(".config/optima-ops-cli");

        if !config_dir.exists() {
            fs::create_dir_all(&config_dir).context("无法创建配置目录")?;
            println!("  创建: {}", config_dir.display().to_string().green());
        } else {
            println!("  已存在: {}", config_dir.display().to_string().bright_black());
        }

        // 创建 .ssh 目录 (如果不存在)
        let ssh_dir = home.join(".ssh");
        if !ssh_dir.exists() {
            fs::create_dir_all(&ssh_dir).context("无法创建 .ssh 目录")?;
            // 设置权限为 700
            fs::set_permissions(&ssh_dir, fs::Permissions::from_mode(0o700))?;
            println!("  创建: {}", ssh_dir.display().to_string().green());
        }

        Ok(config_dir)
    }

    fn setup_ssh_key(&self) -> Result<()> {
        print_section("配置 SSH 密钥");

        let home = dirs::home_dir().context("无法获取用户目录")?;
        let ssh_key_path = home.join(".ssh/optima-ec2-key");

        // 检查是否已存在
        if ssh_key_path.exists() && !self.force {
            println!(
                "  {}",
                format!("SSH 密钥已存在: {}", ssh_key_path.display()).bright_black()
            );
            println!("  {}", "使用 --force 覆盖".bright_black());
            return Ok(());
        }

        // 从 SSM 拉取共享的 EC2 SSH 密钥
        println!("  从 SSM 拉取 EC2 SSH 密钥...");

        let output = Command::new("aws")
            .args([
                "ssm",
                "get-parameter",
                "--name",
                "/optima/ec2/ssh-private-key",
                "--with-decryption",
                "--query",
                "Parameter.Value",
                "--output",
                "text",
                "--region",
                "ap-southeast-1",
            ])
            .output()
            .context("无法从 SSM 获取 SSH 密钥")?;

        if !output.status.success() {
            let stderr = String::from_utf8_lossy(&output.stderr);
            return Err(anyhow::anyhow!("获取 SSH 密钥失败: {}", stderr).into());
        }

        let key_content = String::from_utf8_lossy(&output.stdout);

        // 写入文件
        fs::write(&ssh_key_path, key_content.as_ref())
            .context("无法写入 SSH 密钥文件")?;

        // 设置权限为 600
        fs::set_permissions(&ssh_key_path, fs::Permissions::from_mode(0o600))?;

        println!("  保存到: {}", ssh_key_path.display().to_string().green());

        // 如果指定了用户，也尝试拉取个人密钥
        if let Some(user) = &self.user {
            self.setup_personal_ssh_key(user)?;
        }

        Ok(())
    }

    fn setup_personal_ssh_key(&self, user: &str) -> Result<()> {
        println!();
        println!("  拉取个人 SSH 密钥: {}", user.cyan());

        let home = dirs::home_dir().context("无法获取用户目录")?;
        let personal_key_path = home.join(format!(".ssh/optima-{}-key", user));

        // 尝试从 SSM 获取个人密钥
        let param_name = format!("/optima/dev-machine/private-keys/{}", user);

        let output = Command::new("aws")
            .args([
                "ssm",
                "get-parameter",
                "--name",
                &param_name,
                "--with-decryption",
                "--query",
                "Parameter.Value",
                "--output",
                "text",
                "--region",
                "ap-southeast-1",
            ])
            .output();

        match output {
            Ok(result) if result.status.success() => {
                let key_content = String::from_utf8_lossy(&result.stdout);
                fs::write(&personal_key_path, key_content.as_ref())?;
                fs::set_permissions(&personal_key_path, fs::Permissions::from_mode(0o600))?;
                println!("  保存到: {}", personal_key_path.display().to_string().green());
            }
            _ => {
                println!(
                    "  {}",
                    format!("未找到个人密钥: {}", param_name).yellow()
                );
            }
        }

        Ok(())
    }

    fn generate_config(&self, config_dir: &PathBuf) -> Result<()> {
        print_section("生成配置文件");

        let config_path = config_dir.join("config.json");

        if config_path.exists() && !self.force {
            println!(
                "  {}",
                format!("配置已存在: {}", config_path.display()).bright_black()
            );
            return Ok(());
        }

        // 使用默认配置
        let config = serde_json::json!({
            "environment": "production",
            "ec2": {
                "production": {
                    "host": "ec2-prod.optima.shop",
                    "user": "ec2-user",
                    "keyPath": "~/.ssh/optima-ec2-key"
                },
                "stage": {
                    "host": "ec2-stage.optima.shop",
                    "user": "ec2-user",
                    "keyPath": "~/.ssh/optima-ec2-key"
                },
                "shared": {
                    "host": "shared.optima.onl",
                    "user": "ec2-user",
                    "keyPath": "~/.ssh/optima-ec2-key"
                },
                "development": {
                    "host": "ec2-dev.optima.shop",
                    "user": "ec2-user",
                    "keyPath": "~/.ssh/optima-ec2-key"
                }
            },
            "aws": {
                "region": "ap-southeast-1"
            }
        });

        let content = serde_json::to_string_pretty(&config)
            .context("无法序列化配置")?;
        fs::write(&config_path, content)?;

        println!("  创建: {}", config_path.display().to_string().green());

        Ok(())
    }

    fn verify_setup(&self) -> Result<()> {
        print_section("验证配置");

        let home = dirs::home_dir().context("无法获取用户目录")?;

        // 检查 SSH 密钥
        let ssh_key_path = home.join(".ssh/optima-ec2-key");
        if ssh_key_path.exists() {
            println!("  ✓ SSH 密钥: {}", "OK".green());
        } else {
            println!("  ✗ SSH 密钥: {}", "未配置".yellow());
        }

        // 检查配置文件
        let config_path = home.join(".config/optima-ops-cli/config.json");
        if config_path.exists() {
            println!("  ✓ 配置文件: {}", "OK".green());
        } else {
            println!("  ✗ 配置文件: {}", "使用默认配置".yellow());
        }

        // 测试 SSH 连接 (可选)
        println!("  测试 EC2 连接...");
        let ssh_test = Command::new("ssh")
            .args([
                "-i",
                ssh_key_path.to_str().unwrap_or(""),
                "-o",
                "StrictHostKeyChecking=no",
                "-o",
                "ConnectTimeout=5",
                "-o",
                "BatchMode=yes",
                "ec2-user@ec2-prod.optima.shop",
                "echo ok",
            ])
            .output();

        match ssh_test {
            Ok(result) if result.status.success() => {
                println!("  ✓ EC2 连接: {}", "OK".green());
            }
            _ => {
                println!("  ⚠ EC2 连接: {}", "无法验证 (可能是网络问题)".yellow());
            }
        }

        Ok(())
    }
}
