"""Room-page FT helpers — extracted from the per-page FT modules so the
helpers can be imported without coupling consumer FTs to a sibling test
file's lifecycle (renames, deletions). Mirrors the post_page.py pattern.

Naming: underscored to signal "test infrastructure, not API surface", but
they're public within `functional_tests/` — direct imports are fine.

Consumers:
    test_room_role_select / test_room_sig_select   — define-and-use
    test_component_tray_tooltip                    — _equip_earthman_deck
    test_room_tray / test_deck_contribution         — both core helpers
    test_game_invite / test_room_gatekeeper         — _fill_room_via_orm
"""
from django.utils import timezone

from apps.drama.models import Note
from apps.epic.models import (
    DeckVariant, GateSlot, Room, TableSeat, TarotCard,
)
from apps.lyric.models import User


SIG_SEAT_ORDER = ["PC", "NC", "EC", "SC", "AC", "BC"]


def _equip_earthman_deck(user):
    # get_or_create: TransactionTestCase.flush() wipes migration-seeded
    # DeckVariants between tests, so subsequent tests in the same run can't
    # find it via filter().
    deck, _ = DeckVariant.objects.get_or_create(
        slug="earthman",
        defaults={"name": "Earthman", "card_count": 106, "is_default": True},
    )
    user.equipped_deck = deck
    user.save(update_fields=["equipped_deck"])


def _fill_room_via_orm(room, emails):
    """Fill all 6 gate slots and set gate_status=OPEN. Returns list of gamers."""
    gamers = []
    for i, email in enumerate(emails, start=1):
        gamer, _ = User.objects.get_or_create(email=email)
        slot = room.gate_slots.get(slot_number=i)
        slot.gamer = gamer
        slot.status = GateSlot.FILLED
        slot.save()
        gamers.append(gamer)
    room.gate_status = Room.OPEN
    room.save()
    return gamers


def _assign_all_roles(room, role_order=None):
    """Assign roles to all slots, reveal them, and advance to SIG_SELECT.
    Also ensures all gamers have an equipped_deck (required for sig_deck_cards)."""
    if role_order is None:
        role_order = SIG_SEAT_ORDER[:]
    earthman, _ = DeckVariant.objects.get_or_create(
        slug="earthman",
        defaults={"name": "Earthman Deck", "card_count": 108, "is_default": True},
    )
    # Seed the 18 sig deck cards (migration data is flushed in TransactionTestCase FTs).
    # _sig_unique_cards() filters arcana=MIDDLE, suits BRANDS/CROWNS/BLADES/GRAILS (Earthman).
    _NAME = {11: "Maid", 12: "Jack", 13: "Queen", 14: "King"}
    for suit in ("BRANDS", "CROWNS", "BLADES", "GRAILS"):
        for number in (11, 12, 13, 14):
            TarotCard.objects.get_or_create(
                deck_variant=earthman,
                slug=f"{_NAME[number].lower()}-of-{suit.lower()}-em",
                defaults={"arcana": "MIDDLE", "suit": suit, "number": number,
                          "name": f"{_NAME[number]} of {suit.capitalize()}",
                          "levity_qualifier": "Elevated",
                          "gravity_qualifier": "Graven"},
            )
    # Numbers 0–1 are the sig deck's Major Arcana (unlocked via Note).
    # Seed them with correct Earthman names and qualifiers, then unlock for all gamers.
    for number, name, slug in [
        (0, "The Nomad",  "the-nomad"),
        (1, "The Schizo", "the-schizo"),
    ]:
        TarotCard.objects.get_or_create(
            deck_variant=earthman,
            slug=slug,
            defaults={"arcana": "MAJOR", "number": number, "name": name,
                      "levity_qualifier": "Enlightened",
                      "gravity_qualifier": "Engraven"},
        )
    for slot in room.gate_slots.order_by("slot_number"):
        if slot.gamer:
            Note.objects.get_or_create(
                user=slot.gamer, slug="super-nomad",
                defaults={"earned_at": timezone.now()},
            )
            Note.objects.get_or_create(
                user=slot.gamer, slug="super-schizo",
                defaults={"earned_at": timezone.now()},
            )
    for slot in room.gate_slots.order_by("slot_number"):
        if slot.gamer and not slot.gamer.equipped_deck:
            slot.gamer.equipped_deck = earthman
            slot.gamer.save(update_fields=["equipped_deck"])
        TableSeat.objects.update_or_create(
            room=room,
            slot_number=slot.slot_number,
            defaults={
                "gamer": slot.gamer,
                "role": role_order[slot.slot_number - 1],
                "role_revealed": True,
            },
        )
    room.table_status = Room.SIG_SELECT
    room.save()
