from typing import List, Optional
from pydantic import BaseModel, Field, ConfigDict

class CharacterExtraction(BaseModel):
    name: str = Field(description="Character Name")
    desc: str = Field(description="Brief description or role in this text")
    age: str = Field(description="Approximate age (e.g. '25', 'Teenager', 'Unknown')")
    gender: str = Field(description="Gender")
    role: str = Field(description="Role classification")
    emotion: Optional[str] = Field(None, description="Primary emotional state")
    appearance: str = Field(description="Appearance features")
    tags: List[str] = Field(description="List of keywords/tags describing the character")
    image_prompt: str = Field(description="Visual prompt for character image generation, combining appearance and style details without using character name")

class CharacterList(BaseModel):
    characters: List[CharacterExtraction]
    is_complete: bool = Field(default=True, description="Whether all characters have been extracted")
    continuation_context: Optional[str] = Field(None, description="Context for continuing extraction if incomplete")

class SceneExtraction(BaseModel):
    name: str = Field(description="Scene Name")
    desc: str = Field(description="Visual description of the environment")
    location: str = Field(description="General location setting")
    environment_type: Optional[str] = Field(None, description="Space type (e.g. 'Indoor', 'Outdoor', 'Natural')")
    time_of_day: str = Field(description="Time setting (e.g. 'Night', 'Early Morning')")
    weather: Optional[str] = Field(None, description="Weather condition (e.g. 'Sunny', 'Rainy', 'Foggy')")
    atmosphere: str = Field(description="Mood/Atmosphere")
    tags: List[str] = Field(description="List of keywords/tags describing the scene")
    image_prompt: str = Field(description="Visual prompt for scene image generation, describing environment, lighting, and atmosphere")

class SceneList(BaseModel):
    scenes: List[SceneExtraction]
    is_complete: bool = Field(default=True, description="Whether all scenes have been extracted")
    continuation_context: Optional[str] = Field(None, description="Context for continuing extraction if incomplete")

class PropExtraction(BaseModel):
    name: str = Field(description="Prop Name")
    desc: str = Field(description="Visual description")
    usage: str = Field(description="Why it is important to the plot or how it is used")
    tags: List[str] = Field(description="List of keywords/tags describing the prop")
    image_prompt: str = Field(description="Visual prompt for prop image generation, describing appearance, material, and key features")

class PropList(BaseModel):
    props: List[PropExtraction]
    is_complete: bool = Field(default=True, description="Whether all props have been extracted")
    continuation_context: Optional[str] = Field(None, description="Context for continuing extraction if incomplete")

class NovelSummary(BaseModel):
    title: str = Field(description="Suggested Title (if applicable, or Chapter Title)")
    summary: str = Field(description="The concise summary text capturing main plot, key events, and central themes")

class StoryboardShot(BaseModel):
    shot_number: int
    shot_title: str
    visual_description: str
    dialogue: Optional[str] = None
    duration: str
    shot_type: str
    camera_movement: str
    camera_angle: str = Field(description="Camera angle (e.g. 'Eye Level', 'Low Angle', 'High Angle'). REQUIRED.")
    lens: str = Field(description="Lens focal length (e.g. 'Wide', 'Standard', 'Telephoto'). REQUIRED.")
    focus: str = Field(description="Focus control (e.g. 'Deep Focus', 'Shallow Depth of Field'). REQUIRED.")
    lighting: str = Field(description="Lighting style (e.g. 'Natural Light', 'Cinematic Lighting', 'High Contrast'). REQUIRED.")
    color_style: str = Field(description="Color grading style (e.g. 'Warm Tone', 'Cool Tone', 'Desaturated'). REQUIRED.")
    transition: str
    audio_description: str
    character_list: List[str] = Field(default_factory=list)
    prop_list: List[str] = Field(default_factory=list)
    location: str
    time_of_day: str
    original_text: Optional[str] = Field(None, description="Original novel text corresponding to this shot")
    merge_image_prompt: str = Field(description="Integrated visual prompt combining characters, scene, and shot description for image generation, without using character names")
    video_prompt: str = Field(description="Motion and action prompt for video generation, describing movements, expressions, and dynamic changes")

class StoryboardList(BaseModel):
    storyboards: List[StoryboardShot]
    is_complete: bool = Field(default=True, description="Whether all storyboards have been generated. Set to False if more content needs to be processed.")
    continuation_context: Optional[str] = Field(None, description="Context for continuing generation if is_complete is False. Should indicate where to continue from.")

class MergedAsset(BaseModel):
    model_config = ConfigDict(extra="allow")
    
    id: str
    name: str
    desc: str
    type: str
    tags: List[str] = []

class MergeMapping(BaseModel):
    target_id: str
    source_ids: List[str]

class DeduplicationResult(BaseModel):
    merged_assets: List[MergedAsset]
    merge_mapping: List[MergeMapping]

class Chapter(BaseModel):
    title: str = Field(description="Chapter title")
    content: str = Field(description="Chapter content")
    summary: Optional[str] = Field(None, description="Brief summary of the chapter")

class ChapterList(BaseModel):
    chapters: List[Chapter]

class StyleRecommendation(BaseModel):
    style: str = Field(description="Recommended visual style")
    reasoning: str = Field(description="Reasoning for the recommendation")


class ScriptDiscussion(BaseModel):
    adaptation_strategy: str = Field(description="High-level adaptation strategy for turning the novel into a screenplay")
    episode_structure: List[str] = Field(default_factory=list, description="Suggested episode or act structure")
    character_focus: List[str] = Field(default_factory=list, description="Key character notes to preserve during adaptation")
    dialogue_guidelines: List[str] = Field(default_factory=list, description="Notes for preserving tone and dialogue")


class ScreenplayDraft(BaseModel):
    title: str = Field(description="Episode or section title")
    summary: str = Field(description="Brief summary of the screenplay draft")
    screenplay: str = Field(description="The screenplay text adapted from the source content")
