"""Mapper for converting between CanvasMetadataDB entity and CanvasMetadata schemas"""
import uuid
from datetime import datetime
from typing import Optional

from src.models.entities import CanvasMetadataDB
from src.models.schemas import (
    CanvasMetadata,
    CreateGeneralCanvasRequest,
    UpdateCanvasMetadataRequest,
)


class CanvasMetadataMapper:
    """Mapper for CanvasMetadata entity and schemas"""
    
    @staticmethod
    def to_schema(db: CanvasMetadataDB) -> CanvasMetadata:
        """Convert CanvasMetadataDB entity to CanvasMetadata schema
        
        Args:
            db: CanvasMetadataDB entity from database
            
        Returns:
            CanvasMetadata schema for API response
        """
        return CanvasMetadata(
            id=db.id,
            projectId=db.project_id,
            canvasType=db.canvas_type,
            relatedEntityType=db.related_entity_type,
            relatedEntityId=db.related_entity_id,
            name=db.name,
            description=db.description,
            orderIndex=db.order_index,
            isPinned=db.is_pinned,
            tags=db.tags or [],
            nodeCount=db.node_count,
            lastAccessedAt=db.last_accessed_at,
            accessCount=db.access_count,
            createdAt=db.created_at,
            updatedAt=db.updated_at,
            deletedAt=db.deleted_at,
        )
    
    @staticmethod
    def to_entity(
        schema: CreateGeneralCanvasRequest,
        project_id: str,
        canvas_id: Optional[str] = None
    ) -> CanvasMetadataDB:
        """Convert CreateGeneralCanvasRequest schema to CanvasMetadataDB entity
        
        Args:
            schema: CreateGeneralCanvasRequest from API
            project_id: Project ID this canvas belongs to
            canvas_id: Optional canvas ID (generated if not provided)
            
        Returns:
            CanvasMetadataDB entity for database storage
        """
        now = datetime.now().timestamp()
        
        return CanvasMetadataDB(
            id=canvas_id or str(uuid.uuid4()),
            project_id=project_id,
            canvas_type="general",
            name=schema.name,
            description=schema.description,
            order_index=0,
            is_pinned=False,
            tags=[],
            node_count=0,
            access_count=0,
            created_at=now,
            updated_at=now,
        )
    
    @staticmethod
    def create_asset_canvas(
        project_id: str,
        asset_id: str,
        asset_name: str,
        canvas_id: Optional[str] = None
    ) -> CanvasMetadataDB:
        """ Create CanvasMetadataDB entity for an asset canvas
        
        Args:
            project_id: Project ID
            asset_id: Asset ID this canvas is linked to
            asset_name: Asset name for canvas name
            canvas_id: Optional canvas ID (generated if not provided)
            
        Returns:
            CanvasMetadataDB entity for database storage
        """
        now = datetime.now().timestamp()
        
        return CanvasMetadataDB(
            id=canvas_id or str(uuid.uuid4()),
            project_id=project_id,
            canvas_type="asset",
            related_entity_type="asset",
            related_entity_id=asset_id,
            name=f"{asset_name} Canvas",
            order_index=0,
            is_pinned=False,
            tags=[],
            node_count=0,
            access_count=0,
            created_at=now,
            updated_at=now,
        )
    
    @staticmethod
    def create_storyboard_canvas(
        project_id: str,
        storyboard_id: str,
        storyboard_shot: str,
        canvas_id: Optional[str] = None
    ) -> CanvasMetadataDB:
        """ Create CanvasMetadataDB entity for a storyboard canvas
        
        Args:
            project_id: Project ID
            storyboard_id: Storyboard ID this canvas is linked to
            storyboard_shot: Storyboard shot for canvas name
            canvas_id: Optional canvas ID (generated if not provided)
            
        Returns:
            CanvasMetadataDB entity for database storage
        """
        now = datetime.now().timestamp()
        
        return CanvasMetadataDB(
            id=canvas_id or str(uuid.uuid4()),
            project_id=project_id,
            canvas_type="storyboard",
            related_entity_type="storyboard",
            related_entity_id=storyboard_id,
            name=f"{storyboard_shot} Canvas",
            order_index=0,
            is_pinned=False,
            tags=[],
            node_count=0,
            access_count=0,
            created_at=now,
            updated_at=now,
        )
    
    @staticmethod
    def update_entity(
        db: CanvasMetadataDB,
        schema: UpdateCanvasMetadataRequest
    ) -> CanvasMetadataDB:
        """Update CanvasMetadataDB entity with data from UpdateCanvasMetadataRequest schema
        
        Args:
            db: Existing CanvasMetadataDB entity
            schema: UpdateCanvasMetadataRequest with new data
            
        Returns:
            Updated CanvasMetadataDB entity
        """
        if schema.name is not None:
            db.name = schema.name
        
        if schema.description is not None:
            db.description = schema.description
        
        if schema.is_pinned is not None:
            db.is_pinned = schema.is_pinned
        
        if schema.tags is not None:
            db.tags = schema.tags
        
        db.updated_at = datetime.now().timestamp()
        
        return db
    
    @staticmethod
    def update_access(db: CanvasMetadataDB) -> CanvasMetadataDB:
        """Update canvas access tracking
        
        Args:
            db: Existing CanvasMetadataDB entity
            
        Returns:
            Updated CanvasMetadataDB entity
        """
        db.last_accessed_at = datetime.now().timestamp()
        db.access_count += 1
        db.updated_at = datetime.now().timestamp()
        
        return db
