//! Cookie banner — server emits only when the consent cookie is missing.

use crate::primitives::htmx_path;

/// Localized strings + resolved policy href for the cookie banner.
///
/// The component is language-agnostic: the consumer's shell resolves every
/// string (via the FTL registry) and the per-language privacy route, so this
/// renderer stays a pure HTML emitter with no i18n or routing knowledge.
pub struct CookieBannerLabels {
    /// Lead sentence — FTL `cookies-banner-text`.
    pub message: String,
    /// Language-resolved privacy/cookie policy URL (e.g. `/privacy`,
    /// `/privacidad`).
    pub policy_href: String,
    /// Inline policy link text — FTL `cookies-policy-link`.
    pub policy_link: String,
    /// Sentence tail after the link — FTL `cookies-policy-suffix`.
    pub policy_suffix: String,
    /// "Manage" action label — FTL `cookies-manage`.
    pub manage_label: String,
    /// Reject-non-essential label — FTL `cookies-reject`.
    pub reject_label: String,
    /// Accept-all label — FTL `cookies-accept-all`.
    pub accept_label: String,
}

/// Render the cookie banner when `show` is true.
pub fn render_cookie_banner(show: bool, labels: &CookieBannerLabels) -> String {
    if !show {
        return String::new();
    }
    let endpoint = htmx_path("cookies/accept");
    let ctx = minijinja::context! {
        endpoint => endpoint,
        message => labels.message,
        policy_href => labels.policy_href,
        policy_link => labels.policy_link,
        policy_suffix => labels.policy_suffix,
        manage_label => labels.manage_label,
        reject_label => labels.reject_label,
        accept_label => labels.accept_label,
    };
    rustelo_pages_htmx::fragment_env()
        .and_then(|env| {
            env.get_template("partials/overlays/cookie_banner.j2")
                .and_then(|t| t.render(ctx))
                .ok()
        })
        .unwrap_or_else(|| {
            let ep = html_escape::encode_double_quoted_attribute(&endpoint);
            let href = html_escape::encode_double_quoted_attribute(&labels.policy_href);
            format!(
                r##"<div id="cookie-consent-wrapper"><div class="fixed inset-0 z-50 bg-black opacity-75"></div><div id="cookie-banner" role="dialog" aria-label="Cookie consent" class="fixed bottom-0 left-0 right-0 z-[60] bg-base-100 border-t px-6 py-5 flex gap-4"><p class="text-sm flex-1 ds-text">{msg} <a href="{href}" class="underline ds-text">{plink}</a> {psuffix}</p><div class="flex items-center gap-2 shrink-0"><a href="{href}" class="btn btn-ghost btn-sm rounded-full ds-text no-underline">{manage}</a><button type="button" hx-post="{ep}" hx-vals='{{"level":"essential"}}' hx-target="#cookie-consent-wrapper" hx-swap="outerHTML" class="btn btn-ghost btn-sm rounded-full ds-text">{reject}</button><button type="button" hx-post="{ep}" hx-vals='{{"level":"all"}}' hx-target="#cookie-consent-wrapper" hx-swap="outerHTML" class="btn btn-neutral btn-sm rounded-full">{accept}</button></div></div></div>"##,
                msg = html_escape::encode_text(&labels.message),
                plink = html_escape::encode_text(&labels.policy_link),
                psuffix = html_escape::encode_text(&labels.policy_suffix),
                manage = html_escape::encode_text(&labels.manage_label),
                reject = html_escape::encode_text(&labels.reject_label),
                accept = html_escape::encode_text(&labels.accept_label),
            )
        })
}

#[cfg(test)]
mod tests {
    use super::*;

    fn sample() -> CookieBannerLabels {
        CookieBannerLabels {
            message: "We use cookies".to_string(),
            policy_href: "/privacidad".to_string(),
            policy_link: "Cookie Policy".to_string(),
            policy_suffix: "for more info.".to_string(),
            manage_label: "Manage".to_string(),
            reject_label: "Reject".to_string(),
            accept_label: "Accept".to_string(),
        }
    }

    #[test]
    fn renders_when_show_true() {
        let html = render_cookie_banner(true, &sample());
        assert!(html.contains(r#"id="cookie-banner""#));
        assert!(html.contains("We use cookies"));
        assert!(html.contains(r#"hx-post="/api/htmx/cookies/accept""#));
    }

    #[test]
    fn empty_when_show_false() {
        assert_eq!(render_cookie_banner(false, &sample()), "");
    }

    #[test]
    fn renders_localized_policy_link() {
        let html = render_cookie_banner(true, &sample());
        assert!(html.contains(r#"href="/privacidad""#));
        assert!(html.contains("Cookie Policy"));
        assert!(html.contains("for more info."));
    }

    #[test]
    fn renders_reject_and_accept_levels() {
        let html = render_cookie_banner(true, &sample());
        assert!(html.contains(r#"hx-vals='{"level":"essential"}'"#));
        assert!(html.contains(r#"hx-vals='{"level":"all"}'"#));
        assert!(html.contains("Reject"));
        assert!(html.contains("Accept"));
    }

    #[test]
    fn wrapper_contains_overlay_and_banner() {
        let html = render_cookie_banner(true, &sample());
        assert!(html.contains(r##"id="cookie-consent-wrapper""##));
        assert!(html.contains(r##"id="cookie-banner""##));
    }
}
