"""
Built-in style presets for the Video Production Pipeline.

These presets are based on the production-validated rules from:
- PromptImageNOVO.pdf (v3.0) - Realistic style
- PromptImageNOVO (2).pdf (v4.0) - Diorama style
- VideoPromptNovo.pdf - Cinematic rules
"""

from models import WorldStyle, ClothingStyle, ProductionRules


# ---------------------------------------------------------------------------
# World Style Presets
# ---------------------------------------------------------------------------

WORLD_STYLE_REALISTIC = WorldStyle(
    id="preset_realistic",
    name="Realistic World",
    preset_type="realistic",
    background_rules="""Infer the environment directly from the script. Place the character naturally inside real-world locations (cities, forests, homes, streets, etc.). Environment must be realistic, context-appropriate, and vary across scenes for visual dynamism.""",
    floor_rules="""Natural floor matching environment (concrete sidewalk, grass lawn, wooden floor, tiled bathroom, etc.). Floor texture and material must be photorealistic.""",
    secondary_characters_rules="""Photorealistic human skin with natural texture, pores, and imperfections. Normal human proportions and appearance. Realistic clothing and accessories. Blurred figures in crowds should still have realistic skin tones.""",
    lighting_rules="""Real-world lighting matching the environment. Natural shadows with soft falloff. Photorealistic cinematic realism. Light sources should be contextually appropriate (sunlight, streetlights, indoor lamps, etc.).""",
    props_rules="""Environment-appropriate props and objects. Full scene composition allowed. Props should be contextually realistic and add to the narrative.""",
    architecture_allowed=True
)

WORLD_STYLE_DIORAMA = WorldStyle(
    id="preset_diorama",
    name="Diorama Studio",
    preset_type="diorama",
    background_rules="""Infinite cyan/blue cyclorama background. NO ceiling, NO light fixtures, NO visible walls, NO corners, NO architectural structure. The blue exists in all directions. This creates a clean studio aesthetic.""",
    floor_rules="""Thematic floor correlated with the script (grass patch, sand area, concrete slab, wooden platform, etc.) placed directly on the blue background. Floor should be a defined area, not infinite.""",
    secondary_characters_rules="""Smooth plastic-like skin, matte opaque finish, no pores, mannequin quality. Same material aesthetic as the character's translucent shell but fully opaque. NEVER photorealism with pores. Slightly desaturated skin tones.""",
    lighting_rules="""Studio lighting with soft, even shadows. No visible light sources. Clean, professional illumination. Soft key light with subtle fill. No harsh shadows unless narratively required.""",
    props_rules="""2-4 simple clean props only. Less is more. Props placed directly on thematic floor. Props should be clean, well-defined objects that support the narrative without cluttering the scene.""",
    architecture_allowed=False
)


# ---------------------------------------------------------------------------
# Clothing Style Presets
# ---------------------------------------------------------------------------

CLOTHING_STYLE_MINIMAL = ClothingStyle(
    id="preset_minimal",
    name="Minimal Anatomical",
    preset_type="minimal",
    clothing_rules="""Simple dark shorts mid-thigh ONLY. No shirt. No jacket. No closed shoes. No accessories covering the body. The anatomical visibility is the product - never hide anatomy with clothing. If footwear is needed, open sandals only.""",
    opacity_rules="""100% opaque solid fabric. Completely hide skeleton/body underneath the clothing. Real material texture (cotton, denim), NOT transparent overlay. Fabric should look tangible and real.""",
    max_pieces=1
)

CLOTHING_STYLE_THEMATIC = ClothingStyle(
    id="preset_thematic",
    name="Thematic Free",
    preset_type="thematic",
    clothing_rules="""Claude freely chooses clothing that best represents the script and narrative context. Maximum 1-2 pieces total. Anatomical visibility remains important - avoid fully covering torso AND arms AND legs simultaneously. Describe contextual wear, damage, or weathering in detail when appropriate.""",
    opacity_rules="""100% opaque solid fabric. Real material (cotton, denim, wool, leather, etc.). NOT transparent overlay. Clothing should look worn and lived-in when contextually appropriate.""",
    max_pieces=2
)


# ---------------------------------------------------------------------------
# Production Rules Presets
# ---------------------------------------------------------------------------

PRODUCTION_RULES_STANDARD = ProductionRules(
    id="preset_standard",
    name="Standard Cinematic",
    camera_settings="""Medium or medium-wide shot as default. Eye-level or chest-level camera. No extreme angles unless narratively justified. Same framing logic across scenes for consistency. Camera should feel like a documentary observer.""",
    pose_rule="""Character's POSE, BODY POSITION, and GESTURE MUST change per scene to match the script. NEVER neutral standing pose unless script explicitly requires it. NEVER repeat identical poses in consecutive scenes. Every pose should communicate emotion and action.""",
    shot_intercalation_rules="""Minimum 4 different angles throughout video. Alternate between: close-up, medium, wide, aerial/overhead. Never repeat the same framing in consecutive scenes. Rule of thirds: every 3 scenes, at least 1 should be extreme close-up or macro anatomical.""",
    death_scene_rules="""Overhead 100% camera angle (looking straight down). Asymmetric fall posture - head turned to one side, NOT facing camera. Pale blue-white bioluminescent translucent fluid pooling and spreading organically outward from skull and torso across the ground.""",
    child_rules="""ALWAYS depicted as small blurred indistinct human-shaped silhouette. NO facial features visible. NO detailed body. Purely abstract shape suggesting a child. If infected/zombie: silhouette + green-grey coloring applied to the abstract form. Horror transmitted through color and posture, never through detailed depiction.""",
    zombie_rules="""Infection communicated ONLY by: green-grey desaturated skin coloring, unnatural posture (curved spine, head tilted at wrong angle), empty vacant eyes. ZERO wounds. ZERO decomposition. ZERO gore. ZERO blood. The horror is in the wrongness of posture and color, not in graphic detail.""",
    consequence_philosophy="""Show the CONSEQUENCE, not the symptom. The character doesn't have a red jaw - they CRUSH meat. They don't have a glowing stomach - they EAT with visible satisfaction. The action REPRESENTS the concept. Always show the character DOING something that embodies the narrative beat.""",
    scale_rule="""Character at identical human scale to every person around. In crowds, the character is pushed, bumped, and partially obscured by others. Never giant. Never artificially isolated in a crowd. The character is a person among people."""
)


# ---------------------------------------------------------------------------
# Preset Collections (for easy access)
# ---------------------------------------------------------------------------

WORLD_STYLE_PRESETS = {
    "realistic": WORLD_STYLE_REALISTIC,
    "diorama": WORLD_STYLE_DIORAMA,
}

CLOTHING_STYLE_PRESETS = {
    "minimal": CLOTHING_STYLE_MINIMAL,
    "thematic": CLOTHING_STYLE_THEMATIC,
}

PRODUCTION_RULES_PRESETS = {
    "standard": PRODUCTION_RULES_STANDARD,
}


def get_world_style(preset_id: str) -> WorldStyle | None:
    """Get a world style preset by ID."""
    if preset_id.startswith("preset_"):
        key = preset_id.replace("preset_", "")
        return WORLD_STYLE_PRESETS.get(key)
    return WORLD_STYLE_PRESETS.get(preset_id)


def get_clothing_style(preset_id: str) -> ClothingStyle | None:
    """Get a clothing style preset by ID."""
    if preset_id.startswith("preset_"):
        key = preset_id.replace("preset_", "")
        return CLOTHING_STYLE_PRESETS.get(key)
    return CLOTHING_STYLE_PRESETS.get(preset_id)


def get_production_rules(preset_id: str) -> ProductionRules | None:
    """Get a production rules preset by ID."""
    if preset_id.startswith("preset_"):
        key = preset_id.replace("preset_", "")
        return PRODUCTION_RULES_PRESETS.get(key)
    return PRODUCTION_RULES_PRESETS.get(preset_id)


def list_world_styles() -> list[dict]:
    """List all available world style presets."""
    return [
        {"id": ws.id, "name": ws.name, "preset_type": ws.preset_type, "is_preset": True}
        for ws in WORLD_STYLE_PRESETS.values()
    ]


def list_clothing_styles() -> list[dict]:
    """List all available clothing style presets."""
    return [
        {"id": cs.id, "name": cs.name, "preset_type": cs.preset_type, "is_preset": True}
        for cs in CLOTHING_STYLE_PRESETS.values()
    ]


def list_production_rules() -> list[dict]:
    """List all available production rules presets."""
    return [
        {"id": pr.id, "name": pr.name, "is_preset": True}
        for pr in PRODUCTION_RULES_PRESETS.values()
    ]
