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<String> ingredients;

  @HiveField(6)
  List<String> 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<String, dynamic> 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<String>.from(json['ingredients'] ?? []),
      allergens: List<String>.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<String, dynamic> 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<String>? ingredients,
    List<String>? 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<String> get dietaryTags {
    List<String> 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<String> 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;
    }
  }
}
