from pydantic import BaseModel, Field
from typing import List, Dict, Any, Optional
from uuid import UUID
from enum import Enum

from app.model.base import ServicioBase, ServicioBaseCreate, ServicioBaseUpdate, ServicioBaseOut, Address
from app.model.fotografia import DimensionesEscenario, IntegranteEquipo


class MusicaType(str, Enum):
    DJ = "DJ"
    BANDA = "BANDA"
    SOLISTA = "SOLISTA"
    ORQUESTA = "ORQUESTA"


class GeneroMusical(str, Enum):
    POP = "POP"
    ROCK = "ROCK"
    ELECTRONICA = "ELECTRONICA"
    LATINO = "LATINO"
    JAZZ = "JAZZ"
    CLASICA = "CLASICA"
    FOLK = "FOLK"
    REGGAE = "REGGAE"
    BLUES = "BLUES"
    HIP_HOP = "HIP_HOP"


class RaiderMusicaCreate(BaseModel):
    num_integrantes: int
    equipo: List[IntegranteEquipo]
    solicitar_cancion_nueva: bool
    coste_cancion_nueva: float
    equipo_propio: bool
    coste_equipo_propio: float
    disponible_sin_equipo: bool
    dimensiones_escenario: DimensionesEscenario
    condiciones: List[str]


class RaiderMusicaUpdate(BaseModel):
    num_integrantes: Optional[int] = None
    equipo: Optional[List[IntegranteEquipo]] = None
    solicitar_cancion_nueva: Optional[bool] = None
    coste_cancion_nueva: Optional[float] = None
    equipo_propio: Optional[bool] = None
    coste_equipo_propio: Optional[float] = None
    disponible_sin_equipo: Optional[bool] = None
    dimensiones_escenario: Optional[DimensionesEscenario] = None
    condiciones: Optional[List[str]] = None


class RaiderMusica(BaseModel):
    id: UUID
    num_integrantes: int
    equipo: List[IntegranteEquipo]
    solicitar_cancion_nueva: bool
    coste_cancion_nueva: float
    equipo_propio: bool
    coste_equipo_propio: float
    disponible_sin_equipo: bool
    dimensiones_escenario: DimensionesEscenario
    condiciones: List[str]


class RaiderMusicaOut(RaiderMusica):
    class Config:
        from_attributes = True


class MusicaDetailsCreate(BaseModel):
    musica_type: MusicaType
    duracion: float
    generos: List[GeneroMusical]
    caracteristicas: List[str]
    raider: RaiderMusicaCreate


class MusicaDetailsUpdate(BaseModel):
    musica_type: Optional[MusicaType] = None
    duracion: Optional[float] = None
    generos: Optional[List[GeneroMusical]] = None
    caracteristicas: Optional[List[str]] = None
    raider: Optional[RaiderMusicaUpdate] = None


class MusicaDetails(BaseModel):
    id: UUID
    musica_type: MusicaType
    duracion: float
    generos: List[GeneroMusical]
    caracteristicas: List[str]
    raider_id: UUID
    raider: RaiderMusica


class MusicaDetailsOut(MusicaDetails):
    class Config:
        from_attributes = True


class MusicaCreate(ServicioBaseCreate):
    musica: MusicaDetailsCreate


class MusicaUpdate(ServicioBaseUpdate):
    musica: Optional[MusicaDetailsUpdate] = None


class Musica(ServicioBase):
    musica: MusicaDetails


class MusicaOut(ServicioBaseOut):
    musica: MusicaDetailsOut
    
    class Config:
        from_attributes = True 