use crate::ddg::SearchResult;
use std::io::{self, IsTerminal, Write};

const BOLD: &str = "\x1b[1m";
const DIM: &str = "\x1b[2m";
const GREEN: &str = "\x1b[32m";
const CYAN: &str = "\x1b[36m";
const YELLOW: &str = "\x1b[33m";
const RESET: &str = "\x1b[0m";

pub enum Colorize {
    Auto,
    Always,
    Never,
}

fn use_color(c: &Colorize) -> bool {
    match c {
        Colorize::Always => true,
        Colorize::Never => false,
        Colorize::Auto => io::stdout().is_terminal(),
    }
}

/// ddgr-style omniprompt label: reverse-video "tag" when colored, plain
/// `name: ` otherwise. No `>` arrow — that confuses people into thinking
/// they're at a shell.
pub fn omniprompt_label(name: &str, color: &Colorize) -> String {
    if use_color(color) {
        // \x1b[7m = reverse video; surrounding spaces give it a tag look.
        format!("\n\x1b[7m {name} (? for help) \x1b[0m ")
    } else {
        format!("\n{name} (? for help): ")
    }
}

pub fn print_results(results: &[SearchResult], expand: bool, color: &Colorize) {
    let stdout = io::stdout();
    let mut w = stdout.lock();
    let colored = use_color(color);
    for r in results {
        let url_disp = if expand || r.url.len() <= 80 {
            r.url.clone()
        } else {
            format!("{}…", &r.url[..79])
        };
        if colored {
            let _ = writeln!(
                w,
                "{YELLOW}{:>3}.{RESET} {BOLD}{}{RESET}\n     {GREEN}{}{RESET}\n     {CYAN}{}{RESET}\n",
                r.index, r.title, url_disp, r.abstract_
            );
        } else {
            let _ = writeln!(
                w,
                "{:>3}. {}\n     {}\n     {}\n",
                r.index, r.title, url_disp, r.abstract_
            );
        }
    }
    if results.is_empty() && colored {
        let _ = writeln!(w, "{DIM}(no results){RESET}");
    } else if results.is_empty() {
        let _ = writeln!(w, "(no results)");
    } else {
        let _ = writeln!(w);
    }
}

pub fn print_json(results: &[SearchResult]) -> anyhow::Result<()> {
    serde_json::to_writer_pretty(io::stdout(), results)?;
    println!();
    Ok(())
}
