"""
Diagnostic: figure out why /meta shows no points per player.

Compares Guild_Metas userIDs against the uid keys returned by
obtain_clan_new_points() for the guild's bound squadron, and reports each
plausible failure mode (missing Guilds row, empty API response, uid format
mismatch, squadron-name mismatch).

Usage (on the server):
    cd ~/SREBOT/SREBOT_MEOW
    source ../SHARED/.venv/bin/activate
    python scripts/diag_meta_points.py 1378960248118841507
"""
from __future__ import annotations

import asyncio
import sys
from pathlib import Path

import aiosqlite

ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))

from BOT.game_api import ClanInfoError, obtain_clan_new_points
from BOT.utils import STORAGE_DIR


async def diag(guild_id: str) -> None:
    meta_db = STORAGE_DIR / "Meta.db"
    print(f"== Meta.db: {meta_db} (exists={meta_db.exists()})")

    if not meta_db.exists():
        print("Meta.db missing — wrong STORAGE_DIR?")
        return

    async with aiosqlite.connect(meta_db) as db:
        cur = await db.execute(
            "SELECT squadron_name, squadron_clanID FROM Guilds WHERE guild_id=?",
            (guild_id,),
        )
        guilds_row = await cur.fetchone()
        print(f"== Guilds row for {guild_id}: {guilds_row}")

        cur = await db.execute(
            "SELECT COUNT(*) FROM Guild_Metas WHERE guild_id=?", (guild_id,)
        )
        gm_count_row = await cur.fetchone()
        gm_count = gm_count_row[0] if gm_count_row else 0
        print(f"== Guild_Metas count for {guild_id}: {gm_count}")

        cur = await db.execute(
            "SELECT userID, nick, clanName FROM Guild_Metas "
            "WHERE guild_id=? ORDER BY nick LIMIT 5",
            (guild_id,),
        )
        gm_rows = await cur.fetchall()
        print("== Guild_Metas sample:")
        for uid, nick, clan in gm_rows:
            print(f"   uid={uid!r} type={type(uid).__name__} nick={nick!r} clan={clan!r}")

    if not guilds_row:
        print("\nNo Guilds row — /meta-management was never run for this guild.")
        return

    sq_name = guilds_row[0]
    print(f"\n== Calling obtain_clan_new_points({sq_name!r})...")
    try:
        members, total = await obtain_clan_new_points(sq_name)
    except ClanInfoError as e:
        print(f"   ClanInfoError: {e}")
        return
    except Exception as e:
        print(f"   {type(e).__name__}: {e}")
        return

    print(f"== API returned: {len(members)} members, total_score={total}")
    if not members:
        print("   Empty members dict — JWT was likely refreshed; rerun the script.")
        return

    sample = list(members.items())[:3]
    print("== API sample:")
    for uid, info in sample:
        print(f"   uid={uid!r} type={type(uid).__name__} info={info}")

    gm_rows_list = list(gm_rows)
    if gm_rows_list:
        gm_uid = gm_rows_list[0][0]
        print(
            f"\n== Membership test for first Guild_Metas uid {gm_uid!r}:\n"
            f"   raw in api_map -> {gm_uid in members}\n"
            f"   str(uid) in api_map -> {str(gm_uid) in members}"
        )

        api_uids = set(members.keys())
        gm_uids_all = set()
        async with aiosqlite.connect(meta_db) as db:
            cur = await db.execute(
                "SELECT userID FROM Guild_Metas WHERE guild_id=?", (guild_id,)
            )
            gm_uids_all = {str(r[0]) for r in await cur.fetchall()}
        api_uids_str = {str(u) for u in api_uids}
        overlap = gm_uids_all & api_uids_str
        only_gm = gm_uids_all - api_uids_str
        only_api = api_uids_str - gm_uids_all
        print(
            f"\n== Set overlap (str-cast both sides):\n"
            f"   in both: {len(overlap)}\n"
            f"   only in Guild_Metas: {len(only_gm)} (left squadron / wrong sq_name?)\n"
            f"   only in API:        {len(only_api)} (never bulk-added)"
        )


def main() -> None:
    if len(sys.argv) != 2:
        print("Usage: python scripts/diag_meta_points.py <guild_id>")
        sys.exit(2)
    asyncio.run(diag(sys.argv[1]))


if __name__ == "__main__":
    main()
