from __future__ import annotations

from typing import Optional

from pydantic import BaseModel, Field, model_validator


class PlannerConfigOverride(BaseModel):
    recency_weeks: Optional[int] = Field(default=None, ge=0)
    calorie_tolerance_pct: Optional[int] = Field(default=None, ge=0, le=100)
    max_total_minutes: Optional[int] = Field(default=None, ge=0)
    max_meal_cost: Optional[float] = Field(default=None, ge=0)
    w_savings: Optional[float] = Field(default=None, ge=0, le=1)
    w_coverage: Optional[float] = Field(default=None, ge=0, le=1)
    w_pantry: Optional[float] = Field(default=None, ge=0, le=1)
    w_time: Optional[float] = Field(default=None, ge=0, le=1)
    w_recency: Optional[float] = Field(default=None, ge=0, le=1)
    time_ideal_minutes: Optional[int] = Field(default=None, ge=0)
    time_full_minutes: Optional[int] = Field(default=None, ge=0)
    recency_full_weeks: Optional[int] = Field(default=None, ge=0)
    top_k: Optional[int] = Field(default=None, ge=1)
    set_size: Optional[int] = Field(default=None, ge=1)
    p_protein: Optional[float] = Field(default=None, ge=0)
    p_cuisine: Optional[float] = Field(default=None, ge=0)

    @model_validator(mode="after")
    def _check_weights_sum(self):
        weights = [self.w_savings, self.w_coverage, self.w_pantry, self.w_time, self.w_recency]
        if all(w is not None for w in weights):
            total = sum(weights)
            if not 0.999 <= total <= 1.001:
                raise ValueError(f"weights must sum to 1.0, got {total:.4f}")
        return self


class PlannerConfigResponse(BaseModel):
    recency_weeks: int
    calorie_tolerance_pct: int
    max_total_minutes: int
    max_meal_cost: float
    w_savings: float
    w_coverage: float
    w_pantry: float
    w_time: float
    w_recency: float
    time_ideal_minutes: int
    time_full_minutes: int
    recency_full_weeks: int
    top_k: int
    set_size: int
    p_protein: float
    p_cuisine: float
    source: str = "default"


class PlannerConfigUpdateRequest(BaseModel):
    planner_config: PlannerConfigOverride
