import 'dart:convert';

/// Model representing a user in the travel mate application.
///
/// This class encapsulates user information including personal details
/// and provides methods for serialization/deserialization with Firebase
/// and JSON operations.
class User {
  /// Unique identifier for the user (usually Firebase UID).
  final String? id;

  /// User's last name.
  final String nom;

  /// User's first name.
  final String prenom;

  /// User's email address.
  final String email;

  /// User's profile picture URL (optional).
  final String? profilePictureUrl;

  /// User's phone number (optional).
  final String? phoneNumber;

  /// Platform used for authentication (e.g., 'google', 'apple', 'email').
  final String platform;

  /// Creates a new [User] instance.
  ///
  /// [nom], [prenom], [email] and [platform] are required fields.
  /// [profilePictureUrl] and [phoneNumber] are optional.
  /// [id] is optional and typically assigned by Firebase.
  User({
    this.id,
    required this.nom,
    required this.prenom,
    required this.email,
    this.profilePictureUrl,
    this.phoneNumber,
    required this.platform,
  });

  /// Creates a [User] instance from a Map (useful for Firebase operations).
  ///
  /// Handles null values gracefully by providing empty string defaults.
  factory User.fromMap(Map<String, dynamic> map) {
    return User(
      id: map['id'],
      nom: map['nom'] ?? '',
      prenom: map['prenom'] ?? '',
      email: map['email'] ?? '',
      profilePictureUrl: map['profilePictureUrl'],
      phoneNumber: map['phoneNumber'],
      platform: map['platform'] ?? '',
    );
  }

  /// Creates a [User] instance from a JSON string.
  ///
  /// Parses the JSON and delegates to [fromMap] for object creation.
  factory User.fromJson(String jsonStr) {
    Map<String, dynamic> map = json.decode(jsonStr);
    return User.fromMap(map);
  }

  /// Converts the [User] instance to a Map (useful for Firebase operations).
  ///
  /// Returns a map with all user properties for database storage.
  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'nom': nom,
      'prenom': prenom,
      'email': email,
      'profilePictureUrl': profilePictureUrl,
      'phoneNumber': phoneNumber,
      'platform': platform,
    };
  }

  /// Converts the [User] instance to a JSON string.
  ///
  /// Useful for API communications and data serialization.
  String toJson() {
    return json.encode(toMap());
  }

  /// Gets the user's full name in "first last" format.
  String get fullName => '$prenom $nom';

  /// Creates a copy of this user with optionally modified properties.
  ///
  /// Allows updating specific fields while preserving others.
  /// Useful for state management and partial updates.
  User copyWith({
    String? id,
    String? nom,
    String? prenom,
    String? email,
    String? profilePictureUrl,
    String? phoneNumber,
    String? platform,
  }) {
    return User(
      id: id ?? this.id,
      nom: nom ?? this.nom,
      prenom: prenom ?? this.prenom,
      email: email ?? this.email,
      profilePictureUrl: profilePictureUrl ?? this.profilePictureUrl,
      phoneNumber: phoneNumber ?? this.phoneNumber,
      platform: platform ?? this.platform,
    );
  }

  /// Returns a string representation of the user.
  @override
  String toString() {
    return 'User(id: $id, nom: $nom, prenom: $prenom, email: $email)';
  }

  /// Compares users based on email address.
  ///
  /// Two users are considered equal if they have the same email.
  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is User && other.email == email;
  }

  /// Hash code based on email address.
  @override
  int get hashCode => email.hashCode;
}
