import 'package:flutter_test/flutter_test.dart';
import 'package:travel_mate/models/user.dart';

void main() {
  group('User Model Tests', () {
    const userId = '123';
    const email = 'test@example.com';
    const nom = 'Doe';
    const prenom = 'John';
    const platform = 'email';
    const phoneNumber = '1234567890';
    const profilePictureUrl = 'http://example.com/pic.jpg';

    final user = User(
      id: userId,
      nom: nom,
      prenom: prenom,
      email: email,
      platform: platform,
      phoneNumber: phoneNumber,
      profilePictureUrl: profilePictureUrl,
    );

    test('supports value equality', () {
      final user2 = User(
        id: userId,
        nom: nom,
        prenom: prenom,
        email: email,
        platform: platform,
        phoneNumber: phoneNumber,
        profilePictureUrl: profilePictureUrl,
      );
      expect(user, equals(user2));
    });

    test('props correct', () {
      expect(user.id, userId);
      expect(user.nom, nom);
      expect(user.prenom, prenom);
      expect(user.email, email);
      expect(user.platform, platform);
      expect(user.phoneNumber, phoneNumber);
      expect(user.profilePictureUrl, profilePictureUrl);
      expect(user.fullName, '$prenom $nom');
    });

    group('fromJson', () {
      test('returns correct user from valid json', () {
        final jsonStr =
            '''
          {
            "id": "$userId",
            "nom": "$nom",
            "prenom": "$prenom",
            "email": "$email",
            "platform": "$platform",
            "phoneNumber": "$phoneNumber",
            "profilePictureUrl": "$profilePictureUrl"
          }
        ''';
        expect(User.fromJson(jsonStr), equals(user));
      });
    });

    group('fromMap', () {
      test('returns correct user from valid map', () {
        final map = {
          'id': userId,
          'nom': nom,
          'prenom': prenom,
          'email': email,
          'platform': platform,
          'phoneNumber': phoneNumber,
          'profilePictureUrl': profilePictureUrl,
        };
        expect(User.fromMap(map), equals(user));
      });

      test('handles null/missing values gracefully', () {
        final map = {
          'id': userId,
          // Missing nom
          // Missing prenom
          // Missing email
          // Missing platform
          // Missing phoneNumber
          // Missing profilePictureUrl
        };
        final userFromMap = User.fromMap(map);
        expect(userFromMap.id, userId);
        expect(userFromMap.nom, '');
        expect(userFromMap.prenom, '');
        expect(userFromMap.email, '');
        expect(userFromMap.platform, '');
        expect(userFromMap.phoneNumber, null);
        expect(userFromMap.profilePictureUrl, null);
      });
    });

    group('toJson', () {
      test('returns correct json string', () {
        final expectedJson =
            '{"id":"$userId","nom":"$nom","prenom":"$prenom","email":"$email","profilePictureUrl":"$profilePictureUrl","phoneNumber":"$phoneNumber","platform":"$platform"}';
        expect(user.toJson(), expectedJson);
      });
    });

    group('toMap', () {
      test('returns correct map', () {
        final expectedMap = {
          'id': userId,
          'nom': nom,
          'prenom': prenom,
          'email': email,
          'profilePictureUrl': profilePictureUrl,
          'phoneNumber': phoneNumber,
          'platform': platform,
        };
        expect(user.toMap(), expectedMap);
      });
    });

    group('copyWith', () {
      test('returns object with updated values', () {
        const newNom = 'Smith';
        final updatedUser = user.copyWith(nom: newNom);
        expect(updatedUser.nom, newNom);
        expect(updatedUser.prenom, prenom);
        expect(updatedUser.email, email);
      });

      test('returns same object if no values provided', () {
        final updatedUser = user.copyWith();
        expect(updatedUser, equals(user));
      });
    });
  });
}
