"""인물 + 변형 나열 — Gemini Pro 테스트."""

import json, sys
sys.path.insert(0, ".")

from app.modules.llm.llm_client import call_structured
from app.core.config import settings

PID = "c0f47e88-b9f7-43a5-9e73-66b0f965b247"
EID = "d2d203b8-4865-40f0-b5a6-e5990fa3effd"
CP = f"{settings.projects_dir}/{PID}/checkpoints/episodes/{EID}"

seg = json.load(open(f"{CP}/scene_save/manifest.json"))

from app.core.database import SessionLocal
from app.models.project import Episode
from sqlalchemy.orm import undefer
db = SessionLocal()
ep = db.query(Episode).options(undefer(Episode.fulltext)).filter(Episode.id == EID).first()
ft = ep.fulltext
db.close()

parts = []
for s in seg["data"]["segments"]:
    text = s.get("text") or ft[s["start_char"]:s["end_char"]]
    parts.append(f"[씬 {s['scene_index']}]\n{text}")
scene_block = "\n\n".join(parts)

schema = {
    "type": "object",
    "properties": {
        "characters": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "name": {"type": "string", "description": "인물 이름"},
                    "variants": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {"type": "string", "description": "변형 형태 이름"},
                                "variant_type": {
                                    "type": "string",
                                    "enum": ["face", "full"],
                                    "description": "face: 얼굴이 달라짐, full: 얼굴과 몸을 구분할 수 없는 완전변형"
                                }
                            },
                            "required": ["name", "variant_type"],
                            "additionalProperties": False
                        },
                        "description": "변형 목록. 없으면 빈 배열"
                    }
                },
                "required": ["name", "variants"],
                "additionalProperties": False
            }
        }
    },
    "required": ["characters"],
    "additionalProperties": False
}

system = """시나리오에서 등장하는 인물을 모두 나열하고, 변형이 있다면 그 형태를 따로 나열하세요.

## 인물의 정의
- 머리와 몸이 구분되는 모든 존재 (인간, 요괴, 동물, 로봇, 외계인 등)
- 단, 서사가 있어야 함 (행동이나 대사가 있는 존재만)

## 변형의 정의
변형은 **인물에서 파생된 다른 외형**만 해당합니다:
- 얼굴이 크게 달라지는 변화 → variant_type: "face"
  예: 나이 변화(어린이↔성인), 변장/성형 전후, 빙의로 얼굴이 바뀜
- 시각적으로 얼굴과 몸을 구분할 수 없는 존재로의 변형, 구분 가능하지만 시나리오상에서 옷이 필요하지 않는 경우 → variant_type: "full"

## 변형이 아닌 것 (절대 포함 금지)
- 일시적 상태: 부상, 출혈, 창백해짐 등
- 비유적 표현: "해골처럼", "짐승 같은" 등 ~처럼/~같은
- 복장/의상/감정 변화

## 출력 규칙
- name: 인물의 기본 이름
- variants: 변형 목록 (이름 + variant_type)
- 변형 이름은 시나리오에서 사용된 짧은 이름/호칭만
- 변형이 없는 인물은 variants를 빈 배열로"""

print(f"입력: {len(seg['data']['segments'])}씬, {len(scene_block)}자")

# beat_extract=gemini-pro, visual_world_rules=gpt
for step, label in [("beat_extract", "Gemini Pro"), ("visual_world_rules", "GPT")]:
    print(f"\n=== {label} ===")
    try:
        result = call_structured(
            step=step,
            system_prompt=system,
            user_prompt=scene_block,
            response_schema=schema,
            schema_name=f"char_variants_{step}",
        )
        chars = result["characters"]
        print(f"인물: {len(chars)}명")
        for c in chars:
            if c["variants"]:
                vlist = ", ".join(f"{v['name']}({v['variant_type']})" for v in c["variants"])
                print(f"  {c['name']:20s} → {vlist}")
            else:
                print(f"  {c['name']:20s}")
    except Exception as e:
        print(f"  ERROR: {e}")
