//! Terminal display helpers for the REPL.

use super::conversation::StoredMessage;
use super::session::SessionState;

// ANSI color codes
const RESET: &str = "\x1b[0m";
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";

/// Print the REPL prompt showing the active conversation and unread count.
pub fn print_prompt(session: &SessionState) {
    use std::io::Write;
    let name = session
        .active_display_name()
        .unwrap_or_else(|| "no conversation".into());
    let unread = session.total_unread();
    if unread > 0 {
        print!("{DIM}[{RESET}{BOLD}{name}{RESET} {YELLOW}{unread} unread{RESET}{DIM}]{RESET} > ");
    } else {
        print!("{DIM}[{RESET}{BOLD}{name}{RESET}{DIM}]{RESET} > ");
    }
    let _ = std::io::stdout().flush();
}

/// Print an incoming or outgoing message.
pub fn print_message(msg: &StoredMessage) {
    let body = if msg.msg_type == "reaction" {
        format!("reacted {}", msg.body)
    } else {
        msg.body.clone()
    };
    if msg.is_outgoing {
        println!("\r{GREEN}> {body}{RESET}");
    } else {
        let fallback = hex::encode(&msg.sender_key[..4]);
        let sender = msg.sender_name.as_deref().unwrap_or(&fallback);
        println!("\r{CYAN}{BOLD}[{sender}]{RESET} {body}");
    }
}

/// Print a message received in real-time (clears current line first).
pub fn print_incoming(sender: &str, body: &str) {
    use std::io::Write;
    // Clear current line, print message, then re-show prompt context
    print!("\r\x1b[2K");
    println!("{CYAN}{BOLD}[{sender}]{RESET} {body}");
    let _ = std::io::stdout().flush();
}

/// Print a system/status message.
pub fn print_status(msg: &str) {
    println!("{DIM}  {msg}{RESET}");
}

/// Print a transient typing indicator (clears current line first).
pub fn print_typing(sender: &str) {
    use std::io::Write;
    print!("\r\x1b[2K");
    println!("{DIM}  {sender} is typing...{RESET}");
    let _ = std::io::stdout().flush();
}

/// Print an error message.
pub fn print_error(msg: &str) {
    println!("{YELLOW}  error: {msg}{RESET}");
}

/// Format a conversation list entry for `/list`.
pub fn format_conv_line(display_name: &str, kind: &str, unread: u32, members: usize) -> String {
    let unread_str = if unread > 0 {
        format!(" {YELLOW}({unread} new){RESET}")
    } else {
        String::new()
    };
    format!(
        "  {BOLD}{display_name}{RESET} {DIM}[{kind}, {members} members]{RESET}{unread_str}"
    )
}
