"""Default-structure FTs for the Backstage Pass trinket.

PASS is the magical, never-deposited trinket — unlike CARTE / COIN it
auto-admits the user to any gate without going through the `.token-rails`
deposit flow, so there's no `data-current-room-name` / In-Use parity work
to do. These tests scaffold the auto-equip + tooltip rendering surfaces
that PASS DOES share w. the other trinkets; deposit-side behavior is left
as TODO until PASS's UX direction is decided in a future sprint.
"""

from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By

from .base import FunctionalTest
from apps.applets.models import Applet
from apps.lyric.models import Token, User


class BackstagePassTest(FunctionalTest):
    """PASS auto-equips for is_staff users via the post_save signal in
    apps.lyric.models.create_wallet_and_tokens — coverage focuses on the
    initial-equipped state + tooltip prose. PASS doesn't go through the
    `current_room` deposit path that CARTE / COIN use."""

    def setUp(self):
        super().setUp()
        for slug, name, cols, rows in [
            ("new-game", "New Game", 6, 3),
            ("my-games", "My Games", 6, 3),
            ("game-kit", "Game Kit", 6, 3),
        ]:
            Applet.objects.get_or_create(
                slug=slug,
                defaults={
                    "name": name, "grid_cols": cols,
                    "grid_rows": rows, "context": "gameboard",
                },
            )
        # is_staff branch of the signal grants PASS + auto-equips it
        self.gamer = User.objects.create(email="vip@test.io", is_staff=True)
        self.pass_token = self.gamer.tokens.get(token_type=Token.PASS)

    # ── Test 1 ───────────────────────────────────────────────────────────────

    def test_pass_auto_equipped_for_staff_user(self):
        """Verify the signal contract — staff users land on /gameboard/ with
        PASS already equipped (mirror of COIN's auto-equip path for non-staff)."""
        self.gamer.refresh_from_db()
        self.assertEqual(self.gamer.equipped_trinket_id, self.pass_token.pk)

    # ── Test 2 ───────────────────────────────────────────────────────────────

    def test_pass_tooltip_renders_full_prose(self):
        """Hover the Backstage Pass token in the Game Kit applet → main
        tooltip shows title, description, shoptalk, and expiry."""
        self.create_pre_authenticated_session("vip@test.io")
        self.browser.get(self.live_server_url + "/gameboard/")
        self.wait_for(lambda: self.browser.find_element(By.ID, "id_game_kit"))

        pass_el = self.browser.find_element(By.ID, "id_kit_pass")
        self.browser.execute_script(
            "arguments[0].scrollIntoView({block: 'center'})", pass_el
        )
        ActionChains(self.browser).move_to_element(pass_el).perform()
        self.wait_for(
            lambda: self.browser.find_element(By.ID, "id_tooltip_portal").is_displayed()
        )
        portal = self.browser.find_element(By.ID, "id_tooltip_portal")
        self.assertIn("Backstage Pass", portal.text)
        self.assertIn("Admit All Entry", portal.text)
        self.assertIn("Entry fee", portal.text)  # shoptalk
        self.assertIn("no expiry", portal.text)

    # ── Test 3 ───────────────────────────────────────────────────────────────

    def test_equipped_pass_shows_equipped_mini_tooltip(self):
        """Mini portal under the main tooltip says 'Equipped' for the auto-
        equipped PASS (same shape as COIN's equipped-state mini portal)."""
        self.create_pre_authenticated_session("vip@test.io")
        self.browser.get(self.live_server_url + "/gameboard/")
        self.wait_for(lambda: self.browser.find_element(By.ID, "id_game_kit"))

        pass_el = self.browser.find_element(By.ID, "id_kit_pass")
        ActionChains(self.browser).move_to_element(pass_el).perform()
        self.wait_for(
            lambda: self.browser.find_element(By.ID, "id_tooltip_portal").is_displayed()
        )
        mini = self.browser.find_element(By.ID, "id_mini_tooltip_portal")
        self.wait_for(lambda: self.assertTrue(mini.is_displayed()))
        self.assertIn("Equipped", mini.text)

    # ── Test 4 ───────────────────────────────────────────────────────────────

    def test_equipped_pass_shows_doff_active_don_disabled(self):
        """Equipped PASS apparatus: DOFF active (clickable), DON is × disabled.
        Symmetric to the unequipped state COIN tests exercise after DOFF."""
        self.create_pre_authenticated_session("vip@test.io")
        self.browser.get(self.live_server_url + "/gameboard/")
        self.wait_for(lambda: self.browser.find_element(By.ID, "id_game_kit"))

        pass_el = self.browser.find_element(By.ID, "id_kit_pass")
        ActionChains(self.browser).move_to_element(pass_el).perform()
        portal = self.wait_for(
            lambda: self.browser.find_element(By.ID, "id_tooltip_portal")
        )
        don = portal.find_element(By.CSS_SELECTOR, ".btn-equip")
        doff = portal.find_element(By.CSS_SELECTOR, ".btn-unequip")
        self.assertIn("btn-disabled", don.get_attribute("class"))
        self.assertEqual(don.text, "×")
        self.assertNotIn("btn-disabled", doff.get_attribute("class"))
        self.assertEqual(doff.text, "DOFF")

    # TODO — PASS deposit/admit flow:
    #   PASS auto-admits any gate w.o going through the rails like CARTE / COIN.
    #   When PASS's deposit UX is decided in a future sprint, add tests for the
    #   "PASS admits N slots" flow + (optional) data-current-room-name parity.
