//! `ph post <id>`: View post details.

use ph_cli_core::{Client, Result};

/// Execute the post command.
pub async fn execute(client: &mut Client, id: &str, as_json: bool) -> Result<()> {
    let detail = client.post(id).await?;

    if as_json {
        let json = serde_json::to_string_pretty(&detail)?;
        println!("{}", json);
    } else {
        print_detail(&detail);
    }

    Ok(())
}

/// Pretty-print post detail with comments.
fn print_detail(detail: &ph_cli_core::PostDetail) {
    let post = &detail.post;

    println!("\n  🔶 {}\n", post.name);
    println!("  {}", post.tagline);
    println!();

    if let Some(ref desc) = post.description {
        // Strip HTML tags for terminal display
        let stripped = strip_html(desc);
        println!("  {}", stripped);
        println!();
    }

    println!("  Votes:      {}", post.votes_count);
    println!("  Comments:   {}", post.comments_count);
    println!("  URL:        {}", post.url);

    if let Some(ref website) = post.website {
        println!("  Website:    {}", website);
    }

    if let Some(ref redirect) = post.redirect_url {
        println!("  Redirect:   {}", redirect);
    }

    if !post.topics.is_empty() {
        println!(
            "  Topics:     {}",
            post.topics
                .iter()
                .map(|t| t.name.as_str())
                .collect::<Vec<_>>()
                .join(", ")
        );
    }

    if !post.makers.is_empty() {
        println!(
            "  Makers:     {}",
            post.makers
                .iter()
                .map(|m| {
                    let name =
                        if m.name.trim().is_empty() || m.name.eq_ignore_ascii_case("[REDACTED]") {
                            "Anonymous"
                        } else {
                            m.name.as_str()
                        };
                    let username = if m.username.trim().is_empty()
                        || m.username.eq_ignore_ascii_case("[REDACTED]")
                    {
                        "anonymous"
                    } else {
                        m.username.as_str()
                    };
                    format!("{} (@{})", name, username)
                })
                .collect::<Vec<_>>()
                .join(", ")
        );
    }

    // Comments
    if !detail.comments.is_empty() {
        println!("\n  ── Comments ({}) ──\n", detail.comments.len());

        for comment in &detail.comments {
            print_comment(comment, 0);
        }
    }

    println!();
}

/// Recursively print a comment and its children.
fn print_comment(comment: &ph_cli_core::Comment, depth: usize) {
    let indent = "  ".repeat(depth + 1);
    let prefix = "  │";

    let body = strip_html(&comment.body);
    let first_line = body.lines().next().unwrap_or("");
    let truncated = if first_line.len() > 80 {
        format!("{}…", &first_line[..79])
    } else {
        first_line.to_string()
    };

    let name = if comment.user.name.trim().is_empty()
        || comment.user.name.eq_ignore_ascii_case("[REDACTED]")
    {
        "Anonymous"
    } else {
        &comment.user.name
    };
    let username = if comment.user.username.trim().is_empty()
        || comment.user.username.eq_ignore_ascii_case("[REDACTED]")
    {
        "anonymous"
    } else {
        &comment.user.username
    };

    println!(
        "{}  ├─ {} (@{}) - {} votes",
        prefix, name, username, comment.votes,
    );
    println!("{}   {}", indent, truncated);

    for child in &comment.child_comments {
        print_comment(child, depth + 1);
    }
}

/// Strip HTML tags from a string for terminal display.
fn strip_html(html: &str) -> String {
    let mut result = String::with_capacity(html.len());
    let mut inside_tag = false;

    for c in html.chars() {
        match c {
            '<' => inside_tag = true,
            '>' => inside_tag = false,
            _ if !inside_tag => result.push(c),
            _ => {}
        }
    }

    // Decode common HTML entities
    result
        .replace("&amp;", "&")
        .replace("&lt;", "<")
        .replace("&gt;", ">")
        .replace("&quot;", "\"")
        .replace("&#39;", "'")
        .replace("&apos;", "'")
        .replace("&nbsp;", " ")
        .trim()
        .to_string()
}
