#!/usr/bin/env python3
"""Task 12 — Results history page + public player profile.

Covers:
  A. /results renders finished tournaments with winners + per-rank prizes
  B. Game filter on /results
  C. Hall of Champions sidebar
  D. /player/<numeric_id> profile stats, trophies, per-game, recent activity
  E. Cross-links (leaderboard → profile, results → profile)
  F. i18n (fa) on both pages + guests can access (public pages)

Run:  python scripts/test_results_profile.py
"""
import sys, os, json as _json
from datetime import datetime, timedelta

sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

PASS, FAIL = 0, 0
def check(name, cond, extra=""):
    global PASS, FAIL
    if cond:
        PASS += 1
        print(f"  ✓ {name}")
    else:
        FAIL += 1
        print(f"  ✗ FAIL: {name} {extra}")

from app import create_app
from app.extensions import db
from app.models.game import Game, GameMode
from app.models.user import User
from app.models.match import Match, MatchParticipant
from app.models.leaderboard import PointEvent

app = create_app()
app.config["WTF_CSRF_ENABLED"] = False
ctx = app.app_context()
ctx.push()

print("═" * 60)
print("Setup: sandbox finished match with 2 ranked winners")
print("═" * 60)

# pre-clean leftovers from any previous crashed run
_stale = Game.query.filter_by(slug="__rp_test").first()
if _stale:
    _sm = Match.query.filter_by(game_id=_stale.id).all()
    for _x in _sm:
        PointEvent.query.filter_by(match_id=_x.id).delete(synchronize_session=False)
        for _p in _x.participants.all():
            db.session.delete(_p)
        db.session.delete(_x)
    GameMode.query.filter_by(game_id=_stale.id).delete(synchronize_session=False)
    db.session.delete(_stale)
    db.session.commit()

game = Game(slug="__rp_test", name="__rp_test")
db.session.add(game)
db.session.flush()
mode = GameMode(game_id=game.id, slug="__rp_test", name="__rp_test", squad_size=1)
db.session.add(mode)
db.session.flush()

users = [User.query.filter_by(username=u).first() for u in ("Champ", "zynox", "ProLeague", "PL")]
check("4 test users exist", all(users), [u.username if u else None for u in users])
admin = User.query.filter_by(email="admin@vapolyx.gg").first()

start = datetime.utcnow() - timedelta(days=1)
m = Match(game_id=game.id, mode_id=mode.id, title="TEST results profile match",
          starts_at=start, ends_at=start + timedelta(hours=1),
          entry_fee=0, prize_pool=300, capacity=10, status="finished")
db.session.add(m)
db.session.flush()
parts = []
for i, u in enumerate(users):
    p = MatchParticipant(match_id=m.id, user_id=u.id, status="registered",
                         registered_at=start + timedelta(minutes=i))
    db.session.add(p)
    parts.append(p)
db.session.flush()

wids = [parts[0].id, parts[1].id]
for p in parts:
    p.status = "won" if p.id in wids else "lost"
for pid, uid, pts, prize in ((parts[0].id, users[0].id, 100, 200.0),
                             (parts[1].id, users[1].id, 100, 100.0),
                             (parts[2].id, users[2].id, 20, 0.0),
                             (parts[3].id, users[3].id, 20, 0.0)):
    db.session.add(PointEvent(user_id=uid, game_id=game.id, match_id=m.id,
                              kind="win" if prize > 0 else "participation",
                              points=pts, prize=prize, reason=f"Match: {m.title}",
                              created_at=start + timedelta(hours=1)))
m.winner_participant_ids = _json.dumps(wids)
db.session.commit()

print("═" * 60)
print("A. /results page (guest)")
print("═" * 60)

c = app.test_client()
r = c.get("/results")
check("results page 200 (guest ok)", r.status_code == 200, r.status_code)
h = r.text
check("results history header", "Results History" in h)
check("sandbox match listed", "TEST results profile match" in h)
check("1st place prize $200", "$200.00" in h)
check("2nd place prize $100", "$100.00" in h)
check("stats strip: finished tournaments count", "Finished Tournaments" in h)
check("stats strip: total prize distributed", "Total Prize Distributed" in h)
check("profile links on winner names", "/player/" in h)
check("hall of champions present", "Hall of Champions" in h)
check("champion name in hall", users[0].display_name in h)
check("hall shows title count", "1 title" in h)

print("═" * 60)
print("B. Game filter")
print("═" * 60)

r = c.get("/results?game=__rp_test")
h2 = r.text
check("filtered page shows sandbox match", "TEST results profile match" in h2)
r = c.get("/results?game=does-not-exist")
h3 = r.text
check("unknown filter → empty state", "No results yet" in h3 or "no-results" in h3.lower())

print("═" * 60)
print("C. /player/<id> public profile")
print("═" * 60)

r = c.get(f"/player/{users[0].numeric_id}")
check("profile 200 (guest ok)", r.status_code == 200, r.status_code)
h = r.text
check("player name shown", users[0].display_name in h)
check("numeric id badge", f"#{users[0].numeric_id}" in h)
check("points stat", "Points" in h)
check("matches stat", "Matches Played" in h)
check("wins stat", "Total Wins" in h)
check("win rate stat", "Win Rate" in h)
# values must match the real ledger for this user (other seed/demo data exists)
exp = (db.session.query(
        db.func.count(PointEvent.id),
        db.func.sum(db.case((PointEvent.kind == "win", 1), else_=0)),
        db.func.coalesce(db.func.sum(PointEvent.prize), 0.0))
       .filter(PointEvent.user_id == users[0].id).first())
exp_prize = float(exp[2] or 0)
check(f"prize won ${exp_prize:.2f} rendered", ("$%.2f" % exp_prize) in h, "$%.2f" % exp_prize)
check(f"matches count {int(exp[0])} rendered", str(int(exp[0])) in h)
check("trophies section", "Trophies" in h)
check("trophy = sandbox match title", "TEST results profile match" in h)
check("stats by game section", "Stats by Game" in h)
check("recent activity section", "Recent Activity" in h)
check("leaderboard back-link", "/leaderboard" in h)

# player with zero activity
zero_user = [u for u in users if u.username == "PL"][0]
r = c.get(f"/player/{zero_user.numeric_id}")
check("zero-activity profile 200", r.status_code == 200, r.status_code)
hz = r.text
check("zero-activity shows 0 matches", "0" in hz)

r = c.get("/player/99999999")
check("unknown player → 404", r.status_code == 404, r.status_code)

print("═" * 60)
print("D. Cross-links from leaderboard + podium")
print("═" * 60)

admin_c = app.test_client()
with admin_c.session_transaction() as s:
    s["user_id"] = admin.id
r = admin_c.get(f"/leaderboard?game_id={game.id}")
h = r.text
check("leaderboard links to profile", f"/player/{users[0].numeric_id}" in h)

r = c.get(f"/tournament/{m.id}")
h = r.text
check("podium links to profile", f"/player/{users[0].numeric_id}" in h)
check("share button present", "shareTournament" in h)

print("═" * 60)
print("E. fa locale")
print("═" * 60)

fa_c = app.test_client()
with fa_c.session_transaction() as s:
    s["lang"] = "fa"
r = fa_c.get("/results")
h = r.text
check("fa: تاریخچه نتایج", "تاریخچه نتایج" in h)
check("fa: تالار قهرمانان", "تالار قهرمانان" in h)
r = fa_c.get(f"/player/{users[0].numeric_id}")
h = r.text
check("fa: پروفایل page works (RTL)", "<html" in h and ("جام‌ها" in h or "امتیاز" in h))

print("═" * 60)
print(f"RESULT: {PASS} passed / {FAIL} failed")
print("═" * 60)

# ── cleanup sandbox ──
PointEvent.query.filter_by(match_id=m.id).delete(synchronize_session=False)
for p in m.participants.all():
    db.session.delete(p)
db.session.delete(m)
db.session.delete(mode)
db.session.delete(game)
db.session.commit()
print("sandbox test rows cleaned.")
ctx.pop()
sys.exit(1 if FAIL else 0)
