//! `bd onboard` - Display instructions for configuring AGENTS.md.
//!
//! Outputs philosophical guidance on bd for AI agents to add to their
//! project's AGENTS.md file. Also initializes beads if in a git repo.

use std::fs;
use std::io::Write;
use std::path::Path;

use crate::Result;
use crate::daemon::ipc::{Request, Response, send_request};
use crate::repo;

/// The core philosophical content for AGENTS.md.
const AGENTS_CONTENT: &str = r#"## Issue Tracking

**bd** is infrastructure for you, the agent. It's your external memory.

A bead is a **promise**: you WILL get to this, just not now. When you're in the middle of something and notice tech debt, bugs, slop, or follow-on work that's out of scope—file a bead. Capture enough context that anyone (including future-you) can pick it up cold. Then keep going.

```bash
bd ready              # What can I work on?
bd create "..."       # Promise to handle this later
bd claim <id>         # I'm on it
bd close <id>         # Done
```

Run `bd prime` for full workflow."#;

/// Handle `bd onboard` command.
pub(crate) fn handle(output: Option<&Path>) -> Result<()> {
    // Try to init beads if we're in a git repo (idempotent)
    let init_result = try_init();

    if let Some(path) = output {
        generate_guide(path);
        println!("Generated {}", path.display());
        println!("This file is auto-generated - do not edit manually");
    } else {
        render_instructions(init_result);
    }
    Ok(())
}

/// Try to initialize beads. Returns true if init succeeded or already initialized.
fn try_init() -> bool {
    if let Ok((_repo, path)) = repo::discover() {
        let req = Request::Init { repo: path };
        matches!(send_request(&req), Ok(Response::Ok { .. }))
    } else {
        false
    }
}

fn render_instructions(initialized: bool) {
    let mut stdout = std::io::stdout().lock();

    // Bold: title
    let _ = writeln!(stdout, "\n\x1b[1mbd Onboarding\x1b[0m\n");

    // Show init status
    if initialized {
        let _ = writeln!(stdout, "\x1b[32m✓ beads initialized\x1b[0m\n");
    }

    // Yellow: instruction
    let _ = writeln!(stdout, "\x1b[33mAdd the following to AGENTS.md:\x1b[0m\n");

    // Cyan: content markers
    let _ = writeln!(stdout, "\x1b[36m--- BEGIN AGENTS.MD CONTENT ---\x1b[0m");
    let _ = writeln!(stdout, "{AGENTS_CONTENT}");
    let _ = writeln!(stdout, "\x1b[36m--- END AGENTS.MD CONTENT ---\x1b[0m\n");

    // Bold: CLAUDE.md note
    let _ = writeln!(stdout, "\x1b[1mIf CLAUDE.md exists:\x1b[0m");
    let _ = writeln!(
        stdout,
        "  Add a note referencing AGENTS.md for bd workflow.\n"
    );

    // Green: done message
    let _ = writeln!(
        stdout,
        "\x1b[32mWhen done: \"bd onboarding complete\"\x1b[0m\n"
    );
}

fn generate_guide(path: &Path) {
    let version = env!("CARGO_PKG_VERSION");

    let content = format!(
        r#"<!-- Auto-generated by bd v{version} - DO NOT EDIT MANUALLY -->
<!-- Run 'bd onboard --output <path>' to regenerate -->

# BD (Beads) Guide

This file contains bd workflow guidance for AI agents.
It is auto-generated and version-stamped.

> For project-specific instructions, see AGENTS.md in the repository root.

---

{AGENTS_CONTENT}

---

**Generated by bd v{version}**

To regenerate after upgrading bd:
```bash
bd onboard --output {path}
```
"#,
        path = path.display()
    );

    if let Some(parent) = path.parent()
        && !parent.as_os_str().is_empty()
        && !parent.exists()
    {
        let _ = fs::create_dir_all(parent);
    }

    let _ = fs::write(path, content);
}

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

    #[test]
    fn agents_content_has_key_elements() {
        assert!(AGENTS_CONTENT.contains("bd ready"));
        assert!(AGENTS_CONTENT.contains("bd create"));
        assert!(AGENTS_CONTENT.contains("bd prime"));
        assert!(AGENTS_CONTENT.contains("promise"));
        assert!(AGENTS_CONTENT.contains("external memory"));
    }
}
