"""씬 시각적 연관 추출 — 전체 씬을 보고 시각적으로 연관된 앞/뒤 씬 매핑."""

import json
import logging
import os
from pathlib import Path
from typing import Any, Dict, List, Optional

from app.modules.llm.gemini_text_client import GeminiTextClient

PROMPT_DIR = (
    Path(__file__).resolve().parent.parent.parent.parent.parent
    / "prompts" / "_base" / "scene_dependency"
)

logger = logging.getLogger(__name__)


def extract_scene_dependencies(
    segments: List[Dict[str, Any]],
    fulltext: str,
    checkpoint_dir: Optional[str] = None,
) -> Dict[int, Dict[str, Any]]:
    """전체 씬 → 시각적 연관 씬 매핑.

    Returns:
        {scene_index: {"prev_ref": int, "next_ref": int, "reason": str}}
    """
    # 체크포인트 비활성화 — 씬 의존성 추출은 1회 호출이므로 불필요
    # stale 데이터 방지를 위해 항상 새로 계산

    # 씬 JSON (헤딩만, 텍스트는 짧게)
    scenes_json = []
    for seg in segments:
        scene_text = fulltext[seg["start_char"]:seg["end_char"]]
        scenes_json.append({
            "scene_index": seg["scene_index"],
            "heading": seg["heading"],
            "text_preview": scene_text[:600],
        })

    # 프롬프트 로드
    versions = sorted([d.name for d in PROMPT_DIR.iterdir() if d.is_dir()], reverse=True)
    prompt_text = (PROMPT_DIR / versions[0] / "extract_prompt.md").read_text(encoding="utf-8").strip()
    schema = json.loads((PROMPT_DIR / versions[0] / "extract_schema.json").read_text(encoding="utf-8"))

    prompt = prompt_text.format(scenes_json=json.dumps(scenes_json, ensure_ascii=False, indent=1))

    client = GeminiTextClient()
    logger.info("Scene dependency extraction: %d scenes", len(segments))

    result = None
    for retry in range(3):
        try:
            result = client.send_structured(
                user_message=prompt,
                response_schema=schema,
                system_instruction="시나리오 분석 전문가. 씬 간 시각적 연관성을 정확히 파악한다.",
            )
            break
        except Exception as exc:
            logger.warning("Scene dependency attempt %d failed: %s", retry + 1, exc)
            if retry < 2:
                import time
                time.sleep(5 * (retry + 1))

    if not result:
        logger.warning("Scene dependency extraction failed")
        return {}

    deps = {}
    for d in result.get("dependencies", []):
        deps[d["scene_index"]] = {
            "prev_ref": d.get("prev_ref", -1),
            "next_ref": d.get("next_ref", -1),
            "reason": d.get("reason", ""),
        }

    logger.info("Scene dependencies: %d scenes mapped", len(deps))

    return deps
