class HomeSummary { final TodaySummary today; final List expiringSoon; final List recommendations; const HomeSummary({ required this.today, required this.expiringSoon, required this.recommendations, }); factory HomeSummary.fromJson(Map json) => HomeSummary( today: TodaySummary.fromJson(json['today'] as Map), expiringSoon: (json['expiring_soon'] as List? ?? []) .map((e) => ExpiringSoon.fromJson(e as Map)) .toList(), recommendations: (json['recommendations'] as List? ?? []) .map((e) => HomeRecipe.fromJson(e as Map)) .toList(), ); } class TodaySummary { final String date; final int dailyGoal; final double loggedCalories; final List plan; const TodaySummary({ required this.date, required this.dailyGoal, required this.loggedCalories, required this.plan, }); factory TodaySummary.fromJson(Map json) => TodaySummary( date: json['date'] as String, dailyGoal: (json['daily_goal'] as num).toInt(), loggedCalories: (json['logged_calories'] as num).toDouble(), plan: (json['plan'] as List? ?? []) .map((e) => TodayMealPlan.fromJson(e as Map)) .toList(), ); double get remainingCalories => dailyGoal > 0 ? (dailyGoal - loggedCalories).clamp(0, dailyGoal.toDouble()) : 0; double get progress => dailyGoal > 0 ? (loggedCalories / dailyGoal).clamp(0.0, 1.0) : 0; } class TodayMealPlan { final String mealType; final String? recipeTitle; final String? recipeImageUrl; final double? calories; const TodayMealPlan({ required this.mealType, this.recipeTitle, this.recipeImageUrl, this.calories, }); factory TodayMealPlan.fromJson(Map json) => TodayMealPlan( mealType: json['meal_type'] as String, recipeTitle: json['recipe_title'] as String?, recipeImageUrl: json['recipe_image_url'] as String?, calories: (json['calories'] as num?)?.toDouble(), ); bool get hasRecipe => recipeTitle != null; String get mealLabel => switch (mealType) { 'breakfast' => 'Завтрак', 'lunch' => 'Обед', 'dinner' => 'Ужин', _ => mealType, }; String get mealEmoji => switch (mealType) { 'breakfast' => '🌅', 'lunch' => '☀️', 'dinner' => '🌙', _ => '🍽️', }; } class ExpiringSoon { final String name; final int expiresInDays; final String quantity; const ExpiringSoon({ required this.name, required this.expiresInDays, required this.quantity, }); factory ExpiringSoon.fromJson(Map json) => ExpiringSoon( name: json['name'] as String, expiresInDays: (json['expires_in_days'] as num).toInt(), quantity: json['quantity'] as String, ); String get expiryLabel => expiresInDays == 0 ? 'сегодня' : 'через $expiresInDays д.'; } class HomeRecipe { final String id; final String title; final String imageUrl; final double? calories; const HomeRecipe({ required this.id, required this.title, required this.imageUrl, this.calories, }); factory HomeRecipe.fromJson(Map json) => HomeRecipe( id: json['id'] as String, title: json['title'] as String, imageUrl: json['image_url'] as String? ?? '', calories: (json['calories'] as num?)?.toDouble(), ); }