""" Musica service models """
import uuid
from typing import List, Optional, Dict, Any
from enum import Enum

from sqlmodel import Field, Relationship, Column, JSON
from .base import SQLModel


class MusicaEstilo(str, Enum):
    """Estilos de música disponibles"""
    DJ = "dj"
    MUSICO = "musico"


class Canciones(str, Enum):
    """Tipos de canciones disponibles"""
    PROPIAS = "propias"
    VERSIONES = "versiones"


class Generos(str, Enum):
    """Géneros musicales disponibles"""
    POP = "pop"
    ROCK = "rock"
    JAZZ = "jazz"
    BLUES = "blues"
    SOUL = "soul"
    FUNK = "funk"
    R_B = "r&b"
    HIP_HOP = "hip-hop"
    ELECTRONIC = "electronic"
    HOUSE = "house"
    TECHNO = "techno"
    REGGAETON = "reggaeton"
    SALSA = "salsa"
    BACHATA = "bachata"
    MERENGUE = "merengue"
    FLAMENCO = "flamenco"
    CLASICA = "clasica"
    INDIE = "indie"
    METAL = "metal"
    PUNK = "punk"
    COUNTRY = "country"
    FOLK = "folk"
    LATIN = "latin"
    DISCO = "disco"
    REGGAE = "reggae"
    GOSPEL = "gospel"
    BOSSA_NOVA = "bossa-nova"
    SAMBA = "samba"
    TANGO = "tango"
    BALLROOM = "ballroom"


class MusicaBase(SQLModel):
    """Modelo base para servicios de música"""
    musica_type: MusicaEstilo = Field(description="Tipo de servicio musical (DJ o Músico)")
    canciones: Canciones = Field(description="Tipo de canciones (propias o versiones)")
    generos: List[Generos] = Field(sa_column=Column(JSON), description="Géneros musicales que se interpretan")
    duracion: float = Field(description="Duración del servicio en horas")
    instrumentos: List[str] = Field(sa_column=Column(JSON), description="Instrumentos utilizados")
    caracteristicas: Optional[List[str]] = Field(default_factory=list, sa_column=Column(JSON), description="Características especiales del servicio")


# Database model
class Musica(MusicaBase, table=True):
    """Modelo de base de datos para servicios de música"""
    id: uuid.UUID = Field(default=None, primary_key=True, foreign_key="service.id", description="ID único del servicio de música")
    service: "Service" = Relationship(back_populates="musica")
    raider_id: uuid.UUID = Field(foreign_key="raider.id")
    raider: "Raider" = Relationship(back_populates="musicas")


# Out models
class MusicaOut(MusicaBase):
    """Modelo de salida para servicios de música"""
    id: uuid.UUID
    raider_id: uuid.UUID


class MusicasOut(SQLModel):
    """Modelo de salida para listas de servicios de música"""
    data: List[MusicaOut] = Field(description="Lista de servicios de música")
    count: int = Field(description="Número total de servicios")


class MusicaServiceOut(MusicaBase):
    """Modelo de salida para servicios de música"""
    id: uuid.UUID
    raider_id: uuid.UUID
    raider: Dict[str, Any] = Field(default=None, sa_column=Column(JSON))


class MusicasServiceOut(SQLModel):
    """Modelo de salida para listas de servicios de música"""
    data: List[MusicaServiceOut] = Field(description="Lista de servicios de música")
    count: int = Field(description="Número total de servicios")


# Create/Update models
class MusicaCreate(MusicaBase):
    """Modelo para crear servicios de música"""
    pass


class MusicaUpdate(SQLModel):
    """Modelo para actualizar servicios de música"""
    musica_type: Optional[MusicaEstilo] = Field(default=None, description="Tipo de servicio musical (DJ o Músico)")
    canciones: Optional[Canciones] = Field(default=None, description="Tipo de canciones (propias o versiones)")
    generos: Optional[List[Generos]] = Field(default=None, sa_column=Column(JSON), description="Géneros musicales que se interpretan")
    duracion: Optional[float] = Field(default=None, description="Duración del servicio en horas")
    instrumentos: Optional[List[str]] = Field(default=None, sa_column=Column(JSON), description="Instrumentos utilizados")
    caracteristicas: Optional[List[str]] = Field(default=None, sa_column=Column(JSON), description="Características especiales del servicio")


class MusicaServiceCreate(MusicaBase):
    """Modelo para crear servicios de música"""
    raider: Dict[str, Any] = Field(default=None, sa_column=Column(JSON))


class MusicaServiceUpdate(SQLModel):
    """Modelo para actualizar servicios de música"""
    musica_type: Optional[MusicaEstilo] = Field(default=None, description="Tipo de servicio musical (DJ o Músico)")
    canciones: Optional[Canciones] = Field(default=None, description="Tipo de canciones (propias o versiones)")
    generos: Optional[List[Generos]] = Field(default=None, sa_column=Column(JSON), description="Géneros musicales que se interpretan")
    duracion: Optional[float] = Field(default=None, description="Duración del servicio en horas")
    instrumentos: Optional[List[str]] = Field(default=None, sa_column=Column(JSON), description="Instrumentos utilizados")
    caracteristicas: Optional[List[str]] = Field(default=None, sa_column=Column(JSON), description="Características especiales del servicio")
    raider: Optional[Dict[str, Any]]  = Field(default=None, sa_column=Column(JSON))
