"""Defines the Preferences used as input for trip generation."""

from typing import Optional, Literal
from pydantic import BaseModel, field_validator


class Preference(BaseModel) :
    """
    Type of preference.

    Attributes:
        type: what kind of landmark type.
        score: how important that type is.
    """
    type: Literal['sightseeing', 'nature', 'shopping', 'start', 'finish']
    score: int          # score could be from 1 to 5

    @field_validator("type")
    @classmethod
    def validate_type(cls, v):
        if v not in {'sightseeing', 'nature', 'shopping', 'start', 'finish'}:
            raise ValueError(f"Invalid type: {v}")
        return v


# Input for optimization
class Preferences(BaseModel) :
    """"
    Full collection of preferences needed to generate a personalized trip.
    """
    # Sightseeing / History & Culture (Musées, bâtiments historiques, opéras, églises)
    sightseeing : Preference

    # Nature (parcs, jardins, rivières, plages)
    nature: Preference

    # Shopping (diriger plutôt vers des zones / rues commerçantes)
    shopping : Preference

    max_time_minute: Optional[int] = 3*60
    detour_tolerance_minute: Optional[int] = 0


    def model_post_init(self, __context):
        """
        Method to validate proper initialization of individual Preferences.
        Raises ValueError if the Preference type does not match with the field name.
        """
        if self.sightseeing.type != 'sightseeing':
            raise ValueError(f'The sightseeing preference cannot be {self.sightseeing.type}.')
        if self.nature.type != 'nature':
            raise ValueError(f'The nature preference cannot be {self.nature.type}.')
        if self.shopping.type != 'shopping':
            raise ValueError(f'The shopping preference cannot be {self.shopping.type}.')