"""Consistent user-facing placement label: the CHAT placement is always shown
as "Chat Unlock" across badges, filters, analytics, per-ad stats, the preview
page and exported reports — while the stored value stays ``chat``.

The label is centralised in ``AdvertisementPlacement.display_name`` (server) and
the ``placement_label`` Jinja filter (for raw string values); the admin JS mirrors
it. These tests assert the rendered UI, not the storage.
"""

import os
import shutil
import tempfile
import unittest
from pathlib import Path

os.environ["TEST_DATABASE_URL"] = "sqlite:///:memory:"

from werkzeug.security import generate_password_hash

from app import create_app
from app.extensions import db
from app.models import (
    Advertisement,
    AdvertisementPlacement,
    AdvertisementType,
    User,
    UserRole,
)


class AdPlacementDisplayNameTests(unittest.TestCase):
    def setUp(self):
        self.app = create_app("testing")
        self.ctx = self.app.app_context()
        self.ctx.push()
        db.create_all()
        self._upload_dir = Path(tempfile.mkdtemp())
        self.app.config["ADVERTISEMENT_UPLOAD_FOLDER"] = self._upload_dir
        u = User(email="a@c.edu", password_hash=generate_password_hash("Passw0rd!"),
                 is_verified=True, role=UserRole.SUPER_ADMIN)
        db.session.add(u)
        db.session.commit()
        self.client = self.app.test_client()
        self.client.post("/login", data={"email": "a@c.edu", "password": "Passw0rd!"})

    def tearDown(self):
        shutil.rmtree(self._upload_dir, ignore_errors=True)
        db.session.remove()
        db.drop_all()
        self.ctx.pop()

    def _rewarded_ad(self, title="Reward"):
        ad = Advertisement(
            title=title, advertisement_type=AdvertisementType.REWARDED,
            placement=AdvertisementPlacement.CHAT,
            image_path="/static/uploads/advertisements/r.png", is_active=True, priority=5,
            impression_count=3, click_count=1,
        )
        db.session.add(ad)
        db.session.commit()
        return ad

    # --- centralised helpers ---------------------------------------------------
    def test_enum_display_name(self):
        self.assertEqual(AdvertisementPlacement.CHAT.display_name, "Chat Unlock")
        self.assertEqual(AdvertisementPlacement.LANDING.display_name, "Landing")
        self.assertEqual(AdvertisementPlacement.SIDEBAR.display_name, "Sidebar")

    def test_placement_label_filter(self):
        f = self.app.jinja_env.filters["placement_label"]
        self.assertEqual(f("chat"), "Chat Unlock")
        self.assertEqual(f("landing"), "Landing")
        self.assertEqual(f(AdvertisementPlacement.CHAT), "Chat Unlock")
        self.assertEqual(f("unknown"), "Unknown")   # graceful fallback

    # --- badges / tables -------------------------------------------------------
    def test_list_badge_shows_chat_unlock(self):
        self._rewarded_ad()
        html = self.client.get("/admin/advertisements").get_data(as_text=True)
        self.assertIn("Chat Unlock", html)

    def test_export_data_attribute_uses_chat_unlock(self):
        # The client-side CSV/report export reads data-placement from each row.
        self._rewarded_ad()
        html = self.client.get("/admin/advertisements").get_data(as_text=True)
        self.assertIn('data-placement="Chat Unlock"', html)

    # --- filters ---------------------------------------------------------------
    def test_filter_dropdown_shows_chat_unlock(self):
        html = self.client.get("/admin/advertisements").get_data(as_text=True)
        self.assertIn("Chat Unlock", html)
        # The chat placement filter option uses the display label, not raw "Chat".
        self.assertIn('value="chat"', html)  # stored value unchanged in the option

    # --- analytics / charts ----------------------------------------------------
    def test_analytics_chart_labels_use_chat_unlock(self):
        self._rewarded_ad()
        html = self.client.get("/admin/advertisements/analytics").get_data(as_text=True)
        self.assertIn("Chat Unlock", html)

    def test_placement_summary_card_uses_chat_unlock(self):
        # placement_summary powers the dashboard placement cards + a11y summary.
        from app.admin.advertisements.services import placement_summary
        rows = {r["value"]: r["label"] for r in placement_summary()}
        self.assertEqual(rows["chat"], "Chat Unlock")

    # --- per-ad stats + preview ------------------------------------------------
    def test_stats_page_badge_shows_chat_unlock(self):
        ad = self._rewarded_ad()
        html = self.client.get(f"/admin/advertisements/{ad.public_id}/stats").get_data(as_text=True)
        self.assertIn("Chat Unlock", html)

    def test_preview_page_shows_chat_unlock(self):
        ad = self._rewarded_ad()
        html = self.client.get(f"/admin/advertisements/{ad.public_id}/preview").get_data(as_text=True)
        self.assertIn("Chat Unlock", html)
        self.assertNotIn("Chat Reward", html)   # old wording is gone


if __name__ == "__main__":
    unittest.main()
