""" Espai service models """
import uuid
from typing import List, Optional
from enum import Enum
from pydantic import validator

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



class EspaiType(str, Enum):
    """Tipos de espacios disponibles"""
    MASIA = "masia"
    RESTAURANTE = "restaurante"
    HOTEL = "hotel"
    LOCAL = "local"
    SALA = "sala"
    COMEDOR = "comedor"
    DISCOTECA = "discoteca"
    ESPACIO_DE_ACTIVIDADES = "espacio_de_actividades"
    TERRAZA = "terraza"
    ATICO = "atico"
    CASTILLO = "castillo"
    JARDIN = "jardin"
    CASA_RURAL = "casa_rural"
    FINCA = "finca"
    MOLINO = "molino"
    VILLA = "villa"
    HACIENDA = "hacienda"
    ESPACIO_SINGULAR = "espacio_singular"
    PALACIO = "palacio"
    BOSQUE = "bosque"
    OTROS = "otros"


class EspaiBase(SQLModel):
    """Modelo base para espacios"""
    espai_type: EspaiType = Field(description="Tipo de espacio")
    capacitat_min: int = Field(description="Capacidad mínima de personas")
    capacitat_max: int = Field(description="Capacidad máxima de personas")
    caracteristicas: Optional[List[str]] = Field(default_factory=list, sa_column=Column(JSON))

    @validator('capacitat_max')
    def validate_capacitat_max(cls, v, values):
        """Valida que capacitat_max sea mayor o igual que capacitat_min"""
        if 'capacitat_min' in values and v < values['capacitat_min']:
            raise ValueError('capacitat_max debe ser mayor o igual que capacitat_min')
        return v



# Database model
class Espai(EspaiBase, table=True):
    """Modelo de base de datos para espacios"""
    id: uuid.UUID = Field(default=None, primary_key=True, foreign_key="service.id", description="ID único del espacio")
    service: "Service" = Relationship(back_populates="espai")


# Out models
class EspaiOut(EspaiBase):
    """Modelo de salida para espacios"""
    id: uuid.UUID

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


class EspaiServiceOut(EspaiBase):
    """Modelo de salida para espacios"""
    id: uuid.UUID



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


# Create/Update models
class EspaiCreate(EspaiBase):
    """Modelo para crear espacios"""
    pass


class EspaiUpdate(SQLModel):
    """Modelo para actualizar espacios"""
    espai_type: Optional[EspaiType] = Field(default=None, description="Tipo de espacio")
    capacitat_min: Optional[int] = Field(default=None, description="Capacidad mínima de personas")
    capacitat_max: Optional[int] = Field(default=None, description="Capacidad máxima de personas")
    caracteristicas: Optional[List[str]] = Field(default=None, sa_column=Column(JSON))

    @validator('capacitat_max')
    def validate_capacitat_max(cls, v, values):
        """Valida que capacitat_max sea mayor o igual que capacitat_min"""
        if 'capacitat_min' in values and v is not None and values['capacitat_min'] is not None and v < values['capacitat_min']:
            raise ValueError('capacitat_max debe ser mayor o igual que capacitat_min')
        return v
    

class EspaiServiceCreate(EspaiBase):
    """Modelo para crear espacios"""
    pass


class EspaiServiceUpdate(SQLModel):
    """Modelo para actualizar espacios"""
    espai_type: Optional[EspaiType] = Field(default=None, description="Tipo de espacio")
    capacitat_min: Optional[int] = Field(default=None, description="Capacidad mínima de personas")
    capacitat_max: Optional[int] = Field(default=None, description="Capacidad máxima de personas")
    caracteristicas: Optional[List[str]] = Field(default=None, sa_column=Column(JSON))

    @validator('capacitat_max')
    def validate_capacitat_max(cls, v, values):
        """Valida que capacitat_max sea mayor o igual que capacitat_min"""
        if 'capacitat_min' in values and v is not None and values['capacitat_min'] is not None and v < values['capacitat_min']:
            raise ValueError('capacitat_max debe ser mayor o igual que capacitat_min')
        return v