"""인물 변형 추출 Phase2 — Phase1에서 추출된 인물 리스트 + 원문으로 변형만 질의."""

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)

# Phase1 결과 (Gemini Pro 20명)
phase1_characters = [
    "백련", "남작", "율동", "양 선달", "마부", "노파", "초원",
    "하인", "기생", "마진", "홍 첨지", "손자", "며느리", "무사",
    "김 진사", "기생 셋", "명승", "길도", "수매", "사내들"
]

char_list_block = "\n".join(f"- {name}" for name in phase1_characters)

schema = {
    "type": "object",
    "properties": {
        "variants": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "base_name": {"type": "string", "description": "원래 인물 이름 (위 목록에서)"},
                    "variant_name": {"type": "string", "description": "변형 형태 이름"},
                    "variant_type": {
                        "type": "string",
                        "enum": ["face", "full"],
                        "description": "face: 얼굴이 달라짐, full: 얼굴과 몸 구분 불가 또는 옷 불필요"
                    }
                },
                "required": ["base_name", "variant_name", "variant_type"],
                "additionalProperties": False
            }
        }
    },
    "required": ["variants"],
    "additionalProperties": False
}

system = """아래 인물 목록과 시나리오 원문을 보고, 변형이 있는 인물만 찾아주세요.

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

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

## 출력 규칙
- 변형이 있는 인물만 출력 (변형 없으면 출력하지 말 것)
- base_name: 위 인물 목록의 이름 그대로
- variant_name: 시나리오에서 사용된 짧은 이름/호칭
- 변형이 없으면 빈 배열 반환"""

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

user_prompt = f"[인물 목록]\n{char_list_block}\n\n[시나리오 원문]\n{scene_block}"

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=user_prompt,
            response_schema=schema,
            schema_name=f"char_variant_p2_{step}",
        )
        variants = result.get("variants", [])
        if not variants:
            print("  변형 없음")
        else:
            print(f"  변형 {len(variants)}건:")
            for v in variants:
                print(f"    {v['base_name']:15s} → {v['variant_name']} ({v['variant_type']})")
    except Exception as e:
        print(f"  ERROR: {e}")
