"""Mapper for converting between StoryboardDB entity and Storyboard schemas"""
import uuid
from datetime import datetime

from src.models.entities import StoryboardDB
from src.models.schemas import (
    Storyboard,
    CreateStoryboardRequest,
    UpdateStoryboardRequest,
    GenerationRecord,
)


class StoryboardMapper:
    """Mapper for Storyboard entity and schemas"""
    
    @staticmethod
    def to_schema(db: StoryboardDB) -> Storyboard:
        """Convert StoryboardDB entity to Storyboard schema
        
        Args:
            db: StoryboardDB entity from database
            
        Returns:
            Storyboard schema for API response
        """
        # Parse generations
        generations = []
        if db.generations:
            try:
                from pydantic import TypeAdapter
                adapter = TypeAdapter(list[GenerationRecord])
                generations = adapter.validate_python(db.generations)
            except Exception:
                generations = []
        
        return Storyboard(
            id=db.id,
            episode_id=db.episode_id,
            order=db.order_index,
            shot=db.shot,
            desc=db.desc,
            duration=db.duration,
            type=db.type,
            scene_id=db.scene_id,
            character_ids=db.character_ids or [],
            prop_ids=db.prop_ids or [],
            voiceover=db.voiceover,
            audio_desc=db.audio_desc,
            audio_url=db.audio_url,
            camera_movement=db.camera_movement,
            transition=db.transition,
            camera_angle=db.camera_angle,
            lens=db.lens,
            focus=db.focus,
            lighting=db.lighting,
            color_style=db.color_style,
            location=db.location,
            time=db.time,
            original_text=db.original_text,
            merge_image_prompt=db.merge_image_prompt,
            video_prompt=db.video_prompt,
            image_urls=db.image_urls,
            video_urls=db.video_urls,
            generations=generations,
        )
    
    @staticmethod
    def to_entity(
        schema: CreateStoryboardRequest,
        project_id: str,
        storyboard_id: str = None
    ) -> StoryboardDB:
        """Convert CreateStoryboardRequest schema to StoryboardDB entity
        
        Args:
            schema: CreateStoryboardRequest from API
            project_id: Project ID this storyboard belongs to
            storyboard_id: Optional storyboard ID (generated if not provided)
            
        Returns:
            StoryboardDB entity for database storage
        """
        return StoryboardDB(
            id=storyboard_id or str(uuid.uuid4()),
            project_id=project_id,
            episode_id=schema.episode_id,
            order_index=schema.order,
            shot=schema.shot,
            desc=schema.desc,
            duration=schema.duration,
            type=schema.type,
            scene_id=schema.scene_id,
            character_ids=schema.character_ids or [],
            prop_ids=schema.prop_ids or [],
            voiceover=schema.voiceover,
            audio_desc=schema.audio_desc,
            audio_url=schema.audio_url,
            camera_movement=schema.camera_movement,
            transition=schema.transition,
            camera_angle=schema.camera_angle,
            lens=schema.lens,
            focus=schema.focus,
            lighting=schema.lighting,
            color_style=schema.color_style,
            location=schema.location,
            time=schema.time,
            original_text=schema.original_text,
            merge_image_prompt=schema.merge_image_prompt,
            video_prompt=schema.video_prompt,
            image_urls=schema.image_urls,
            video_urls=schema.video_urls,
            generations=[],
        )
    
    @staticmethod
    def update_entity(db: StoryboardDB, schema: UpdateStoryboardRequest) -> StoryboardDB:
        """Update StoryboardDB entity with data from UpdateStoryboardRequest schema
        
        Args:
            db: Existing StoryboardDB entity
            schema: UpdateStoryboardRequest with new data
            
        Returns:
            Updated StoryboardDB entity
        """
        # Update all provided fields
        if schema.episode_id is not None:
            db.episode_id = schema.episode_id
        
        if schema.order is not None:
            db.order_index = schema.order
        
        if schema.shot is not None:
            db.shot = schema.shot
        
        if schema.desc is not None:
            db.desc = schema.desc
        
        if schema.duration is not None:
            db.duration = schema.duration
        
        if schema.type is not None:
            db.type = schema.type
        
        if schema.scene_id is not None:
            db.scene_id = schema.scene_id
        
        if schema.character_ids is not None:
            db.character_ids = schema.character_ids
        
        if schema.prop_ids is not None:
            db.prop_ids = schema.prop_ids
        
        if schema.voiceover is not None:
            db.voiceover = schema.voiceover
        
        if schema.audio_desc is not None:
            db.audio_desc = schema.audio_desc
        
        if schema.audio_url is not None:
            db.audio_url = schema.audio_url
        
        if schema.camera_movement is not None:
            db.camera_movement = schema.camera_movement
        
        if schema.transition is not None:
            db.transition = schema.transition
        
        if schema.camera_angle is not None:
            db.camera_angle = schema.camera_angle
        
        if schema.lens is not None:
            db.lens = schema.lens
        
        if schema.focus is not None:
            db.focus = schema.focus
        
        if schema.lighting is not None:
            db.lighting = schema.lighting
        
        if schema.color_style is not None:
            db.color_style = schema.color_style
        
        if schema.location is not None:
            db.location = schema.location
        
        if schema.time is not None:
            db.time = schema.time
        
        if schema.original_text is not None:
            db.original_text = schema.original_text
        
        if schema.merge_image_prompt is not None:
            db.merge_image_prompt = schema.merge_image_prompt
        
        if schema.video_prompt is not None:
            db.video_prompt = schema.video_prompt
        
        if schema.image_urls is not None:
            db.image_urls = schema.image_urls
        
        if schema.video_urls is not None:
            db.video_urls = schema.video_urls
        
        if schema.generations is not None:
            # Convert GenerationRecord objects to dicts
            db.generations = [gen.model_dump() for gen in schema.generations]
        
        return db
