use crate::db::pool;
use rusqlite::params;
use std::path::Path;
use std::process::Command;

/// 将 UNC WSL 路径转换为 Linux 路径
/// \\wsl.localhost\Ubuntu\home\user\proj  →  /home/user/proj
/// \\wsl$\Ubuntu\home\user\proj           →  /home/user/proj
/// /home/user/proj                        →  /home/user/proj（直接返回）
fn unc_to_linux(path: &str) -> String {
    for prefix in &["\\\\wsl.localhost\\", "\\\\wsl$\\"] {
        if path.to_lowercase().starts_with(&prefix.to_lowercase()) {
            let rest = &path[prefix.len()..];
            // 去掉 distro 名（第一段），剩余部分转 /
            let after_distro = rest.splitn(2, '\\').nth(1).unwrap_or("");
            return format!("/{}", after_distro.replace('\\', "/"));
        }
    }
    // 已经是 Linux 路径，直接返回
    path.to_string()
}

fn get_setting(key: &str) -> Option<String> {
    let conn = pool().get().ok()?;
    // 先查全局 settings 表
    if let Ok(val) = conn.query_row(
        "SELECT value FROM settings WHERE key = ?1",
        params![key],
        |row| row.get::<_, String>(0),
    ) {
        if !val.is_empty() {
            return Some(val);
        }
    }
    // 兼容旧数据：回退查 space_settings（任意空间取第一条）
    conn.query_row(
        "SELECT value FROM space_settings WHERE key = ?1 LIMIT 1",
        params![key],
        |row| row.get::<_, String>(0),
    ).ok()
}

#[tauri::command]
pub fn open_editor(project_id: String, env: String, editor_path: String) -> Result<String, String> {
    let conn = pool().get().map_err(|e| e.to_string())?;
    let (wsl_path, win_path): (Option<String>, Option<String>) = conn
        .query_row(
            "SELECT wsl_path, win_path FROM project_workspaces WHERE id = ?1",
            params![project_id],
            |row| Ok((row.get(0)?, row.get(1)?)),
        )
        .map_err(|_| format!("Project not found: {project_id}"))?;

    let wsl_distro = get_setting("wsl_distro").unwrap_or_else(|| "Ubuntu".into());

    // WSL 环境：按 wsl_open_mode 配置自适应启动
    // wsl_internal  (默认): wsl -d <distro> -- <editor> <linux_path>
    // remote_flag         : <editor> --remote wsl+<distro> <linux_path>
    // unc_path            : <editor> <unc_path>（直接用 UNC 路径，不走 Remote）
    if env == "wsl" {
        let path = wsl_path.ok_or("WSL path not configured")?;
        let open_mode = get_setting("wsl_open_mode")
            .unwrap_or_else(|| "wsl_internal".into());

        if open_mode == "wsl_internal" {
            // 直接调用 wsl 进程，用参数数组传路径，避免 cmd /c 的引号转义问题
            let linux_path = unc_to_linux(&path);
            let cmd_name = std::path::Path::new(&editor_path)
                .file_stem()
                .and_then(|s| s.to_str())
                .map(|s| s.to_lowercase())
                .unwrap_or_else(|| editor_path.clone());
            Command::new("wsl")
                .args(["-d", &wsl_distro, "--", &cmd_name, &linux_path])
                .spawn()
                .map_err(|e| format!("无法启动编辑器: {e}"))?;
            return Ok(format!("wsl -d {} -- {} {}", wsl_distro, cmd_name, linux_path));
        }

        let cmd_str = match open_mode.as_str() {
            "remote_flag" => {
                let linux_path = unc_to_linux(&path);
                format!("\"{}\" --remote wsl+{} \"{}\"", editor_path, wsl_distro, linux_path)
            }
            _ => {
                // unc_path：直接用原始路径，不走 Remote
                format!("\"{}\" \"{}\"", editor_path, path)
            }
        };

        Command::new("cmd")
            .args(["/c", &cmd_str])
            .spawn()
            .map_err(|e| format!("无法启动编辑器: {e}"))?;
        return Ok(cmd_str);
    }

    let args: Vec<String> = match env.as_str() {
        "win" => {
            let path = win_path.ok_or("Windows path not configured")?;
            vec![path]
        }
        _ => return Err(format!("Unknown env: {env}")),
    };

    // Windows 上编辑器可能是 .cmd 脚本，通过 cmd /c 让 shell 解析
    #[cfg(target_os = "windows")]
    let spawn_result = Command::new("cmd")
        .args(["/c", &editor_path])
        .args(&args)
        .spawn();

    #[cfg(not(target_os = "windows"))]
    let spawn_result = Command::new(&editor_path).args(&args).spawn();

    spawn_result.map_err(|e| {
        format!("无法启动编辑器 \"{editor_path}\": {e}\n请在设置中检查编辑器路径是否正确")
    })?;

    Ok(format!("{editor_path} {}", args.join(" ")))
}

#[tauri::command]
pub fn open_terminal(project_id: String, env: String) -> Result<String, String> {
    let conn = pool().get().map_err(|e| e.to_string())?;
    let (wsl_path, win_path): (Option<String>, Option<String>) = conn
        .query_row(
            "SELECT wsl_path, win_path FROM project_workspaces WHERE id = ?1",
            params![project_id],
            |row| Ok((row.get(0)?, row.get(1)?)),
        )
        .map_err(|_| format!("Project not found: {project_id}"))?;

    let wsl_distro = get_setting("wsl_distro").unwrap_or_else(|| "Ubuntu".into());

    let args: Vec<String> = match env.as_str() {
        "wsl" => {
            let path = wsl_path.ok_or("WSL path not configured")?;
            vec!["-p".into(), wsl_distro, "--".into(), "wsl".into(), "--cd".into(), path]
        }
        "win" => {
            let path = win_path.ok_or("Windows path not configured")?;
            if Path::new(&path).exists() {
                vec!["-p".into(), "PowerShell".into(), "-d".into(), path]
            } else {
                vec!["-p".into(), "PowerShell".into()]
            }
        }
        _ => return Err(format!("Unknown env: {env}")),
    };

    #[cfg(target_os = "windows")]
    let term_result = Command::new("cmd").args(["/c", "wt"]).args(&args).spawn();

    #[cfg(not(target_os = "windows"))]
    let term_result = Command::new("wt").args(&args).spawn();

    term_result.map_err(|e| format!("无法启动终端: {e}"))?;

    Ok(format!("wt {}", args.join(" ")))
}
