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


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


class WineCardItem(BaseModel):
    name: str = Field(..., description="Wine name as listed (producer and style if possible)")
    description: Optional[str] = Field(None, description="Optional tasting notes or grape variety")
    price: Optional[str] = Field(None, description="Displayed wine price (string to preserve formatting)")


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

    language: str = Field(..., description="Language code or locale for the response")
    foods: List[WinePairingFood] = Field(..., min_length=1, description="Dishes to evaluate for wine matches")
    wines: List[WineCardItem] = Field(..., min_length=1, description="Restaurant wine 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 wine 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
