"""Write hand-crafted stub XML fixtures into tests/fixtures/bgg_cache/.

BGG's XML API now requires a registered application token, which we don't
have yet, so these fixtures are realistic approximations of real responses
(shapes verified against the API docs) rather than recordings. Once a
BGG_API_TOKEN exists: delete tests/fixtures/bgg_cache/ and run
scripts/record_fixtures.py — it writes real recordings under the SAME
filenames, and the test suite must still pass.

Usage: uv run python scripts/write_stub_fixtures.py
"""

from __future__ import annotations

from fixture_common import FIXTURE_CACHE, esc, write_cache_marker

from bggpipe.bgg_client import SEARCH_TYPES, cache_key


def search_item(bgg_id: int, name: str, year: int | None, type_: str) -> str:
    year_xml = f'<yearpublished value="{year}"/>' if year else ""
    return (
        f'<item type="{type_}" id="{bgg_id}">'
        f'<name type="primary" value="{esc(name)}"/>{year_xml}</item>'
    )


WINGSPAN_FAMILY = (
    search_item(266192, "Wingspan", 2019, "boardgame")
    + search_item(290448, "Wingspan: European Expansion", 2019, "boardgameexpansion")
    + search_item(300580, "Wingspan: Oceania Expansion", 2020, "boardgameexpansion")
    + search_item(366161, "Wingspan Asia", 2022, "boardgame")
)

SEARCHES = {
    "Catan": (
        search_item(13, "CATAN", 1995, "boardgame")
        + search_item(926, "CATAN: Seafarers", 1997, "boardgameexpansion")
        + search_item(27760, "Catan Dice Game", 2007, "boardgame")
        + search_item(133038, "CATAN 3D Collector's Edition", 2005, "boardgame")
    ),
    "Wingspan": WINGSPAN_FAMILY,
    "Wingspan: European Expansion": WINGSPAN_FAMILY,
    "Wingspan Europe": WINGSPAN_FAMILY,
    "Café International": (
        search_item(373, "Café International", 1989, "boardgame")
        + search_item(8103, "Café International: Das Kartenspiel", 2001, "boardgame")
    ),
    "Citadels": (
        search_item(478, "Citadels", 2000, "boardgame")
        + search_item(205398, "Citadels", 2016, "boardgame")
    ),
    "Blorvath: Quest of the Zzyzx": "",
    "Blorvath": "",  # truncation-retry head of the nonsense title
}

THINGS = {
    # Citadels tie-break: neither edition dominates 10x -> stays ambiguous.
    ("478,205398", "stats"): """<items>
  <item type="boardgame" id="478">
    <name type="primary" value="Citadels"/><yearpublished value="2000"/>
    <statistics><ratings><owned value="85000"/>
      <ranks><rank type="subtype" id="1" name="boardgame" value="250"/></ranks>
    </ratings></statistics>
  </item>
  <item type="boardgame" id="205398">
    <name type="primary" value="Citadels"/><yearpublished value="2016"/>
    <statistics><ratings><owned value="24000"/>
      <ranks><rank type="subtype" id="1" name="boardgame" value="400"/></ranks>
    </ratings></statistics>
  </item>
</items>""",
    # Wingspan versions: 2019 Stonemaier English must beat the 2020 printing.
    ("266192", "versions"): """<items>
  <item type="boardgame" id="266192">
    <name type="primary" value="Wingspan"/><yearpublished value="2019"/>
    <versions>
      <item type="boardgameversion" id="465063">
        <name type="primary" value="English first edition"/>
        <yearpublished value="2019"/>
        <link type="boardgamepublisher" id="23202" value="Stonemaier Games"/>
        <link type="language" id="2184" value="English"/>
      </item>
      <item type="boardgameversion" id="521212">
        <name type="primary" value="English fourth printing"/>
        <yearpublished value="2020"/>
        <link type="boardgamepublisher" id="23202" value="Stonemaier Games"/>
        <link type="language" id="2184" value="English"/>
      </item>
      <item type="boardgameversion" id="472430">
        <name type="primary" value="German edition"/>
        <yearpublished value="2019"/>
        <link type="boardgamepublisher" id="22160" value="Feuerland Spiele"/>
        <link type="language" id="2188" value="German"/>
      </item>
    </versions>
  </item>
</items>""",
}


def main() -> None:
    FIXTURE_CACHE.mkdir(parents=True, exist_ok=True)
    write_cache_marker(FIXTURE_CACHE)
    for query, items in SEARCHES.items():
        key = cache_key("search", {"query": query, "type": SEARCH_TYPES})
        total = items.count("<item ")
        (FIXTURE_CACHE / key).write_text(f'<items total="{total}">{items}</items>')
        # resolve falls back to an rpgitem search whenever the board-game
        # search runs dry: every known query needs an (empty) answer there
        rpg_key = cache_key("search", {"query": query, "type": "rpgitem"})
        (FIXTURE_CACHE / rpg_key).write_text('<items total="0"></items>')
    for (ids, flavor), xml in THINGS.items():
        key = cache_key("thing", {"id": ids, flavor: "1"})
        (FIXTURE_CACHE / key).write_text(xml)
    for f in sorted(FIXTURE_CACHE.iterdir()):
        print(f"  {f.name}")


if __name__ == "__main__":
    main()
