#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""BYDOTA粉丝玩车俱乐部 · 开放接口 Python 调用示例（Python 3 标准库，无需安装依赖）

用法：
    python3 openapi-demo.py <你的API密钥>
    python3 openapi-demo.py <你的API密钥> search 海狮
    python3 openapi-demo.py <你的API密钥> download <文件id>

接口文档与在线申请：https://pan.zoroli.com/openapi
"""
import json
import sys
import urllib.parse
import urllib.request

BASE = "https://pan.zoroli.com"


def call(path, params=None):
    """调用开放接口：带鉴权请求头，返回解析后的 JSON"""
    url = BASE + path
    if params:
        url += "?" + urllib.parse.urlencode(params)
    req = urllib.request.Request(url, headers={
        "Authorization": "Bearer " + API_KEY,
        "Accept": "application/json",
    })
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            return json.loads(resp.read().decode("utf-8"))
    except urllib.error.HTTPError as e:
        body = e.read().decode("utf-8", "replace")
        try:
            return json.loads(body)
        except ValueError:
            return {"ok": False, "error": "HTTP %d: %s" % (e.code, body[:200])}


def main():
    global API_KEY
    if len(sys.argv) < 2:
        print(__doc__)
        sys.exit(1)
    API_KEY = sys.argv[1]
    cmd = sys.argv[2] if len(sys.argv) > 2 else ""

    if cmd == "search":
        q = sys.argv[3] if len(sys.argv) > 3 else "海狮"
        r = call("/open/v1/search", {"q": q, "limit": 5})
        print("== 搜索「%s」，命中 %s 条 ==" % (q, r.get("data", {}).get("total")))
        for it in r.get("data", {}).get("items", []):
            print("  [%s] %s  (%s)  路径: %s" % ("文件夹" if it["folder"] else "文件", it["name"], it["id"], it.get("path", "")))
        return

    if cmd == "download":
        fid = sys.argv[3] if len(sys.argv) > 3 else ""
        if not fid:
            print("用法: python3 openapi-demo.py <密钥> download <文件id>")
            sys.exit(1)
        r = call("/open/v1/download", {"fid": fid})
        if r.get("ok"):
            d = r["data"]
            print("== 文件：%s（%.1f MB）==" % (d["name"], d["size"] / 1048576))
            print("下载直链（约 30 分钟内有效）：")
            print(d["url"])
        else:
            print("换链失败：", r)
        return

    # 默认演示：概览 → 根目录列表 → 搜索
    r = call("/open/v1/stats")
    if not r.get("ok"):
        print("调用失败：", r)
        print("请检查密钥是否正确、是否已通过审核。")
        sys.exit(1)
    d = r["data"]
    print("== 目录概览 ==  文件夹 %d 个 / 文件 %d 个，最近同步：%s" % (d["folders"], d["files"], d["syncedAt"]))

    r = call("/open/v1/list", {"fid": "root", "size": 5, "sort": "time"})
    print("\n== 根目录最新 5 条 ==")
    for it in r["data"]["items"]:
        kind = "📁" if it["folder"] else "📄"
        print("  %s %s  (id=%s)" % (kind, it["name"], it["id"]))

    # 下钻演示：根目录是 7 个品牌分区（01王朝…07其他），把 folder 条目的 id 作为 fid 继续浏览
    first = next((it for it in r["data"]["items"] if it["folder"]), None)
    if first:
        r2 = call("/open/v1/list", {"fid": first["id"], "size": 5, "sort": "name", "asc": "1"})
        print("\n== 「%s」下的前 5 项（下钻演示）==" % first["name"])
        for it in r2["data"]["items"]:
            kind = "📁" if it["folder"] else "📄"
            print("  %s %s  (id=%s)" % (kind, it["name"], it["id"]))

    # v2.70 新增：车架号校验（无需品牌/车系/车型）与 OTA 推送记录
    r = call("/open/v1/vin-check", {"vin": "LC0C74C44M1107654"})
    d = r["data"]
    print("\n== 车架号校验 ==  %s 是否比亚迪：%s（%s）" % (d["vin"], d["byd"], d["code"]))

    r = call("/open/v1/ota-records", {"size": 5})
    print("\n== OTA 推送记录（最近观测 5 条）==  共 %d 条" % r["data"]["total"])
    for rec in r["data"]["records"]:
        print("  %s  %s  预计推送 %s（观测 %d 次）" % (rec["model"], rec["version"], rec["pushTime"], rec["seenCount"]))

    print("\n提示：运行 `python3 openapi-demo.py <密钥> search 海狮` 查看搜索演示；")
    print("      运行 `python3 openapi-demo.py <密钥> download <文件id>` 换取下载短链")
    print("      （跨车型共享条目的 v:r: 开头 id 也可直接用于下载换链）。")


if __name__ == "__main__":
    main()
