"""
Asset-related schemas.
"""
from typing import List, Optional, Literal
from pydantic import BaseModel, Field, ConfigDict

from .common import AssetType
from .generation import GenerationRecord


class BaseAsset(BaseModel):
    id: str
    type: AssetType
    name: str
    desc: str
    tags: List[str] = []
    image_url: Optional[str] = Field(None, alias="imageUrl")
    image_urls: Optional[List[str]] = Field(None, alias="imageUrls")
    video_urls: Optional[List[str]] = Field(None, alias="videoUrls")
    audio_url: Optional[str] = Field(None, alias="audioUrl")
    image_prompt: Optional[str] = Field(None, alias="imagePrompt")
    generations: Optional[List[GenerationRecord]] = []

    model_config = ConfigDict(populate_by_name=True)


class CharacterAsset(BaseAsset):
    type: Literal['character'] = 'character'
    age: Optional[str] = None
    gender: Optional[str] = None
    role: Optional[str] = None
    emotion: Optional[str] = None
    appearance: Optional[str] = None


class SceneAsset(BaseAsset):
    type: Literal['scene'] = 'scene'
    location: Optional[str] = None
    time_of_day: Optional[str] = Field(None, alias="timeOfDay")
    environment_type: Optional[str] = Field(None, alias="environmentType")
    weather: Optional[str] = None
    atmosphere: Optional[str] = None


class PropAsset(BaseAsset):
    type: Literal['prop'] = 'prop'
    usage: Optional[str] = None


class AudioAsset(BaseAsset):
    type: Literal['audio'] = 'audio'
    duration: Optional[int] = None


class OtherAsset(BaseAsset):
    type: Literal['other'] = 'other'


Asset = CharacterAsset | SceneAsset | PropAsset | AudioAsset | OtherAsset


# Asset request schemas
class CreateCharacterAssetRequest(BaseModel):
    type: Literal['character'] = 'character'
    name: str
    desc: str
    tags: List[str] = []
    image_url: Optional[str] = Field(None, alias="imageUrl")
    image_urls: Optional[List[str]] = Field(None, alias="imageUrls")
    video_urls: Optional[List[str]] = Field(None, alias="videoUrls")
    image_prompt: Optional[str] = Field(None, alias="imagePrompt")
    age: Optional[str] = None
    gender: Optional[str] = None
    role: Optional[str] = None
    appearance: Optional[str] = None

    model_config = ConfigDict(populate_by_name=True)


class CreateSceneAssetRequest(BaseModel):
    type: Literal['scene'] = 'scene'
    name: str
    desc: str
    tags: List[str] = []
    image_url: Optional[str] = Field(None, alias="imageUrl")
    image_urls: Optional[List[str]] = Field(None, alias="imageUrls")
    video_urls: Optional[List[str]] = Field(None, alias="videoUrls")
    image_prompt: Optional[str] = Field(None, alias="imagePrompt")
    location: Optional[str] = None
    time_of_day: Optional[str] = Field(None, alias="timeOfDay")
    atmosphere: Optional[str] = None

    model_config = ConfigDict(populate_by_name=True)


class CreatePropAssetRequest(BaseModel):
    type: Literal['prop'] = 'prop'
    name: str
    desc: str
    tags: List[str] = []
    image_url: Optional[str] = Field(None, alias="imageUrl")
    image_urls: Optional[List[str]] = Field(None, alias="imageUrls")
    video_urls: Optional[List[str]] = Field(None, alias="videoUrls")
    image_prompt: Optional[str] = Field(None, alias="imagePrompt")
    usage: Optional[str] = None

    model_config = ConfigDict(populate_by_name=True)


class CreateOtherAssetRequest(BaseModel):
    type: Literal['other'] = 'other'
    name: str
    desc: str
    tags: List[str] = []
    image_url: Optional[str] = Field(None, alias="imageUrl")
    image_urls: Optional[List[str]] = Field(None, alias="imageUrls")
    video_urls: Optional[List[str]] = Field(None, alias="videoUrls")
    image_prompt: Optional[str] = Field(None, alias="imagePrompt")

    model_config = ConfigDict(populate_by_name=True)


CreateAssetRequest = CreateCharacterAssetRequest | CreateSceneAssetRequest | CreatePropAssetRequest | CreateOtherAssetRequest


class UpdateAssetRequest(BaseModel):
    name: Optional[str] = None
    desc: Optional[str] = None
    tags: Optional[List[str]] = None
    image_url: Optional[str] = Field(None, alias="imageUrl")
    image_urls: Optional[List[str]] = Field(None, alias="imageUrls")
    video_urls: Optional[List[str]] = Field(None, alias="videoUrls")
    image_prompt: Optional[str] = Field(None, alias="imagePrompt")
    # Specific fields
    age: Optional[str] = None
    role: Optional[str] = None
    appearance: Optional[str] = None
    location: Optional[str] = None
    time_of_day: Optional[str] = Field(None, alias="timeOfDay")
    atmosphere: Optional[str] = None
    usage: Optional[str] = None
    generations: Optional[List[GenerationRecord]] = None

    model_config = ConfigDict(populate_by_name=True)
