"""T2I 프롬프트 검수 테스트 — 감지만 하고, 문제 항목만 재생성 요청."""
import json
import re
import sys
sys.path.insert(0, "/Users/manta/Documents/Projects/TheRoad-I1/backend")

from app.modules.llm.llm_client import call_structured

CPDIR = "/Users/manta/Documents/Projects/TheRoad-I1/projects/b0a366c5-f5bb-4b46-985b-b66d6bc4bf05/checkpoints/episodes/77714701-5e11-4bc9-b8ea-d3e04a81d90f"

# t2i_context 로드
vwr = json.load(open(f"{CPDIR}/visual_world_rules/manifest.json"))["data"]
t2i_context = vwr.get("t2i_context", "")

# 인물 목록 로드
entity_merge = json.load(open(f"{CPDIR}/entity_merge/manifest.json"))["data"]
char_names = [c["name"] for c in entity_merge.get("characters", [])]
char_names_str = ", ".join(char_names)

# ── Step 1: 감지 전용 프롬프트 ──

DETECT_SYSTEM = """당신은 T2I(text-to-image) 프롬프트 품질 검수관입니다.
프롬프트를 수정하지 마세요. 문제를 감지만 하세요.

## 시각 컨텍스트
{t2i_context}

## 등록된 인물 목록 (이들에 대한 국적/인종은 이미 관리됨 — 검수 대상 아님)
{char_names}

## 감지 대상
1. **국적/인종 누락**: 등록 인물이 아닌 보통명사 인물(직원, 경찰, 행인 등)에 국적/인종이 빠진 경우
2. **고유명사 번역**: 지명·상호명 등이 영어로 번역된 경우 (예: "Incheon" → "인천"이어야 함)
3. **원어 어색**: 원어가 자연스러운데 영어로 번역되어 어색한 표현

## 감지하지 않을 것
- 등록된 인물(위 목록)의 국적/인종 — 별도 관리됨
- 엔티티 ID (C01O02, P03 등) — 시스템 내부 코드
- 프롬프트 구조, 문체, 길이
- 문제가 없으면 has_issues=false — 억지로 찾지 마세요
""".format(t2i_context=t2i_context, char_names=char_names_str)

DETECT_SCHEMA = {
    "type": "object",
    "properties": {
        "has_issues": {"type": "boolean", "description": "문제가 있는지 여부"},
        "issues": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "type": {"type": "string", "enum": ["missing_ethnicity", "proper_noun_translated", "awkward_translation"]},
                    "target": {"type": "string", "description": "문제가 있는 구체적인 단어/구문"},
                    "suggestion": {"type": "string", "description": "간단한 수정 제안"}
                },
                "required": ["type", "target", "suggestion"],
                "additionalProperties": False
            }
        }
    },
    "required": ["has_issues", "issues"],
    "additionalProperties": False
}

# ── 문제 후보 수집 (사전 필터링으로 비용 절감) ──

candidates = []

# shot_extract — 보통명사 인물 국적 미표기
d = json.load(open(f"{CPDIR}/shot_extract/manifest.json"))["data"]
for s in d.get("scenes", []):
    si = s.get("scene_index")
    for sh in s.get("shots", []):
        desc = sh.get("description", "")
        for m in re.finditer(r'(남자|여자|직원|경찰|노인|아저씨|아줌마|행인|사람)', desc):
            ctx = desc[max(0, m.start()-10):m.end()+5]
            if not any(w in ctx for w in ['한국', 'Korean', '동양', '아시안']):
                candidates.append({"type": "shot", "scene": si, "shot_index": sh.get("shot_index", 0), "text": desc})
                break

# entity_t2i — Korean 미표기 또는 Incheon 영어 표기
d2 = json.load(open(f"{CPDIR}/entity_t2i/manifest.json"))["data"]
for cat in ["characters", "props"]:
    for c in d2.get(cat, []):
        t2i = c.get("t2i_prompt", "")
        if not t2i:
            continue
        needs_check = False
        if not any(w in t2i.lower() for w in ["korean", "east asian", "한국"]):
            if "사진" in c.get("name", "") or cat == "characters":
                needs_check = True
        if "Incheon" in t2i or "Seoul" in t2i:
            needs_check = True
        if needs_check:
            candidates.append({"type": "entity_t2i", "name": c.get("name", ""), "short_id": c.get("short_id", ""), "text": t2i})

# scene_detail — Incheon 영어 표기 또는 원어 없는 것 샘플
d3 = json.load(open(f"{CPDIR}/scene_detail/manifest.json"))["data"]
sample_cnt = 0
for s in d3["scenes"]:
    si = s.get("scene_index")
    for vi, v in enumerate(s.get("t2i_variations", [])):
        t2i = v.get("t2i_prompt", "")
        if not t2i:
            continue
        if "Incheon" in t2i or "Seoul" in t2i:
            candidates.append({"type": "scene_t2i", "scene": si, "var_index": vi, "text": t2i})
        elif sample_cnt < 5 and not re.findall(r'[가-힣]+', t2i):
            candidates.append({"type": "scene_t2i", "scene": si, "var_index": vi, "text": t2i})
            sample_cnt += 1

print(f"사전 필터링: {len(candidates)}개 후보 → LLM 감지 시작\n")

detected = []

for i, item in enumerate(candidates):
    label = f"[{item['type']}] "
    if "scene" in item:
        label += f"씬{item['scene']}"
    if "name" in item:
        label += item["name"]

    try:
        result = call_structured(
            step="text_cleanup",
            system_prompt=DETECT_SYSTEM,
            user_prompt=f"검수 대상:\n{item['text']}",
            response_schema=DETECT_SCHEMA,
        )
        if result.get("has_issues") and result.get("issues"):
            issues = result["issues"]
            detected.append({"item": item, "issues": issues})
            print(f"{i+1}/{len(candidates)} {label} — {len(issues)}건 감지")
            for iss in issues:
                print(f"    [{iss['type']}] \"{iss['target']}\" → {iss['suggestion']}")
        else:
            print(f"{i+1}/{len(candidates)} {label} — OK")
    except Exception as e:
        print(f"{i+1}/{len(candidates)} {label} — ERROR: {e}")

print(f"\n{'='*60}")
print(f"검수 완료: {len(candidates)}개 후보 중 {len(detected)}개에서 문제 감지")
print(f"{'='*60}")

# 타입별 요약
by_type = {}
for d in detected:
    t = d["item"]["type"]
    by_type[t] = by_type.get(t, 0) + 1
for t, c in sorted(by_type.items()):
    print(f"  {t}: {c}건")

# 이슈 타입별 요약
by_issue = {}
for d in detected:
    for iss in d["issues"]:
        it = iss["type"]
        by_issue[it] = by_issue.get(it, 0) + 1
print()
for it, c in sorted(by_issue.items()):
    print(f"  {it}: {c}건")
