//! Basic meta tags: charset, viewport, title, description, keywords, robots.

use html_escape::{encode_double_quoted_attribute, encode_text};

use crate::types::PageSeo;

/// Render the basic head tags. Does **not** include `<head>`, `<html>`,
/// charset, or viewport — those belong to the shell's static prefix. This is
/// the per-page slice: title, description, keywords, robots.
pub fn render_basic_tags(seo: &PageSeo) -> String {
    let mut out = String::new();
    out.push_str(&format!("<title>{}</title>", encode_text(&seo.title)));
    if let Some(desc) = &seo.description {
        out.push_str(&format!(
            r#"<meta name="description" content="{}">"#,
            encode_double_quoted_attribute(desc)
        ));
    }
    if !seo.keywords.is_empty() {
        let joined = seo.keywords.join(", ");
        out.push_str(&format!(
            r#"<meta name="keywords" content="{}">"#,
            encode_double_quoted_attribute(&joined)
        ));
    }
    if let Some(robots) = seo.robots.directive() {
        out.push_str(&format!(
            r#"<meta name="robots" content="{}">"#,
            encode_double_quoted_attribute(&robots)
        ));
    }
    out
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::types::{MaxImagePreview, PageSeo, RobotsDirective};

    #[test]
    fn renders_title() {
        let seo = PageSeo::new("Home", "https://example.com/", "en");
        let html = render_basic_tags(&seo);
        assert!(html.contains("<title>Home</title>"));
    }

    #[test]
    fn escapes_title() {
        let seo = PageSeo::new("A <script>", "https://example.com/", "en");
        let html = render_basic_tags(&seo);
        assert!(html.contains("&lt;script&gt;"));
        assert!(!html.contains("<script>"));
    }

    #[test]
    fn omits_robots_when_default() {
        let seo = PageSeo::new("Home", "https://example.com/", "en");
        let html = render_basic_tags(&seo);
        assert!(!html.contains(r#"name="robots""#));
    }

    #[test]
    fn renders_robots_directive() {
        let mut seo = PageSeo::new("Home", "https://example.com/", "en");
        seo.robots = RobotsDirective {
            noindex: true,
            nofollow: true,
            max_image_preview: Some(MaxImagePreview::Large),
            ..Default::default()
        };
        let html = render_basic_tags(&seo);
        assert!(html.contains(r#"content="noindex, nofollow, max-image-preview:large""#));
    }

    #[test]
    fn renders_keywords_joined() {
        let mut seo = PageSeo::new("Home", "https://example.com/", "en");
        seo.keywords = vec!["rust".into(), "leptos".into()];
        let html = render_basic_tags(&seo);
        assert!(html.contains(r#"content="rust, leptos""#));
    }
}
