import uuid

from sqlalchemy import Boolean, Column, Date, Float, Integer, String, Text, ForeignKey
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.sql import func
from sqlalchemy.sql.expression import text
from sqlalchemy.sql.sqltypes import TIMESTAMP

from shared.database import BaseModel


class FoodItem(BaseModel):
    """Модель для хранения информации о продуктах питания"""
    __tablename__ = "food_items"

    uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, unique=True, index=True)
    
    # Основная информация о продукте
    fatsecret_id = Column(String(50), unique=True, index=True, nullable=True)  # ID продукта в FatSecret
    name = Column(String(255), nullable=False)
    brand = Column(String(255), nullable=True)
    description = Column(Text, nullable=True)
    food_type = Column(String(50), nullable=True)  # generic, branded, etc.
    serving_size = Column(String(100), nullable=True)  # e.g. "1 cup" or "100g"
    serving_weight_grams = Column(Float, nullable=True)
    
    # Пищевая ценность на порцию
    calories = Column(Float, nullable=True)  # kcal
    protein_grams = Column(Float, nullable=True)
    fat_grams = Column(Float, nullable=True)
    carbs_grams = Column(Float, nullable=True)
    fiber_grams = Column(Float, nullable=True)
    sugar_grams = Column(Float, nullable=True)
    sodium_mg = Column(Float, nullable=True)
    cholesterol_mg = Column(Float, nullable=True)
    
    # Дополнительная информация
    ingredients = Column(Text, nullable=True)
    is_verified = Column(Boolean, default=False)  # Проверенные данные или пользовательские
    created_at = Column(TIMESTAMP(timezone=True), nullable=False, server_default=func.now())
    updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
    
    def __repr__(self):
        return f"<FoodItem {self.name}>"


class UserNutritionEntry(BaseModel):
    """Модель для хранения записей пользователя о потреблении пищи"""
    __tablename__ = "user_nutrition_entries"
    
    uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, unique=True, index=True)
    user_id = Column(Integer, nullable=False, index=True)  # Связь с таблицей пользователей
    
    # Информация о приеме пищи
    entry_date = Column(Date, nullable=False, index=True)
    meal_type = Column(String(50), nullable=False)  # breakfast, lunch, dinner, snack
    
    food_item_id = Column(Integer, ForeignKey("food_items.id"), nullable=True)
    custom_food_name = Column(String(255), nullable=True)  # Если продукт не из базы
    
    # Количество
    quantity = Column(Float, nullable=False, default=1.0)
    unit = Column(String(50), nullable=True)  # g, ml, oz, piece, etc.
    
    # Рассчитанная пищевая ценность для данного количества
    calories = Column(Float, nullable=True)
    protein_grams = Column(Float, nullable=True)
    fat_grams = Column(Float, nullable=True)
    carbs_grams = Column(Float, nullable=True)
    
    # Метаданные
    notes = Column(Text, nullable=True)
    created_at = Column(TIMESTAMP(timezone=True), nullable=False, server_default=func.now())
    updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
    
    def __repr__(self):
        return f"<UserNutritionEntry user_id={self.user_id} date={self.entry_date} meal={self.meal_type}>"


class WaterIntake(BaseModel):
    """Модель для отслеживания потребления воды"""
    __tablename__ = "water_intake"
    
    uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, unique=True, index=True)
    user_id = Column(Integer, nullable=False, index=True)  # Связь с таблицей пользователей
    
    entry_date = Column(Date, nullable=False, index=True)
    amount_ml = Column(Integer, nullable=False)  # Количество в миллилитрах
    entry_time = Column(TIMESTAMP(timezone=True), nullable=False, server_default=func.now())
    
    notes = Column(Text, nullable=True)
    
    def __repr__(self):
        return f"<WaterIntake user_id={self.user_id} date={self.entry_date} amount={self.amount_ml}ml>"


class UserActivityEntry(BaseModel):
    """Модель для отслеживания физической активности"""
    __tablename__ = "user_activity_entries"
    
    uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, unique=True, index=True)
    user_id = Column(Integer, nullable=False, index=True)  # Связь с таблицей пользователей
    
    entry_date = Column(Date, nullable=False, index=True)
    activity_type = Column(String(100), nullable=False)  # walking, running, yoga, etc.
    
    duration_minutes = Column(Integer, nullable=False)
    calories_burned = Column(Float, nullable=True)  # Расчетное количество сожженных калорий
    
    # Дополнительные параметры активности
    distance_km = Column(Float, nullable=True)  # Для активностей с расстоянием
    steps = Column(Integer, nullable=True)  # Для ходьбы
    intensity = Column(String(20), nullable=True)  # low, medium, high
    
    notes = Column(Text, nullable=True)
    created_at = Column(TIMESTAMP(timezone=True), nullable=False, server_default=func.now())
    
    def __repr__(self):
        return f"<UserActivityEntry user_id={self.user_id} date={self.entry_date} activity={self.activity_type}>"


class NutritionGoal(BaseModel):
    """Модель для хранения целей пользователя по питанию и активности"""
    __tablename__ = "nutrition_goals"
    
    user_id = Column(Integer, nullable=False, index=True, unique=True)  # Связь с таблицей пользователей
    
    # Цели по калориям и макронутриентам
    daily_calorie_goal = Column(Integer, nullable=True)
    protein_goal_grams = Column(Integer, nullable=True)
    fat_goal_grams = Column(Integer, nullable=True)
    carbs_goal_grams = Column(Integer, nullable=True)
    
    # Цели по воде и активности
    water_goal_ml = Column(Integer, nullable=True, default=2000)  # Стандартно 2 литра
    activity_goal_minutes = Column(Integer, nullable=True, default=30)  # Минимум 30 минут активности
    
    # Цель по весу и предпочтения
    weight_goal_kg = Column(Float, nullable=True)
    goal_type = Column(String(50), nullable=True)  # lose_weight, maintain, gain_weight, health
    
    created_at = Column(TIMESTAMP(timezone=True), nullable=False, server_default=func.now())
    updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
    
    def __repr__(self):
        return f"<NutritionGoal user_id={self.user_id} calories={self.daily_calorie_goal}>"