import 'package:hive/hive.dart'; part 'menu_model.g.dart'; @HiveType(typeId: 2) class MenuModel extends HiveObject { @HiveField(0) String id; @HiveField(1) String name; @HiveField(2) String description; @HiveField(3) double price; @HiveField(4) String category; @HiveField(5) List ingredients; @HiveField(6) List allergens; @HiveField(7) String spiceLevel; @HiveField(8) bool isVegetarian; @HiveField(9) bool isVegan; @HiveField(10) bool isHalal; @HiveField(11) String? imageUrl; @HiveField(12) double rating; @HiveField(13) int reviewCount; @HiveField(14) bool isAvailable; @HiveField(15) DateTime createdAt; @HiveField(16) DateTime updatedAt; MenuModel({ required this.id, required this.name, required this.description, required this.price, required this.category, this.ingredients = const [], this.allergens = const [], this.spiceLevel = 'mild', this.isVegetarian = false, this.isVegan = false, this.isHalal = true, this.imageUrl, this.rating = 0.0, this.reviewCount = 0, this.isAvailable = true, required this.createdAt, required this.updatedAt, }); factory MenuModel.fromJson(Map json) { return MenuModel( id: json['id'] as String, name: json['name'] as String, description: json['description'] as String, price: (json['price'] as num).toDouble(), category: json['category'] as String, ingredients: List.from(json['ingredients'] ?? []), allergens: List.from(json['allergens'] ?? []), spiceLevel: json['spiceLevel'] as String? ?? 'mild', isVegetarian: json['isVegetarian'] as bool? ?? false, isVegan: json['isVegan'] as bool? ?? false, isHalal: json['isHalal'] as bool? ?? true, imageUrl: json['imageUrl'] as String?, rating: (json['rating'] as num?)?.toDouble() ?? 0.0, reviewCount: json['reviewCount'] as int? ?? 0, isAvailable: json['isAvailable'] as bool? ?? true, createdAt: DateTime.parse(json['createdAt'] as String), updatedAt: DateTime.parse(json['updatedAt'] as String), ); } Map toJson() { return { 'id': id, 'name': name, 'description': description, 'price': price, 'category': category, 'ingredients': ingredients, 'allergens': allergens, 'spiceLevel': spiceLevel, 'isVegetarian': isVegetarian, 'isVegan': isVegan, 'isHalal': isHalal, 'imageUrl': imageUrl, 'rating': rating, 'reviewCount': reviewCount, 'isAvailable': isAvailable, 'createdAt': createdAt.toIso8601String(), 'updatedAt': updatedAt.toIso8601String(), }; } MenuModel copyWith({ String? id, String? name, String? description, double? price, String? category, List? ingredients, List? allergens, String? spiceLevel, bool? isVegetarian, bool? isVegan, bool? isHalal, String? imageUrl, double? rating, int? reviewCount, bool? isAvailable, DateTime? createdAt, DateTime? updatedAt, }) { return MenuModel( id: id ?? this.id, name: name ?? this.name, description: description ?? this.description, price: price ?? this.price, category: category ?? this.category, ingredients: ingredients ?? this.ingredients, allergens: allergens ?? this.allergens, spiceLevel: spiceLevel ?? this.spiceLevel, isVegetarian: isVegetarian ?? this.isVegetarian, isVegan: isVegan ?? this.isVegan, isHalal: isHalal ?? this.isHalal, imageUrl: imageUrl ?? this.imageUrl, rating: rating ?? this.rating, reviewCount: reviewCount ?? this.reviewCount, isAvailable: isAvailable ?? this.isAvailable, createdAt: createdAt ?? this.createdAt, updatedAt: updatedAt ?? this.updatedAt, ); } String get formattedPrice { return 'Rp ${price.toStringAsFixed(0).replaceAllMapped( RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]}.', )}'; } List get dietaryTags { List tags = []; if (isVegetarian) tags.add('Vegetarian'); if (isVegan) tags.add('Vegan'); if (isHalal) tags.add('Halal'); return tags; } String get spiceLevelEmoji { switch (spiceLevel.toLowerCase()) { case 'mild': return '🌶️'; case 'medium': return '🌶️🌶️'; case 'hot': return '🌶️🌶️🌶️'; case 'very hot': return '🌶️🌶️🌶️🌶️'; default: return ''; } } bool hasAllergen(String allergen) { return allergens.any((a) => a.toLowerCase() == allergen.toLowerCase()); } bool isCompatibleWithPreferences(List userAllergies, String dietaryRestriction) { // Check allergies for (String allergy in userAllergies) { if (hasAllergen(allergy)) { return false; } } // Check dietary restrictions switch (dietaryRestriction.toLowerCase()) { case 'vegetarian': return isVegetarian; case 'vegan': return isVegan; case 'halal': return isHalal; default: return true; } } }