# -*- coding: utf-8 -*-
"""BytePlus Seed 2.0 Pro 呼び出しクライアント（OpenAI互換チャットAPI想定）+ ローカルキャッシュ。
Track A/B 共通。画像(静止画)を渡し、JSONで軸スコアを受け取る。

前提（要確認・受領後に config.yaml で設定）:
  - BytePlus Ark/ModelArk は OpenAI互換の /chat/completions を提供する想定。
  - 画像は base64 data URL で渡す（image_url 形式）。
  - 動画URL入力に切り替える場合は input_kind: video（後日対応）。

キャッシュ: 同じ(画像群+プロンプト+モデル)はAPIを再呼びせずローカルJSONを返す（課金節約）。
"""
import os, json, base64, hashlib, time
import yaml

ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
CACHE_DIR = os.path.join(ROOT, ".vlm_cache")

def load_config():
    p = os.path.join(ROOT, "common", "config.yaml")
    if not os.path.exists(p):
        p = os.path.join(ROOT, "common", "config.example.yaml")
    return yaml.safe_load(open(p, encoding="utf-8"))

def _read_key(path):
    p = os.path.join(ROOT, path)
    return open(p, encoding="utf-8").read().strip() if os.path.exists(p) else None

def _img_data_url(path):
    b = base64.b64encode(open(path, "rb").read()).decode()
    ext = os.path.splitext(path)[1].lstrip(".").lower() or "jpeg"
    if ext == "jpg": ext = "jpeg"
    return f"data:image/{ext};base64,{b}"

def _cache_key(images, prompt, model):
    h = hashlib.sha256()
    for p in images: h.update(open(p, "rb").read())
    h.update(prompt.encode()); h.update(model.encode())
    return h.hexdigest()[:32]

def score(images, prompt, schema_hint="", cfg=None, max_retry=3):
    """images: 画像パスのリスト。prompt: 指示文。戻り値: APIが返したJSON(dict)。
    schema_hint: 期待JSON形をプロンプト末尾に添える文字列。"""
    cfg = cfg or load_config()
    vlm = cfg["vlm"]; model = vlm["model"]["byteplus"]
    os.makedirs(CACHE_DIR, exist_ok=True)
    ck = _cache_key(images, prompt + schema_hint, model)
    cpath = os.path.join(CACHE_DIR, ck + ".json")
    if os.path.exists(cpath):
        return json.load(open(cpath, encoding="utf-8"))

    import requests
    key = _read_key(vlm["key_file"]["byteplus"])
    base = vlm["byteplus_endpoint"].rstrip("/")
    if not key or not base:
        raise RuntimeError("BytePlusのキー(secrets/byteplus.key)とendpoint(config.yaml)が未設定です。")

    content = [{"type": "text", "text": prompt + "\n" + schema_hint}]
    for im in images:
        content.append({"type": "image_url", "image_url": {"url": _img_data_url(im)}})
    payload = {"model": model, "messages": [{"role": "user", "content": content}],
               "temperature": 0, "response_format": {"type": "json_object"}}
    headers = {"Authorization": f"Bearer {key}", "Content-Type": "application/json"}

    last = None
    for attempt in range(max_retry):
        try:
            r = requests.post(f"{base}/chat/completions", headers=headers,
                              json=payload, timeout=120)
            r.raise_for_status()
            txt = r.json()["choices"][0]["message"]["content"]
            out = json.loads(txt)
            json.dump(out, open(cpath, "w", encoding="utf-8"), ensure_ascii=False, indent=2)
            return out
        except Exception as e:
            last = e; time.sleep(2 * (attempt + 1))
    raise RuntimeError(f"VLM呼び出し失敗: {last}")

if __name__ == "__main__":
    # 設定だけ確認（キー無しでもここまでは動く）
    cfg = load_config()
    print("provider:", cfg["vlm"]["provider"], "| model:", cfg["vlm"]["model"]["byteplus"])
    print("endpoint設定:", bool(cfg["vlm"]["byteplus_endpoint"]))
    print("key存在:", bool(_read_key(cfg["vlm"]["key_file"]["byteplus"])))
