""" Event models """
import uuid
from datetime import datetime
from typing import List, Optional, Dict, Any
from enum import Enum
from .relationship_event_service import EventService
from .base import SQLModel
from sqlmodel import Field, Relationship, Column, JSON

class TipusEvent(str, Enum):
    """Tipos de eventos disponibles"""
    BODA = "boda"
    GRADUACIO = "graduacio"
    FESTA = "festa"
    CELEBRACIO = "celebracio"
    MENJAR_GRUP = "menjar_grup"
    ALTRES = "altres"

class EstadoEvent(str, Enum):
    """Estados de un evento"""
    EN_CURSO = "en_curso"
    GUARDADO = "guardado"
    PAGADO = "pagado"
    EXPIRADO = "expirado"
    CANCELADO = "cancelado"
    FINALIZADO = "finalizado"

class EventBase(SQLModel):
    """Modelo base para eventos"""
    name: str = Field(max_length=255, description="Nombre del evento")
    tipus: TipusEvent = Field(description="Tipo de evento")
    pressupost: float = Field(default=0, description="Presupuesto del evento")
    data_inici: datetime = Field(description="Fecha y hora de inicio del evento")
    data_fi: datetime = Field(description="Fecha y hora de finalización del evento")
    num_invitats: int = Field(description="Número de invitados")

# Database model
class Event(EventBase, table=True):
    """Modelo de base de datos para eventos"""
    id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
    account_id: uuid.UUID = Field(foreign_key="account.id")
    account: "Account" = Relationship(back_populates="events")
    services: List["Service"] = Relationship(back_populates="events", link_model=EventService)
    estat: EstadoEvent = Field(default=EstadoEvent.GUARDADO, description="Estado del evento")
    espai_propi_id: Optional[uuid.UUID] = Field(default=None, foreign_key="espai_propi.id", description="ID del espacio propio del evento")
    espai_propi: Optional["EspaiPropi"] = Relationship(back_populates="events")

class EventUpdate(SQLModel):
    """Modelo para actualizar eventos"""
    name: Optional[str] = Field(default=None, max_length=255, description="Nombre del evento")
    tipus: Optional[TipusEvent] = Field(default=None, description="Tipo de evento")
    pressupost: Optional[float] = Field(default=None, description="Presupuesto del evento")
    data_inici: Optional[datetime] = Field(default=None, description="Fecha y hora de inicio del evento")
    data_fi: Optional[datetime] = Field(default=None, description="Fecha y hora de finalización del evento")
    num_invitats: Optional[int] = Field(default=None, description="Número de invitados")
    estat: Optional[EstadoEvent] = Field(default=None, description="Estado del evento")
    espai_propi_id: Optional[uuid.UUID] = Field(default=None, foreign_key="espai_propi.id", description="ID del espacio propio del evento")
    espai_propi: Optional[Dict[str, Any]] = Field(default=None, description="Espacio propio del evento")


class EventCreate(EventBase):
    """Modelo para crear eventos"""
    espai_propi_id: Optional[uuid.UUID] = Field(default=None, foreign_key="espai_propi.id", description="ID del espacio propio del evento")
    espai_propi: Optional[Dict[str, Any]] = Field(default=None, description="Espacio propio del evento")
    estat: Optional[EstadoEvent] = Field(default=EstadoEvent.GUARDADO, description="Estado del evento")

class EventOut(EventBase):
    """Modelo de salida para eventos"""
    id: uuid.UUID
    account_id: uuid.UUID
    espai_propi_id: Optional[uuid.UUID] = None
    espai_propi: Optional[Dict[str, Any]] = None
    estat: Optional[EstadoEvent] = None

class EventsOut(SQLModel):
    """Modelo de salida para listas de eventos"""
    data: List[EventOut] = Field(description="Lista de eventos")
    count: int = Field(description="Número total de eventos")

class EventAllServicesOut(EventBase):
    """Modelo de salida para eventos y servicios"""
    id: uuid.UUID
    account_id: uuid.UUID
    estat: Optional[EstadoEvent] = None
    espai_propi_id: Optional[uuid.UUID] = None
    espai_propi: Optional[Dict[str, Any]] = None
    services: Optional[List[Dict[str, Any]]] = None

class EventsAllServicesOut(SQLModel):
    """Modelo de salida para listas de eventos y servicios"""
    data: List[EventAllServicesOut] = Field(description="Lista de eventos y servicios")
    count: int = Field(description="Número total de eventos y servicios")