from typing import Optional, List
from pydantic import BaseModel, Field, ConfigDict, model_validator


class BeerPairingFood(BaseModel):
    name: str = Field(..., description="Name of the dish to pair")
    description: Optional[str] = Field(None, description="Optional description or key ingredients")


class BeerCardItem(BaseModel):
    name: str = Field(..., description="Beer name as listed (brewery and style if possible)")
    description: Optional[str] = Field(None, description="Optional tasting notes or style details")
    price: Optional[str] = Field(None, description="Displayed beer price (string to preserve formatting)")


class BeerPairingRequest(BaseModel):
    model_config = ConfigDict(populate_by_name=True)

    language: str = Field(..., description="Language code or locale for the response")
    foods: List[BeerPairingFood] = Field(..., min_length=1, description="Dishes to evaluate for beer matches")
    beers: List[BeerCardItem] = Field(..., min_length=1, description="Restaurant beer list candidates")
    user_prompt: Optional[str] = Field(
        default=None,
        description="Optional free-form diner instructions to respect during the pairing"
    )
    city: Optional[str] = Field(
        default=None,
        description="Optional city identifier for analytics"
    )
    zavedenia_id: Optional[int] = Field(
        default=None,
        description="Optional Zavedenia restaurant identifier for analytics"
    )
    model: Optional[str] = Field(
        None,
        description="Optional OpenAI model override for beer pairing generation"
    )

    @model_validator(mode="before")
    @classmethod
    def apply_user_prompt_alias(cls, data):
        """
        Support camelCase `userPrompt` payloads without relying on alias metadata
        that can conflict with FastAPI's Annotated parameter handling.
        """
        if isinstance(data, dict) and "user_prompt" not in data and "userPrompt" in data:
            data = data.copy()
            data["user_prompt"] = data["userPrompt"]
        return data
