//! 接入包模板分发（基线档）。
//!
//! 向项目种入 AGENTS.md / lefthook.yml / git-workflow.md 标准模板：
//! 文件不存在才写、绝不覆盖用户已有；返回每个模板的处理结果。
//! 模板蓝本取自 enterprise-system，已通用化。

use serde::{Deserialize, Serialize};
use std::path::Path;

// 标准模板（编译期内嵌）
const TMPL_AGENTS: &str = include_str!("../../resources/onboarding/AGENTS.md.tmpl");
const TMPL_LEFTHOOK: &str = include_str!("../../resources/onboarding/lefthook.yml.tmpl");
const TMPL_GIT_WORKFLOW: &str = include_str!("../../resources/onboarding/git-workflow.md.tmpl");

/// 单个模板的分发结果。
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct TemplateResult {
    /// 相对项目根的目标路径
    pub name: String,
    /// "written" | "skipped" | "failed"
    pub action: String,
    pub detail: String,
}

/// 分发单个模板：存在则跳过（绝不覆盖），不存在则写入。
fn dispatch_one(root: &Path, relative: &str, content: &str) -> TemplateResult {
    let target = root.join(relative);
    if target.exists() {
        return TemplateResult {
            name: relative.to_string(),
            action: "skipped".into(),
            detail: "已存在，未覆盖".into(),
        };
    }
    if let Some(parent) = target.parent() {
        if let Err(e) = std::fs::create_dir_all(parent) {
            return TemplateResult {
                name: relative.to_string(),
                action: "failed".into(),
                detail: format!("建目录失败: {e}"),
            };
        }
    }
    match std::fs::write(&target, content) {
        Ok(_) => TemplateResult {
            name: relative.to_string(),
            action: "written".into(),
            detail: "已写入".into(),
        },
        Err(e) => TemplateResult {
            name: relative.to_string(),
            action: "failed".into(),
            detail: format!("写入失败: {e}"),
        },
    }
}

/// 向项目分发全部基线模板，返回每个的处理结果。
/// project_path 为项目根（WSL 项目为 \\wsl.localhost\... UNC 路径，可直接写）。
pub fn dispatch_templates(project_path: &str) -> Vec<TemplateResult> {
    let root = Path::new(project_path.trim_end_matches(['/', '\\']));
    vec![
        dispatch_one(root, "AGENTS.md", TMPL_AGENTS),
        dispatch_one(root, "lefthook.yml", TMPL_LEFTHOOK),
        dispatch_one(root, "docs/ai-context/git-workflow.md", TMPL_GIT_WORKFLOW),
    ]
}

/// 接入包应用报告：模板分发结果 + buff 状态。
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct OnboardingReport {
    pub templates: Vec<TemplateResult>,
    pub buff: crate::commands::buff::BuffStatus,
}

/// 应用接入包（基线档）：分发标准模板 + 挂 buff（炼境登记 + git 观测/飞轮采集）。
#[tauri::command]
pub fn apply_onboarding_pack(
    project_path: String,
    project_id: String,
) -> Result<OnboardingReport, String> {
    let templates = dispatch_templates(&project_path);
    let buff = crate::commands::buff::apply_blueprint_buff(project_path, project_id)?;
    Ok(OnboardingReport { templates, buff })
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn writes_then_skips_never_overwrites() {
        let base = std::env::temp_dir()
            .join(format!("lianjing_onboarding_test_{}", std::process::id()));
        let _ = std::fs::remove_dir_all(&base);
        std::fs::create_dir_all(&base).unwrap();
        let pp = base.to_str().unwrap();

        // 首次：全部写入
        let r1 = dispatch_templates(pp);
        assert!(r1.iter().all(|t| t.action == "written"), "首次应全部写入");
        assert!(base.join("AGENTS.md").exists());
        assert!(base.join("lefthook.yml").exists());
        assert!(base.join("docs/ai-context/git-workflow.md").exists());

        // 改一个文件，验证再次分发不覆盖
        std::fs::write(base.join("AGENTS.md"), "用户自己的内容").unwrap();
        let r2 = dispatch_templates(pp);
        assert!(r2.iter().all(|t| t.action == "skipped"), "已存在应全部跳过");
        let kept = std::fs::read_to_string(base.join("AGENTS.md")).unwrap();
        assert_eq!(kept, "用户自己的内容", "绝不覆盖用户已有内容");

        let _ = std::fs::remove_dir_all(&base);
    }
}
