#!/usr/bin/env python3
"""
统计 Jellyfin 中每个演员出演的作品数量，找出超过指定阈值的演员。
结果保存为 JSON 和 Markdown 文档。
"""

import json
import os
import sys
import time
import urllib.request

# ====== 配置 ======
JELLYFIN_BASE = "http://192.168.3.5:8096"
AUTH_HEADER = 'MediaBrowser Client="OpenClaw", Device="PC", DeviceId="openclaw", Version="1.0", Token="8cbcfe4d7d294c8aa00412ccc853459f"'
USER_ID = "0f2540701e884852a2d2a1b7e63299e8"
MIN_MOVIES = 5
OUTPUT_DIR = "/mnt/f/docs"

# 需要检查的媒体类型
MEDIA_TYPES = "Movie,Series,Episode,Video"


def api_get(path, params=None):
    """通用 GET 请求"""
    url = JELLYFIN_BASE + path
    if params:
        parts = []
        for k, v in params.items():
            if isinstance(v, bool):
                v = "true" if v else "false"
            elif isinstance(v, int):
                v = str(v)
            parts.append(f"{k}={urllib.request.quote(str(v))}")
        url += "?" + "&".join(parts)

    req = urllib.request.Request(url)
    req.add_header("X-Emby-Authorization", AUTH_HEADER)
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            return json.loads(resp.read())
    except urllib.error.HTTPError as e:
        body = e.read().decode(errors="replace") if e.fp else ""
        print(f"  HTTP {e.code}: {e.reason} | {body[:200]}", file=sys.stderr)
        return None
    except Exception as e:
        print(f"  Error: {e}", file=sys.stderr)
        return None


def main():
    print("=== 获取所有演员 ===", file=sys.stderr)

    # Persons API 无 limit 时返回全部
    data = api_get("/Persons")
    if not data:
        print("ERROR: 无法获取演员列表", file=sys.stderr)
        sys.exit(1)

    persons = data.get("Items", [])
    total_count = data.get("TotalRecordCount", len(persons))
    print(f"总计 {total_count} 个演员，获取到 {len(persons)} 条", file=sys.stderr)

    results = []
    total = len(persons)

    for i, p in enumerate(persons, 1):
        name = p["Name"]
        pid = p["Id"]
        has_image = bool(p.get("ImageTags", {}))

        # 查询该演员出演的媒体数量
        movie_data = api_get(f"/Users/{USER_ID}/Items", {
            "personIds": pid,
            "recursive": True,
            "includeItemTypes": MEDIA_TYPES,
            "limit": 0,
        })

        count = movie_data.get("TotalRecordCount", 0) if movie_data else 0

        if count >= MIN_MOVIES:
            results.append({
                "name": name,
                "id": pid,
                "movie_count": count,
                "has_image": has_image,
            })

        if i % 30 == 0 or i == total:
            print(f"  进度: {i}/{total} | 已找到 {len(results)} 人超过 {MIN_MOVIES} 部", file=sys.stderr)
        time.sleep(0.03)

    # 排序：作品数降序 → 姓名升序
    results.sort(key=lambda x: (-x["movie_count"], x["name"]))

    # ====== JSON ======
    json_path = os.path.join(OUTPUT_DIR, "jellyfin_actor_stats.json")
    with open(json_path, "w", encoding="utf-8") as f:
        json.dump({
            "total_persons": total_count,
            "fetched_persons": len(persons),
            "threshold": MIN_MOVIES,
            "actors_above_threshold": len(results),
            "generated_at": time.strftime("%Y-%m-%dT%H:%M:%S%z"),
            "actors": results,
        }, f, ensure_ascii=False, indent=2)
    print(f"\n✅ JSON: {json_path}", file=sys.stderr)

    # ====== Markdown ======
    md_path = os.path.join(OUTPUT_DIR, "jellyfin_actor_stats.md")
    with open(md_path, "w", encoding="utf-8") as f:
        f.write("# Jellyfin 演员作品统计\n\n")
        f.write(f"- **演员总数**：{total_count}\n")
        f.write(f"- **统计阈值**：作品数 **> {MIN_MOVIES}** 部\n")
        f.write(f"- **满足条件的演员**：**{len(results)}** 人\n")
        f.write(f"- **统计时间**：{time.strftime('%Y-%m-%d %H:%M:%S')}\n\n")
        f.write("---\n\n")

        # 用序号代表排名
        rank = 0
        prev = None
        same_rank_start = 0
        for idx, a in enumerate(results):
            if a["movie_count"] != prev:
                rank = idx + 1
                prev = a["movie_count"]
            img = "✅" if a["has_image"] else "❌"
            f.write(f"| {rank} | {a['name']} | {a['movie_count']} | {img} |\n")

        f.write("\n\n---\n\n")
        f.write("*由脚本 `jellyfin_actor_stats.py` 自动生成*\n")

    print(f"✅ Markdown: {md_path}", file=sys.stderr)

    print(f"\n=== 结果摘要 ===", file=sys.stderr)
    print(f"演员总数: {total_count}", file=sys.stderr)
    print(f"超过 {MIN_MOVIES} 部: {len(results)} 人", file=sys.stderr)

    top_n = min(20, len(results))
    print(f"\n--- Top {top_n} ---", file=sys.stderr)
    for a in results[:top_n]:
        img = "🖼️" if a["has_image"] else "  "
        print(f"  #{rank:3d} {a['name']:30s} {a['movie_count']:4d} 部 {img}", file=sys.stderr)


if __name__ == "__main__":
    main()
