import 'package:hive/hive.dart';

part 'user_model.g.dart';

@HiveType(typeId: 0)
class UserModel extends HiveObject {
  @HiveField(0)
  String id;

  @HiveField(1)
  String email;

  @HiveField(2)
  String? displayName;

  @HiveField(3)
  String? photoUrl;

  @HiveField(4)
  UserPreferences preferences;

  @HiveField(5)
  DateTime createdAt;

  @HiveField(6)
  DateTime updatedAt;

  @HiveField(7)
  String? phoneNumber;

  @HiveField(8)
  bool isSetupComplete;

  @HiveField(9)
  String? nickname;

  @HiveField(10)
  String? gender;

  @HiveField(11)
  String? address;

  @HiveField(12)
  DateTime? lastCheckinDate;

  @HiveField(13)
  Map<String, dynamic>? dailyPreferences;

  UserModel({
    required this.id,
    required this.email,
    this.displayName,
    this.photoUrl,
    this.phoneNumber,
    required this.preferences,
    required this.createdAt,
    required this.updatedAt,
    this.isSetupComplete = false,
    this.nickname,
    this.gender,
    this.address,
    this.lastCheckinDate,
    this.dailyPreferences,
  });

  factory UserModel.fromJson(Map<String, dynamic> json) {
    return UserModel(
      id: json['id'] as String,
      email: json['email'] as String,
      displayName: json['displayName'] as String?,
      phoneNumber: json['phoneNumber'] as String?,
      preferences: UserPreferences.fromJson(
        json['preferences'] as Map<String, dynamic>,
      ),
      createdAt: DateTime.parse(json['createdAt'] as String),
      updatedAt: DateTime.parse(json['updatedAt'] as String),
      isSetupComplete: json['isSetupComplete'] as bool? ?? false,
      nickname: json['nickname'] as String?,
      gender: json['gender'] as String?,
      address: json['address'] as String?,
      lastCheckinDate: json['lastCheckinDate'] != null
          ? DateTime.parse(json['lastCheckinDate'] as String)
          : null,
      dailyPreferences: json['dailyPreferences'] as Map<String, dynamic>?,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'email': email,
      'displayName': displayName,
      'photoUrl': photoUrl,
      'phoneNumber': phoneNumber,
      'preferences': preferences.toJson(),
      'createdAt': createdAt.toIso8601String(),
      'updatedAt': updatedAt.toIso8601String(),
      'isSetupComplete': isSetupComplete,
      'nickname': nickname,
      'gender': gender,
      'address': address,
      'lastCheckinDate': lastCheckinDate?.toIso8601String(),
      'dailyPreferences': dailyPreferences,
    };
  }

  UserModel copyWith({
    String? id,
    String? email,
    String? displayName,
    String? photoUrl,
    String? phoneNumber,
    UserPreferences? preferences,
    DateTime? createdAt,
    DateTime? updatedAt,
    bool? isSetupComplete,
    String? nickname,
    String? gender,
    String? address,
    DateTime? lastCheckinDate,
    Map<String, dynamic>? dailyPreferences,
  }) {
    return UserModel(
      id: id ?? this.id,
      email: email ?? this.email,
      displayName: displayName ?? this.displayName,
      photoUrl: photoUrl ?? this.photoUrl,
      phoneNumber: phoneNumber ?? this.phoneNumber,
      preferences: preferences ?? this.preferences,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
      isSetupComplete: isSetupComplete ?? this.isSetupComplete,
      nickname: nickname ?? this.nickname,
      gender: gender ?? this.gender,
      address: address ?? this.address,
      lastCheckinDate: lastCheckinDate ?? this.lastCheckinDate,
      dailyPreferences: dailyPreferences ?? this.dailyPreferences,
    );
  }
}

@HiveType(typeId: 1)
class UserPreferences extends HiveObject {
  @HiveField(0)
  List<String> favoriteCategories;

  @HiveField(1)
  List<String> allergies;

  @HiveField(2)
  String mood;

  @HiveField(3)
  String spiceLevel;

  @HiveField(4)
  String dietaryRestriction;

  @HiveField(5)
  int budgetRange;

  @HiveField(6)
  bool enableNotifications;

  @HiveField(7)
  String language;

  @HiveField(8)
  String? ageRange;

  UserPreferences({
    this.favoriteCategories = const [],
    this.allergies = const [],
    this.mood = 'neutral',
    this.spiceLevel = 'medium',
    this.dietaryRestriction = 'none',
    this.budgetRange = 50000,
    this.enableNotifications = true,
    this.language = 'id',
    this.ageRange,
  });

  factory UserPreferences.fromJson(Map<String, dynamic> json) {
    return UserPreferences(
      favoriteCategories: List<String>.from(json['favoriteCategories'] ?? []),
      allergies: List<String>.from(json['allergies'] ?? []),
      mood: json['mood'] as String? ?? 'neutral',
      spiceLevel: json['spiceLevel'] as String? ?? 'medium',
      dietaryRestriction: json['dietaryRestriction'] as String? ?? 'none',
      budgetRange: json['budgetRange'] as int? ?? 50000,
      enableNotifications: json['enableNotifications'] as bool? ?? true,
      language: json['language'] as String? ?? 'id',
      ageRange: json['ageRange'] as String?,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'favoriteCategories': favoriteCategories,
      'allergies': allergies,
      'mood': mood,
      'spiceLevel': spiceLevel,
      'dietaryRestriction': dietaryRestriction,
      'budgetRange': budgetRange,
      'enableNotifications': enableNotifications,
      'language': language,
      'ageRange': ageRange,
    };
  }

  UserPreferences copyWith({
    List<String>? favoriteCategories,
    List<String>? allergies,
    String? mood,
    String? spiceLevel,
    String? dietaryRestriction,
    int? budgetRange,
    bool? enableNotifications,
    String? language,
    String? ageRange,
  }) {
    return UserPreferences(
      favoriteCategories: favoriteCategories ?? this.favoriteCategories,
      allergies: allergies ?? this.allergies,
      mood: mood ?? this.mood,
      spiceLevel: spiceLevel ?? this.spiceLevel,
      dietaryRestriction: dietaryRestriction ?? this.dietaryRestriction,
      budgetRange: budgetRange ?? this.budgetRange,
      enableNotifications: enableNotifications ?? this.enableNotifications,
      language: language ?? this.language,
      ageRange: ageRange ?? this.ageRange,
    );
  }

  String get preferencesDescription {
    List<String> descriptions = [];

    if (favoriteCategories.isNotEmpty) {
      descriptions.add('Suka: ${favoriteCategories.join(', ')}');
    }

    if (allergies.isNotEmpty) {
      descriptions.add('Alergi: ${allergies.join(', ')}');
    }

    descriptions.add('Mood: $mood');
    descriptions.add('Level pedas: $spiceLevel');

    if (dietaryRestriction != 'none') {
      descriptions.add('Diet: $dietaryRestriction');
    }

    descriptions.add('Budget: Rp ${budgetRange.toString()}');

    return descriptions.join(', ');
  }
}
