"""① LLM step — interview answers → VideoSpec (JSON).

Uses the Anthropic Python SDK (claude-opus-4-7) with structured outputs so the
result is guaranteed to match the Remotion data contract. The guardrail system
prompt is cached (stable prefix) to cut cost/latency across requests.
"""
from __future__ import annotations

import json
import anthropic

from app.schemas import GenerateRequest, VideoSpec, ScriptResult

MODEL = "claude-opus-4-7"

# Stable, cacheable guardrail + role prompt.
SYSTEM_PROMPT = """\
당신은 한국 로컬 비즈니스(숙소·매장·제품)의 8초 세로형 숏폼 광고 카피 디렉터입니다.
사장/마케터가 직접 답한 정보만으로, 영상 사양(VideoSpec)을 설계합니다. 복잡한 분석은 하지 않습니다.

[절대 가드레일]
1. 식민지 유산·역사정치 민감 용어 금지: "적산가옥", "일제", "식민지", "근대사" 등 → 미학·경험 어휘로 대체.
2. 거짓·과장 금지: 사용자가 주지 않은 거리(예: "서울 40분")·효능·수치를 지어내지 않는다. 주어진 정보만 사용.
3. 자막은 흰색 모노크롬 전제 — 카피에 색 지시어를 넣지 않는다.
4. AI 디스클로저는 end_card.disclosure에 고정 문구로 포함.

[hook 작성 — 레퍼런스 바이럴 공식 "[반전/호기심] + [한방]"]
- eyebrow: 짧은 도발/맥락 한 줄 (예: "아무도 모르는 군산").
- title: 굵은 한방 헤드라인. 사용자의 셀링포인트를 가장 강하게 압축.

[selling_point.items] 정확히 3개. 사용자 한방 셀링포인트 + 유형 기반의 구체 명사구(짧게). 이모지 금지.

[brand_lines] 감성 2줄 (각 줄 짧게). 한 덩어리로 읽히게.

[end_card] brand=업체/상품명, location=주소나 URL(없으면 빈 문자열 ""), disclosure 고정.

[caption] 업로드용. 정보(업체/주소/가격) + 짧은 감성 + 해시태그 5~8개. 유형에 맞는 해시태그.

[profile 선택]
- place + 정적/프라이빗/힐링 → "Still Cinema"
- place + 뷰/활동성/포토스팟, 또는 product 일반 → "Rhythm Reveal"
- 파티/워터파크/대형 액티비티 → "Maximum Viral"

[higgsfield_prompt] 영문. marketing_studio_video tv_spot용. 빠르고 역동적인 카메라(quick punchy moves, crash zoom, kinetic glide). 유형 반영: place=공간 투어, product=제품 쇼케이스. 반드시 "keep structure realistic, do not distort" 포함.
"""

# Structured-output JSON schema (additionalProperties:false everywhere).
_SPEC_SCHEMA = {
    "type": "object",
    "additionalProperties": False,
    "properties": {
        "profile": {"type": "string", "enum": ["Still Cinema", "Rhythm Reveal", "Maximum Viral"]},
        "higgsfield_prompt": {"type": "string"},
        "hook": {
            "type": "object",
            "additionalProperties": False,
            "properties": {"eyebrow": {"type": "string"}, "title": {"type": "string"}},
            "required": ["eyebrow", "title"],
        },
        "selling_point": {
            "type": "object",
            "additionalProperties": False,
            "properties": {"items": {"type": "array", "items": {"type": "string"}}},
            "required": ["items"],
        },
        "brand_lines": {"type": "array", "items": {"type": "string"}},
        "end_card": {
            "type": "object",
            "additionalProperties": False,
            "properties": {
                "brand": {"type": "string"},
                "location": {"type": "string"},
                "disclosure": {"type": "string"},
            },
            "required": ["brand", "location", "disclosure"],
        },
        "caption": {"type": "string"},
    },
    "required": [
        "profile", "higgsfield_prompt", "hook", "selling_point",
        "brand_lines", "end_card", "caption",
    ],
}


def build_spec(req: GenerateRequest, client: anthropic.Anthropic | None = None) -> VideoSpec:
    client = client or anthropic.Anthropic()

    user_msg = (
        f"유형: {'장소' if req.kind == 'place' else '메시지(축하·안부·홍보)' if req.kind == 'message' else '물건(제품·음식 등 정적 아이템)'}\n"
        f"업체/상품명: {req.biz_name}\n"
        f"주소/판매URL: {req.addr or '(없음)'}\n"
        f"가격: {req.price or '(없음)'}\n"
        f"강력한 한방 셀링포인트: {req.selling}\n\n"
        "위 정보로 VideoSpec을 설계해줘."
    )

    resp = client.messages.create(
        model=MODEL,
        max_tokens=2048,
        thinking={"type": "adaptive"},
        output_config={
            "effort": "medium",
            "format": {"type": "json_schema", "name": "video_spec", "schema": _SPEC_SCHEMA},
        },
        system=[{
            "type": "text",
            "text": SYSTEM_PROMPT,
            "cache_control": {"type": "ephemeral"},
        }],
        messages=[{"role": "user", "content": user_msg}],
    )

    text = "".join(b.text for b in resp.content if b.type == "text")
    return VideoSpec.model_validate(json.loads(text))


# ---------- 자막 스크립트 4블록 ----------
SCRIPT_SYSTEM = """\
당신은 한국 로컬 비즈니스 숏폼 광고의 자막 스크립트 작가입니다.
사장/마케터가 답한 정보로, 영상에 얹을 4개 블록을 만듭니다.

[4블록]
- intro: 첫 1~2초 후킹. 호기심·반전을 거는 짧은 한 줄.
- selling: 가장 강력한 셀링포인트를 한 문장으로 압축.
- story: 감성 스토리. 고객이 그 공간/제품에서 느낄 감정을 1~2문장으로.
- cta: 행동 유도. 예약·구매·방문으로 자연스럽게.

[가드레일]
- 거짓·과장 금지(주어지지 않은 거리·효능·수치 X). 주어진 정보만.
- 식민지 유산 어휘(적산가옥/일제/식민지 등) 금지 → 미학·경험 어휘로.
- 자막은 흰색 모노크롬 전제 — 색 지시어 넣지 않음. 이모지 남발 금지.
- 각 블록은 짧고 입에 붙게. 한국어.
"""

_SCRIPT_SCHEMA = {
    "type": "object",
    "additionalProperties": False,
    "properties": {
        "intro": {"type": "string"},
        "selling": {"type": "string"},
        "story": {"type": "string"},
        "cta": {"type": "string"},
    },
    "required": ["intro", "selling", "story", "cta"],
}


def build_script(req: GenerateRequest, client: anthropic.Anthropic | None = None) -> ScriptResult:
    client = client or anthropic.Anthropic()
    user_msg = (
        f"유형: {'장소' if req.kind == 'place' else '메시지(축하·안부·홍보)' if req.kind == 'message' else '물건(제품·음식 등 정적 아이템)'}\n"
        f"업체/상품명: {req.biz_name}\n"
        f"주소/판매URL: {req.addr or '(없음)'}\n"
        f"가격: {req.price or '(없음)'}\n"
        f"강력한 한방 셀링포인트: {req.selling}\n\n"
        "위 정보로 4블록 자막 스크립트를 만들어줘."
    )
    resp = client.messages.create(
        model=MODEL,
        max_tokens=1024,
        thinking={"type": "adaptive"},
        output_config={
            "effort": "low",
            "format": {"type": "json_schema", "name": "script", "schema": _SCRIPT_SCHEMA},
        },
        system=[{"type": "text", "text": SCRIPT_SYSTEM, "cache_control": {"type": "ephemeral"}}],
        messages=[{"role": "user", "content": user_msg}],
    )
    text = "".join(b.text for b in resp.content if b.type == "text")
    return ScriptResult.model_validate(json.loads(text))
