"""S5_Shot3 chain bg 가설 검증 — GPT Image 2 (gpt-image-2) 버전.

사용법:
  cd backend
  .venv/bin/python scripts/experiment_chain_bg_gptimage_test.py

같은 references (chain bg + C04 face + P06) + 같은 두 prompt 버전:
  A. 기존 production prompt (TV 재묘사 포함)
  B. 기존 + [Background reference notice] 섹션 추가 (TV 그리지 말라고 명시)

production background_chain_render_step와 동일한 호출 방식:
  openai_client.images.edit(model="gpt-image-2", image=[...], prompt=...)

multi-image input 지원 (openai SDK Sequence[FileTypes]).

결과:
  scripts/experiment_results/s5shot3_gpt_A_original.png
  scripts/experiment_results/s5shot3_gpt_B_with_bg_note.png
"""
from __future__ import annotations

import base64
import json
import os
import sys
from pathlib import Path

try:
    from dotenv import load_dotenv
    load_dotenv(Path(__file__).parent.parent / ".env")
except ImportError:
    pass

from openai import OpenAI

PID = "c00bbe19-a9b5-463f-acfc-806f2e820258"
EID = "fe165e3a-19c2-4a0f-9acb-e0c9bab0ee5a"
PROJECT_ROOT = Path("/Users/manta/Documents/Projects/TheRoad-I1")

CHAIN_BG = (
    PROJECT_ROOT / "projects" / PID / "images" / EID
    / "background_chain" / "L05" / "interior_living_kitchen_day_normal.png"
)
C04_FACE_REF = (
    PROJECT_ROOT / "projects" / PID / "images" / EID
    / "reference" / "008b5d4c-5a02-4233-853e-ffc99225cfe1.png"
)
P06_REF = (
    PROJECT_ROOT / "projects" / PID / "images" / EID
    / "reference" / "48735792-33c0-415b-afdf-46146fe19ed4.png"
)

PROMPT_A_ORIGINAL = (
    "Photorealistic cinematic still. "
    "[L05: A cramped modern Korean 옥탑방 (rooftop room) interior, dusty small "
    "window, worn sink, low table, pale daylight, damp muted domestic shadows.] "
    "C04O06 in a plain apron occupies the right-center of the frame, at "
    "three-quarter angle from the left, one hand gripping the apron hem, eyes "
    "fixed on the television at the far left. The lens emphasizes her serious "
    "expression, tightened jaw, and the tense hand at the apron hem through a "
    "thin veil of white kitchen steam in the left foreground. A blurred "
    "television edge, screen angled away, sits at the far left, its cold "
    "blue-gray glow brushing her cheek; pale daylight from the closed dusty "
    "window adds washed yellow highlights. A steaming pot with a slightly "
    "lifted lid sits in the foreground, P06 rests rinsed beside the sink, and "
    "a thin stream from the faucet falls into the basin in the background. "
    "Muted blue-gray and washed yellow palette, damp domestic surfaces, uneasy "
    "stillness."
)

BG_NOTE = (
    "\n\n[Background reference notice — read FIRST]\n"
    "The first reference image (background chain ref) already contains the full "
    "interior layout: the television (left side), the small window, the worn "
    "sink, the kitchen counter, the low dining table, the front door, and the "
    "wall finish. These background elements are FIXED and must be reused as-is "
    "from the reference image. DO NOT redraw them, do not change their "
    "position, size, color, or style. The prompt mentions some of these "
    "elements only to indicate where the character looks or what light hits "
    "her face — they are NOT instructions to redraw the elements themselves. "
    "Add only: the character (C04O06), her pose, her gaze direction, the "
    "steam, the steaming pot in the foreground, and P06 (a herb) beside the "
    "sink. Keep everything else identical to the background reference."
)

PROMPT_B_WITH_NOTE = PROMPT_A_ORIGINAL + BG_NOTE

MODEL = "gpt-image-2"
SIZE = "1536x1024"  # 16:9에 가장 가까움 (gpt-image-2 옵션 중)
QUALITY = "high"


def call_gpt_image_2(client: OpenAI, prompt: str, image_paths: list, out_path: Path):
    """production background_chain_render와 동일한 호출 방식 (multi-image)."""
    files = [open(p, "rb") for p in image_paths]
    try:
        resp = client.images.edit(
            model=MODEL,
            image=files,
            prompt=prompt,
            size=SIZE,
            quality=QUALITY,
            n=1,
        )
    finally:
        for f in files:
            f.close()
    b64 = resp.data[0].b64_json
    if not b64:
        raise RuntimeError("empty b64 response")
    out_path.write_bytes(base64.b64decode(b64))
    return out_path


def main():
    api_key = os.environ.get("OPENAI_API_KEY", "")
    if not api_key:
        print("ERROR: OPENAI_API_KEY env not set", file=sys.stderr)
        sys.exit(1)

    out_dir = Path(__file__).parent / "experiment_results"
    out_dir.mkdir(exist_ok=True)

    client = OpenAI(api_key=api_key)

    print("=" * 60)
    print("S5_Shot3 chain bg double-render 검증 — GPT Image 2")
    print("=" * 60)
    print(f"Model: {MODEL}, size={SIZE}, quality={QUALITY}")
    print("References (3, multi-image input):")
    for p in [CHAIN_BG, C04_FACE_REF, P06_REF]:
        print(f"  {p.name} ({p.stat().st_size:,} bytes)")
    print()

    image_paths = [CHAIN_BG, C04_FACE_REF, P06_REF]

    # A
    print("--- A: 기존 prompt (TV 재묘사 포함, 안내 X) ---")
    print(f"prompt length: {len(PROMPT_A_ORIGINAL)} chars")
    a_path = out_dir / "s5shot3_gpt_A_original.png"
    try:
        call_gpt_image_2(client, PROMPT_A_ORIGINAL, image_paths, a_path)
        print(f"OK: {a_path} ({a_path.stat().st_size:,} bytes)")
    except Exception as exc:
        print(f"FAIL: {exc}")
        a_path = None
    print()

    # B
    print("--- B: 기존 + [배경 안내] (TV 그리지 말라고 명시) ---")
    print(f"prompt length: {len(PROMPT_B_WITH_NOTE)} chars")
    b_path = out_dir / "s5shot3_gpt_B_with_bg_note.png"
    try:
        call_gpt_image_2(client, PROMPT_B_WITH_NOTE, image_paths, b_path)
        print(f"OK: {b_path} ({b_path.stat().st_size:,} bytes)")
    except Exception as exc:
        print(f"FAIL: {exc}")
        b_path = None
    print()

    meta = {
        "test": "S5_Shot3 chain bg double-render — GPT Image 2",
        "model": MODEL,
        "size": SIZE,
        "quality": QUALITY,
        "references": [str(p) for p in image_paths],
        "variants": {
            "A_original": {
                "prompt": PROMPT_A_ORIGINAL,
                "result_path": str(a_path) if a_path else None,
            },
            "B_with_bg_note": {
                "prompt": PROMPT_B_WITH_NOTE,
                "result_path": str(b_path) if b_path else None,
                "added_section": BG_NOTE,
            },
        },
    }
    meta_path = out_dir / "s5shot3_gpt_metadata.json"
    meta_path.write_text(
        json.dumps(meta, ensure_ascii=False, indent=2), encoding="utf-8"
    )
    print(f"metadata: {meta_path}")


if __name__ == "__main__":
    main()
