# -*- coding: utf-8 -*-
"""造测试数据验证邀请列表"真实头像能不能连上"。

A 邀请 B1(上传真实头像)/B2(无头像→色块)/B3(设昵称→色块), 然后:
  ① 打印 A 的邀请码 + /invitees 返回(看 B1 有 avatar_url、B2 空、B3 昵称);
  ② 直接 HTTP 访问 B1 的头像地址,确认文件能取到(后端静态托管通)。
前端 AsyncImage 实际显示,装机后真机用 A 登录看。

跑: <app-server py> scripts/seed_invitee_avatar_test.py"""
import io
import struct
import sys
import zlib

import httpx

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")

BASE = "http://127.0.0.1:8770"


def solid_png(size: int = 96, rgb: tuple = (80, 140, 240)) -> bytes:
    """生成一张纯色 PNG(蓝色 96x96),够真机看清、魔数是合法 PNG。"""
    row = b"\x00" + bytes(rgb) * size
    raw = row * size
    comp = zlib.compress(raw)

    def chunk(typ: bytes, data: bytes) -> bytes:
        c = typ + data
        return struct.pack(">I", len(data)) + c + struct.pack(">I", zlib.crc32(c) & 0xFFFFFFFF)

    sig = b"\x89PNG\r\n\x1a\n"
    ihdr = struct.pack(">IIBBBBB", size, size, 8, 2, 0, 0, 0)  # 8bit, RGB
    return sig + chunk(b"IHDR", ihdr) + chunk(b"IDAT", comp) + chunk(b"IEND", b"")


def login(c: httpx.Client, phone: str) -> str:
    c.post(f"{BASE}/api/v1/auth/sms/send", json={"phone": phone})
    r = c.post(f"{BASE}/api/v1/auth/sms/login", json={"phone": phone, "code": "123456"})
    r.raise_for_status()
    return r.json()["access_token"]


def auth(tok: str) -> dict:
    return {"Authorization": f"Bearer {tok}"}


with httpx.Client(timeout=15) as c:
    # A = 邀请人(真机用它登录看)
    A_PHONE = "13900008001"
    a_tok = login(c, A_PHONE)
    a_code = c.get(f"{BASE}/api/v1/invite/me", headers=auth(a_tok)).json()["invite_code"]
    print(f"邀请人 A: 手机号={A_PHONE} 验证码=123456 邀请码={a_code}")

    # B1: 绑 A 码 + 上传真实头像
    b1 = login(c, "13900008002")
    c.post(f"{BASE}/api/v1/invite/bind", json={"invite_code": a_code}, headers=auth(b1))
    r = c.post(
        f"{BASE}/api/v1/user/avatar",
        headers=auth(b1),
        files={"file": ("avatar.png", io.BytesIO(solid_png()), "image/png")},
    )
    print(f"B1 绑定 + 上传头像 -> HTTP {r.status_code}, avatar_url={r.json().get('avatar_url')!r}")

    # B2: 绑 A 码, 不传头像(测色块兜底)
    b2 = login(c, "13900008003")
    c.post(f"{BASE}/api/v1/invite/bind", json={"invite_code": a_code}, headers=auth(b2))
    print("B2 绑定, 无头像(测色块)")

    # B3: 绑 A 码 + 设昵称(测昵称优先 + 色块)
    b3 = login(c, "13900008004")
    c.post(f"{BASE}/api/v1/invite/bind", json={"invite_code": a_code}, headers=auth(b3))
    c.patch(f"{BASE}/api/v1/user/profile", json={"nickname": "测试昵称"}, headers=auth(b3))
    print("B3 绑定 + 昵称='测试昵称'")

    # A 的邀请列表
    inv = c.get(f"{BASE}/api/v1/invite/invitees", headers=auth(a_tok)).json()
    print(f"\n=== A 的 /invitees (共 {inv['total']} 人) ===")
    for it in inv["items"]:
        print(f"  name={it['display_name']!r}  avatar={it['avatar_url']!r}  coins={it['coins']}  time={it['invited_at']}")

    # 关键: 直接 HTTP 取 B1 的头像文件, 确认后端静态托管能 serve(= 前端拿这地址也能加载)
    b1_avatar = next((it["avatar_url"] for it in inv["items"] if it["avatar_url"]), None)
    print("\n=== 头像文件 HTTP 可访问性(后端静态托管) ===")
    if b1_avatar:
        rr = c.get(f"{BASE}{b1_avatar}")
        ok = rr.status_code == 200 and (rr.headers.get("content-type", "").startswith("image"))
        print(f"  GET {BASE}{b1_avatar}")
        print(f"  -> HTTP {rr.status_code}, content-type={rr.headers.get('content-type')}, {len(rr.content)} bytes  {'✅ 能取到' if ok else '✗ 取不到'}")
    else:
        print("  没有带头像的被邀请人?!")
