"""Planner constants. Tune here without touching algorithm code."""
from __future__ import annotations

from dataclasses import dataclass


@dataclass(frozen=True)
class PlannerConfig:
    # Hard constraints
    recency_weeks: int = 4              # constraint #3: no repeat within N weeks
    calorie_tolerance_pct: int = 20     # constraint #4: ±X% of family.calorie_target
    max_total_minutes: int = 45         # constraint #5: prep + cook
    max_meal_cost: float = 30.00        # constraint #6: dollars per meal

    # Scoring weights (must sum to 1.0)
    w_savings: float = 0.30
    w_coverage: float = 0.25
    w_pantry: float = 0.10
    w_time: float = 0.15
    w_recency: float = 0.20

    # Time bonus boundaries
    time_ideal_minutes: int = 25        # full bonus at <= this
    time_full_minutes: int = 45         # zero bonus at this; matches max_total_minutes

    # Recency bonus boundary
    recency_full_weeks: int = 12        # full bonus when last cooked >= this many weeks ago

    # Set selection
    top_k: int = 20                     # how many feasible recipes to enumerate over
    set_size: int = 21                  # 21 meals/week (3 per day × 7 days)
    p_protein: float = 0.15             # diversity penalty per shared-protein pair
    p_cuisine: float = 0.10             # diversity penalty per shared-cuisine pair

    def validate(self) -> None:
        total = self.w_savings + self.w_coverage + self.w_pantry + self.w_time + self.w_recency
        if abs(total - 1.0) > 1e-6:
            raise ValueError(f"weights must sum to 1.0, got {total}")


DEFAULT = PlannerConfig()
DEFAULT.validate()
