from datetime import date
from enum import Enum
from typing import List, Optional
from uuid import UUID

from pydantic import BaseModel, Field, root_validator, field_serializer


class MealType(str, Enum):
    BREAKFAST = "breakfast"
    LUNCH = "lunch"
    DINNER = "dinner"
    SNACK = "snack"


class ActivityIntensity(str, Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"


class GoalType(str, Enum):
    LOSE_WEIGHT = "lose_weight"
    MAINTAIN = "maintain"
    GAIN_WEIGHT = "gain_weight"
    HEALTH = "health"


# Схемы для FoodItem
class FoodItemBase(BaseModel):
    name: str
    brand: Optional[str] = None
    description: Optional[str] = None
    food_type: Optional[str] = None
    serving_size: Optional[str] = None
    serving_weight_grams: Optional[float] = None
    calories: Optional[float] = None
    protein_grams: Optional[float] = None
    fat_grams: Optional[float] = None
    carbs_grams: Optional[float] = None
    fiber_grams: Optional[float] = None
    sugar_grams: Optional[float] = None
    sodium_mg: Optional[float] = None
    cholesterol_mg: Optional[float] = None
    ingredients: Optional[str] = None


class FoodItemCreate(FoodItemBase):
    fatsecret_id: Optional[str] = None
    is_verified: bool = False


class FoodItemResponse(FoodItemBase):
    id: int
    uuid: str
    fatsecret_id: Optional[str] = None
    is_verified: bool
    created_at: str
    updated_at: Optional[str] = None

    class Config:
        from_attributes = True


# Схемы для UserNutritionEntry
class UserNutritionEntryBase(BaseModel):
    entry_date: date
    meal_type: MealType
    quantity: float = Field(gt=0)
    unit: Optional[str] = None
    notes: Optional[str] = None


class UserNutritionEntryCreate(UserNutritionEntryBase):
    food_item_id: Optional[int] = None
    custom_food_name: Optional[str] = None
    calories: Optional[float] = None
    protein_grams: Optional[float] = None
    fat_grams: Optional[float] = None
    carbs_grams: Optional[float] = None

    @root_validator(skip_on_failure=True)
    def check_food_info(cls, values):
        food_item_id = values.get("food_item_id")
        custom_food_name = values.get("custom_food_name")
        
        if food_item_id is None and not custom_food_name:
            raise ValueError("Either food_item_id or custom_food_name must be provided")
        return values


class UserNutritionEntryResponse(UserNutritionEntryBase):
    id: int
    uuid: str
    user_id: int
    food_item_id: Optional[int] = None
    custom_food_name: Optional[str] = None
    calories: Optional[float] = None
    protein_grams: Optional[float] = None
    fat_grams: Optional[float] = None
    carbs_grams: Optional[float] = None
    created_at: str
    updated_at: Optional[str] = None

    class Config:
        from_attributes = True


# Схемы для WaterIntake
class WaterIntakeBase(BaseModel):
    entry_date: date
    amount_ml: int = Field(gt=0)
    notes: Optional[str] = None


class WaterIntakeCreate(WaterIntakeBase):
    pass


class WaterIntakeResponse(WaterIntakeBase):
    id: int
    uuid: str
    user_id: int
    entry_time: str

    class Config:
        from_attributes = True


# Схемы для UserActivityEntry
class UserActivityEntryBase(BaseModel):
    entry_date: date
    activity_type: str
    duration_minutes: int = Field(gt=0)
    distance_km: Optional[float] = None
    steps: Optional[int] = None
    intensity: Optional[ActivityIntensity] = None
    notes: Optional[str] = None


class UserActivityEntryCreate(UserActivityEntryBase):
    calories_burned: Optional[float] = None


class UserActivityEntryResponse(UserActivityEntryBase):
    id: int
    uuid: str
    user_id: int
    calories_burned: Optional[float] = None
    created_at: str

    class Config:
        from_attributes = True


# Схемы для NutritionGoal
class NutritionGoalBase(BaseModel):
    daily_calorie_goal: Optional[int] = None
    protein_goal_grams: Optional[int] = None
    fat_goal_grams: Optional[int] = None
    carbs_goal_grams: Optional[int] = None
    water_goal_ml: Optional[int] = None
    activity_goal_minutes: Optional[int] = None
    weight_goal_kg: Optional[float] = None
    goal_type: Optional[GoalType] = None


class NutritionGoalCreate(NutritionGoalBase):
    pass


class NutritionGoalResponse(NutritionGoalBase):
    id: int
    user_id: int
    created_at: str
    updated_at: Optional[str] = None

    class Config:
        from_attributes = True


# Схемы для запросов к FatSecret API
class FoodSearchQuery(BaseModel):
    query: str
    page_number: int = 0
    max_results: int = 10


class FoodDetailsQuery(BaseModel):
    food_id: str


# Схемы для сводных данных
class DailyNutritionSummary(BaseModel):
    date: date
    total_calories: float = 0
    total_protein_grams: float = 0
    total_fat_grams: float = 0
    total_carbs_grams: float = 0
    total_water_ml: int = 0
    total_activity_minutes: int = 0
    estimated_calories_burned: float = 0
    meals: List[UserNutritionEntryResponse] = []
    water_entries: List[WaterIntakeResponse] = []
    activity_entries: List[UserActivityEntryResponse] = []