"""T2I 프롬프트 안전 정책 수정 모듈 — 거절된 프롬프트를 GPT로 수정."""

import logging
from pathlib import Path
from typing import Any, Dict, List

from app.modules.llm.base import BaseLLMClient

logger = logging.getLogger(__name__)

PROMPTS_DIR = (
    Path(__file__).resolve().parent.parent.parent.parent
    / "prompts" / "_base" / "prompt_sanitizer" / "v1"
)

SANITIZE_SCHEMA: Dict[str, Any] = {
    "type": "object",
    "properties": {
        "sanitized_prompt": {"type": "string"},
        "changes": {"type": "string"},
        "strategy": {"type": "string"},
    },
    "required": ["sanitized_prompt", "changes", "strategy"],
    "additionalProperties": False,
}

STRATEGIES: Dict[str, Dict[str, str]] = {
    "film_previs": {
        "name": "영화 프리비즈",
        "description": "촬영 전 컨셉아트 형태로 재구성",
        "prefix": (
            "This is a pre-visualization concept art for a Korean sci-fi film production. "
            "Storyboard-quality still frame for the director's shot planning. "
            "Cinematic composition, dramatic lighting, professional film production context. "
            "NO gore, NO explicit violence, NO blood — focus on dramatic tension and emotion.\n\n"
        ),
    },
    "movie_poster": {
        "name": "영화 포스터",
        "description": "감정과 분위기 중심의 키 비주얼로 재구성",
        "prefix": (
            "A cinematic movie poster key visual for a Korean sci-fi thriller. "
            "Focus on the emotional core — characters' faces, dramatic poses, atmospheric lighting. "
            "Professional film marketing quality. Show mood and tension, not violence.\n\n"
        ),
    },
    "aftermath": {
        "name": "직후 정적 장면",
        "description": "액션 직후의 정적인 순간으로 시점 변경",
        "prefix": (
            "The moment AFTER the action — a quiet, contemplative still frame. "
            "Characters process what just happened. Focus on facial expressions, "
            "body posture, environmental details. Cinematic, thoughtful, no active violence.\n\n"
        ),
    },
}

ATTEMPT_TO_STRATEGY = {
    1: "film_previs",
    2: "movie_poster",
    3: "aftermath",
}


def _load_prompt(filename: str) -> str:
    return (PROMPTS_DIR / filename).read_text(encoding="utf-8").strip()


class PromptSanitizer:
    """GPT-5.4로 T2I 거절된 프롬프트를 수정하는 모듈."""

    def __init__(self, llm_client: BaseLLMClient) -> None:
        self._llm = llm_client

    def sanitize(
        self,
        original_prompt: str,
        block_reason: str,
        block_categories: List[str],
        attempt: int = 1,
    ) -> Dict[str, Any]:
        """Sanitize a blocked T2I prompt.

        Args:
            original_prompt: The original prompt that was blocked.
            block_reason: Reason for the block (e.g. SAFETY, HARM).
            block_categories: List of safety categories that triggered the block.
            attempt: Sanitization attempt number (1=film_previs, 2=movie_poster, 3=aftermath).

        Returns:
            Dict with keys: sanitized_prompt, changes, strategy
        """
        strategy_key = ATTEMPT_TO_STRATEGY.get(attempt, "aftermath")
        strategy = STRATEGIES[strategy_key]

        system_prompt = _load_prompt("sanitize_system.md")
        user_prompt = _load_prompt("sanitize_user.md").format(
            original_prompt=original_prompt,
            block_reason=block_reason,
            block_categories=", ".join(block_categories) if block_categories else "N/A",
            attempt=attempt,
            strategy_name=strategy["name"],
            strategy_description=strategy["description"],
            strategy_prefix=strategy["prefix"],
        )

        result = self._llm.generate_structured(
            system_prompt=system_prompt,
            user_prompt=user_prompt,
            response_schema=SANITIZE_SCHEMA,
            schema_name="prompt_sanitize",
            max_tokens=4000,
        )

        # Ensure the strategy prefix is included in the sanitized prompt
        sanitized = result.get("sanitized_prompt", "")
        if not sanitized.startswith(strategy["prefix"].strip()[:40]):
            result["sanitized_prompt"] = strategy["prefix"] + sanitized

        # Record which strategy was used
        result["strategy"] = strategy_key

        logger.info(
            "Prompt sanitized: attempt=%d, strategy=%s, changes=%s",
            attempt,
            strategy_key,
            result.get("changes", "")[:100],
        )

        return result
