//! `adom-parts-search install` — deploy SKILL.md + BUILD-SKILL.md + bash completions.
//!
//! Per adom-cli-design: skills are NOT embedded in the binary — they
//! live as independent assets on the wiki and are fetched at install
//! time. Prose changes often; a binary rebuild + release shouldn't be
//! required for a typo fix. Only fall back to the bundled copy when the
//! wiki is unreachable (network outage) so fresh installs still work
//! offline or during migrations.

use crate::{ok, warn};
use clap::CommandFactory;
use clap_complete::Shell;
use std::fs;
use std::io::Write;
use std::path::PathBuf;
use std::time::Duration;

// SAFETY NET only — do not rely on these for day-to-day release
// propagation. The wiki-hosted copy at
//   https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-parts-search/SKILL.md
// is authoritative.
const FALLBACK_SKILL_MD: &str = include_str!("../SKILL.md");
const FALLBACK_BUILD_SKILL_MD: &str = include_str!("../BUILD-SKILL.md");

const WIKI_SKILL_URL: &str = "https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-parts-search/SKILL.md";
const WIKI_BUILD_SKILL_URL: &str = "https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-parts-search/BUILD-SKILL.md";

fn fetch_or_fallback(url: &str, fallback: &'static str, label: &str) -> String {
    let agent = ureq::AgentBuilder::new().timeout(Duration::from_secs(5)).build();
    match agent.get(url).call() {
        Ok(r) => match r.into_string() {
            Ok(body) if body.len() >= 200 => body,
            _ => {
                warn(format!("wiki returned short/unreadable {label} — using bundled fallback"));
                fallback.to_string()
            }
        },
        Err(_) => {
            warn(format!("wiki unreachable, installing bundled {label} (may be stale — re-run `adom-parts-search install` once network is up)"));
            fallback.to_string()
        }
    }
}

pub fn install() -> Result<(), String> {
    let home = std::env::var("HOME").map_err(|_| "HOME env var not set".to_string())?;
    let skills_root = PathBuf::from(&home).join(".claude").join("skills");

    // 1a. User-facing skill (fetched from wiki; bundled copy is fallback)
    let skill_md = fetch_or_fallback(WIKI_SKILL_URL, FALLBACK_SKILL_MD, "SKILL.md");
    let skill_dir = skills_root.join("adom-parts-search");
    fs::create_dir_all(&skill_dir).map_err(|e| format!("create {}: {}", skill_dir.display(), e))?;
    let skill_path = skill_dir.join("SKILL.md");
    fs::write(&skill_path, &skill_md).map_err(|e| format!("write {}: {}", skill_path.display(), e))?;
    ok(format!("installed skill → {} ({} bytes)", skill_path.display(), skill_md.len()));

    // 1b. Build skill (per-app release workflow)
    let build_skill_md = fetch_or_fallback(WIKI_BUILD_SKILL_URL, FALLBACK_BUILD_SKILL_MD, "BUILD-SKILL.md");
    let build_skill_dir = skills_root.join("adom-parts-search-build");
    fs::create_dir_all(&build_skill_dir)
        .map_err(|e| format!("create {}: {}", build_skill_dir.display(), e))?;
    let build_skill_path = build_skill_dir.join("SKILL.md");
    fs::write(&build_skill_path, &build_skill_md)
        .map_err(|e| format!("write {}: {}", build_skill_path.display(), e))?;
    ok(format!("installed build skill → {} ({} bytes)", build_skill_path.display(), build_skill_md.len()));

    // 2. Bash completions
    let comp_dir = PathBuf::from(&home)
        .join(".local")
        .join("share")
        .join("bash-completion")
        .join("completions");
    fs::create_dir_all(&comp_dir).map_err(|e| format!("create {}: {}", comp_dir.display(), e))?;
    let comp_path = comp_dir.join("adom-parts-search");
    let mut cmd = crate::Cli::command();
    let mut buf: Vec<u8> = Vec::new();
    clap_complete::generate(Shell::Bash, &mut cmd, "adom-parts-search", &mut buf);
    fs::write(&comp_path, &buf).map_err(|e| format!("write {}: {}", comp_path.display(), e))?;
    ok(format!("installed completions → {}", comp_path.display()));

    // 3. Append eval to .bashrc once
    let bashrc = PathBuf::from(&home).join(".bashrc");
    let current = fs::read_to_string(&bashrc).unwrap_or_default();
    if !current.contains("# adom-parts-search completions") {
        match fs::OpenOptions::new().append(true).open(&bashrc) {
            Ok(mut f) => {
                let _ = f.write_all(b"\n# adom-parts-search completions\neval \"$(adom-parts-search completions bash 2>/dev/null)\"\n");
                ok("appended completion source line to ~/.bashrc (open a new shell for it to take effect)");
            }
            Err(e) => warn(format!(".bashrc: {}", e)),
        }
    }

    Ok(())
}