use crate::db::pool;
use crate::models::GitRepo;
use rusqlite::params;
use serde::Deserialize;

// ── 输入结构体 ─────────────────────────────────────────────────────────────────

#[derive(Debug, Deserialize)]
pub struct ImportGitRepoInput {
    pub id: String,
    pub repo_url: String,
    pub name: String,
    pub description: Option<String>,
    pub default_branch: Option<String>,
    pub upstream_url: Option<String>,
    pub tech_stack: Option<String>,
}

#[derive(Debug, Deserialize)]
pub struct UpdateGitRepoDeployInput {
    pub staging_url: Option<String>,
    pub prod_url: Option<String>,
    pub server_note: Option<String>,
    pub upstream_url: Option<String>,
    pub tech_stack: Option<String>,
    pub status: Option<String>,
    pub priority: Option<String>,
}

#[derive(Debug, Deserialize)]
pub struct MountRepoInput {
    /// 新 workspace 的 id（前端传 UUID）
    pub workspace_id: String,
    pub repo_id: String,
    pub space_id: Option<String>,
    pub win_path: Option<String>,
    pub wsl_path: Option<String>,
    pub platform: Option<String>,
}

// ── 命令实现 ───────────────────────────────────────────────────────────────────

/// 获取所有已注册仓库
#[tauri::command]
pub fn get_git_repos() -> Result<Vec<GitRepo>, String> {
    let conn = pool().get().map_err(|e| e.to_string())?;
    let mut stmt = conn
        .prepare("SELECT * FROM git_repos ORDER BY created_at DESC")
        .map_err(|e| e.to_string())?;
    let rows = stmt
        .query_map([], GitRepo::from_row)
        .map_err(|e| e.to_string())?
        .collect::<rusqlite::Result<Vec<_>>>()
        .map_err(|e| e.to_string())?;
    Ok(rows)
}

/// 批量导入 GitHub 仓库（INSERT OR IGNORE，幂等）
#[tauri::command]
pub fn import_git_repos(repos: Vec<ImportGitRepoInput>) -> Result<Vec<String>, String> {
    let conn = pool().get().map_err(|e| e.to_string())?;
    let mut imported = Vec::new();
    for r in repos {
        let affected = conn
            .execute(
                "INSERT OR IGNORE INTO git_repos
                    (id, repo_url, name, description, default_branch, upstream_url, tech_stack,
                     last_synced_at)
                 VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, datetime('now'))",
                params![
                    r.id,
                    r.repo_url,
                    r.name,
                    r.description,
                    r.default_branch,
                    r.upstream_url,
                    r.tech_stack,
                ],
            )
            .map_err(|e| e.to_string())?;
        if affected > 0 {
            imported.push(r.id);
        }
    }
    Ok(imported)
}

/// 更新仓库部署信息（staging_url, prod_url, server_note, upstream_url 等）
#[tauri::command]
pub fn update_git_repo_deploy(id: String, input: UpdateGitRepoDeployInput) -> Result<(), String> {
    let conn = pool().get().map_err(|e| e.to_string())?;
    conn.execute(
        "UPDATE git_repos SET
            staging_url  = COALESCE(?2, staging_url),
            prod_url     = COALESCE(?3, prod_url),
            server_note  = COALESCE(?4, server_note),
            upstream_url = COALESCE(?5, upstream_url),
            tech_stack   = COALESCE(?6, tech_stack),
            status       = COALESCE(?7, status),
            priority     = COALESCE(?8, priority)
         WHERE id = ?1",
        params![
            id,
            input.staging_url,
            input.prod_url,
            input.server_note,
            input.upstream_url,
            input.tech_stack,
            input.status,
            input.priority,
        ],
    )
    .map_err(|e| e.to_string())?;
    Ok(())
}

/// 将仓库挂载到某个空间（创建 workspace + profile）
#[tauri::command]
pub fn mount_repo(input: MountRepoInput) -> Result<(), String> {
    let conn = pool().get().map_err(|e| e.to_string())?;

    // 读取 git_repo 基础信息
    let repo: GitRepo = conn
        .query_row(
            "SELECT * FROM git_repos WHERE id = ?1",
            params![input.repo_id],
            GitRepo::from_row,
        )
        .map_err(|e| format!("仓库不存在: {e}"))?;

    let profile_id = format!("prof-{}", input.workspace_id);

    // 创建 project_profile（若已存在则忽略）
    conn.execute(
        "INSERT OR IGNORE INTO project_profiles
            (id, name, description, repo_url, upstream_url, default_branch,
             staging_url, prod_url, server_note, status, priority, tech_stack)
         VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)",
        params![
            profile_id,
            repo.name,
            repo.description,
            repo.repo_url,
            repo.upstream_url,
            repo.default_branch,
            repo.staging_url,
            repo.prod_url,
            repo.server_note,
            repo.status.as_deref().unwrap_or("active"),
            repo.priority.as_deref().unwrap_or("mid"),
            repo.tech_stack,
        ],
    )
    .map_err(|e| e.to_string())?;

    let platform = input.platform.as_deref().unwrap_or("windows");

    // 创建 project_workspace（若同一 space 已挂载则报错）
    conn.execute(
        "INSERT INTO project_workspaces
            (id, profile_id, repo_id, space_id, win_path, wsl_path, platform)
         VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
        params![
            input.workspace_id,
            profile_id,
            input.repo_id,
            input.space_id,
            input.win_path,
            input.wsl_path,
            platform,
        ],
    )
    .map_err(|e| {
        if e.to_string().contains("UNIQUE") {
            "该仓库已在此空间中挂载".to_string()
        } else {
            e.to_string()
        }
    })?;

    Ok(())
}

/// 删除仓库注册记录（同时删除关联的 workspace/profile）
#[tauri::command]
pub fn delete_git_repo(id: String) -> Result<(), String> {
    let conn = pool().get().map_err(|e| e.to_string())?;
    conn.execute("DELETE FROM git_repos WHERE id = ?1", params![id])
        .map_err(|e| e.to_string())?;
    Ok(())
}
