"""
Tests for the standalone email template renderer and admin gallery routes.

render_email_template() tests: each registry entry renders without error,
produces a valid DOCTYPE document, includes the wordmark, and supports both
EN and DE languages.

Admin gallery tests: access control, list page, preview page, error handling.
"""

import pytest
from padelnomics.email_templates import EMAIL_TEMPLATE_REGISTRY, render_email_template

# ── render_email_template() ──────────────────────────────────────────────────


class TestRenderEmailTemplate:
    """render_email_template() produces valid HTML for all registry entries."""

    @pytest.mark.parametrize("slug", list(EMAIL_TEMPLATE_REGISTRY.keys()))
    def test_all_templates_render_en(self, slug):
        entry = EMAIL_TEMPLATE_REGISTRY[slug]
        sample = entry["sample_data"]("en")
        html = render_email_template(entry["template"], lang="en", **sample)
        assert "<!DOCTYPE html>" in html
        assert "padelnomics" in html.lower()
        assert 'lang="en"' in html

    @pytest.mark.parametrize("slug", list(EMAIL_TEMPLATE_REGISTRY.keys()))
    def test_all_templates_render_de(self, slug):
        entry = EMAIL_TEMPLATE_REGISTRY[slug]
        sample = entry["sample_data"]("de")
        html = render_email_template(entry["template"], lang="de", **sample)
        assert "<!DOCTYPE html>" in html
        assert "padelnomics" in html.lower()
        assert 'lang="de"' in html

    def test_magic_link_contains_verify_link(self):
        entry = EMAIL_TEMPLATE_REGISTRY["magic_link"]
        html = render_email_template(entry["template"], lang="en", **entry["sample_data"]("en"))
        assert "/auth/verify?token=" in html

    def test_magic_link_has_preheader(self):
        entry = EMAIL_TEMPLATE_REGISTRY["magic_link"]
        html = render_email_template(entry["template"], lang="en", **entry["sample_data"]("en"))
        assert "display:none" in html  # hidden preheader span

    def test_lead_forward_has_heat_badge(self):
        entry = EMAIL_TEMPLATE_REGISTRY["lead_forward"]
        html = render_email_template(entry["template"], lang="en", **entry["sample_data"]("en"))
        assert "HOT" in html
        assert "#DC2626" in html  # HOT badge color

    def test_lead_forward_has_brief_rows(self):
        entry = EMAIL_TEMPLATE_REGISTRY["lead_forward"]
        html = render_email_template(entry["template"], lang="en", **entry["sample_data"]("en"))
        # Brief rows table is rendered (e.g. "Facility" label)
        assert "Facility" in html

    def test_lead_forward_has_contact_info(self):
        entry = EMAIL_TEMPLATE_REGISTRY["lead_forward"]
        html = render_email_template(entry["template"], lang="en", **entry["sample_data"]("en"))
        assert "ceo@padelclub.es" in html
        assert "Carlos Rivera" in html

    def test_weekly_digest_loops_over_leads(self):
        entry = EMAIL_TEMPLATE_REGISTRY["weekly_digest"]
        html = render_email_template(entry["template"], lang="en", **entry["sample_data"]("en"))
        # Sample data has 3 leads — all 3 countries should appear
        assert "Germany" in html
        assert "Austria" in html
        assert "Switzerland" in html

    def test_weekly_digest_has_heat_badges(self):
        entry = EMAIL_TEMPLATE_REGISTRY["weekly_digest"]
        html = render_email_template(entry["template"], lang="en", **entry["sample_data"]("en"))
        assert "HOT" in html
        assert "WARM" in html
        assert "COOL" in html

    def test_welcome_has_quickstart_links(self):
        entry = EMAIL_TEMPLATE_REGISTRY["welcome"]
        html = render_email_template(entry["template"], lang="en", **entry["sample_data"]("en"))
        assert "/planner" in html
        assert "/markets" in html

    def test_admin_compose_renders_body_html(self):
        entry = EMAIL_TEMPLATE_REGISTRY["admin_compose"]
        html = render_email_template(entry["template"], lang="en", **entry["sample_data"]("en"))
        assert "test message" in html.lower()

    def test_business_plan_has_download_link(self):
        entry = EMAIL_TEMPLATE_REGISTRY["business_plan"]
        html = render_email_template(entry["template"], lang="en", **entry["sample_data"]("en"))
        assert "/planner/export/" in html

    def test_invalid_lang_raises(self):
        entry = EMAIL_TEMPLATE_REGISTRY["magic_link"]
        with pytest.raises(AssertionError, match="Unsupported lang"):
            render_email_template(entry["template"], lang="fr", **entry["sample_data"]("en"))

    def test_non_emails_prefix_raises(self):
        with pytest.raises(AssertionError, match="Expected emails/ prefix"):
            render_email_template("base.html", lang="en")

    def test_common_design_elements_present(self):
        """Branded shell must include font + blue accent across all templates."""
        entry = EMAIL_TEMPLATE_REGISTRY["magic_link"]
        html = render_email_template(entry["template"], lang="en", **entry["sample_data"]("en"))
        assert "Bricolage Grotesque" in html
        assert "#1D4ED8" in html
        assert "padelnomics.io" in html

    def test_registry_has_required_keys(self):
        for slug, entry in EMAIL_TEMPLATE_REGISTRY.items():
            assert "template" in entry, f"{slug}: missing 'template'"
            assert "label" in entry, f"{slug}: missing 'label'"
            assert "description" in entry, f"{slug}: missing 'description'"
            assert callable(entry.get("sample_data")), f"{slug}: sample_data must be callable"
            assert entry["template"].startswith("emails/"), f"{slug}: template must start with emails/"


# ── Admin gallery routes ──────────────────────────────────────────────────────


class TestEmailGalleryRoutes:
    @pytest.mark.asyncio
    async def test_gallery_requires_auth(self, client):
        resp = await client.get("/admin/emails/gallery")
        assert resp.status_code == 302

    @pytest.mark.asyncio
    async def test_gallery_list_returns_200(self, admin_client):
        resp = await admin_client.get("/admin/emails/gallery")
        assert resp.status_code == 200

    @pytest.mark.asyncio
    async def test_gallery_list_shows_all_template_labels(self, admin_client):
        resp = await admin_client.get("/admin/emails/gallery")
        html = (await resp.get_data(as_text=True))
        for entry in EMAIL_TEMPLATE_REGISTRY.values():
            assert entry["label"] in html, f"Expected label {entry['label']!r} on gallery page"

    @pytest.mark.asyncio
    async def test_gallery_preview_magic_link_en(self, admin_client):
        resp = await admin_client.get("/admin/emails/gallery/magic_link")
        assert resp.status_code == 200
        html = (await resp.get_data(as_text=True))
        assert "srcdoc" in html  # sandboxed iframe is present
        assert "Magic Link" in html

    @pytest.mark.asyncio
    async def test_gallery_preview_magic_link_de(self, admin_client):
        resp = await admin_client.get("/admin/emails/gallery/magic_link?lang=de")
        assert resp.status_code == 200
        html = (await resp.get_data(as_text=True))
        assert 'lang="de"' in html or "de" in html  # lang toggle shows active state

    @pytest.mark.asyncio
    async def test_gallery_preview_lead_forward(self, admin_client):
        resp = await admin_client.get("/admin/emails/gallery/lead_forward")
        assert resp.status_code == 200
        html = (await resp.get_data(as_text=True))
        assert "Lead Forward" in html
        assert "srcdoc" in html

    @pytest.mark.asyncio
    async def test_gallery_preview_weekly_digest(self, admin_client):
        resp = await admin_client.get("/admin/emails/gallery/weekly_digest")
        assert resp.status_code == 200

    @pytest.mark.asyncio
    async def test_gallery_preview_nonexistent_slug_redirects(self, admin_client):
        resp = await admin_client.get("/admin/emails/gallery/does-not-exist")
        assert resp.status_code == 302

    @pytest.mark.asyncio
    async def test_gallery_preview_invalid_lang_falls_back(self, admin_client):
        resp = await admin_client.get("/admin/emails/gallery/magic_link?lang=fr")
        assert resp.status_code == 200  # invalid lang → falls back to "en"

    @pytest.mark.asyncio
    async def test_gallery_preview_requires_auth(self, client):
        resp = await client.get("/admin/emails/gallery/magic_link")
        assert resp.status_code == 302

    @pytest.mark.asyncio
    async def test_gallery_list_has_preview_links(self, admin_client):
        resp = await admin_client.get("/admin/emails/gallery")
        html = (await resp.get_data(as_text=True))
        # Each card links to the preview page
        for slug in EMAIL_TEMPLATE_REGISTRY:
            assert f"/admin/emails/gallery/{slug}" in html

    @pytest.mark.asyncio
    async def test_compose_preview_plain_body(self, admin_client):
        """POST to compose/preview with wrap=0 returns plain HTML body."""
        resp = await admin_client.post(
            "/admin/emails/compose/preview",
            form={"body": "Hello world", "wrap": "0"},
        )
        assert resp.status_code == 200
        html = (await resp.get_data(as_text=True))
        assert "Hello world" in html

    @pytest.mark.asyncio
    async def test_compose_preview_wrapped_body(self, admin_client):
        """POST to compose/preview with wrap=1 wraps body in branded layout."""
        resp = await admin_client.post(
            "/admin/emails/compose/preview",
            form={"body": "Test preview content", "wrap": "1"},
        )
        assert resp.status_code == 200
        html = (await resp.get_data(as_text=True))
        assert "Test preview content" in html
        # Branded wrapper includes padelnomics wordmark
        assert "padelnomics" in html.lower()

    @pytest.mark.asyncio
    async def test_compose_preview_empty_body(self, admin_client):
        """Empty body returns an empty but valid partial."""
        resp = await admin_client.post(
            "/admin/emails/compose/preview",
            form={"body": "", "wrap": "1"},
        )
        assert resp.status_code == 200
