import 'package:afterwork/core/errors/failures.dart';
import 'package:afterwork/domain/entities/user.dart';
import 'package:afterwork/domain/repositories/user_repository.dart';
import 'package:afterwork/domain/usecases/get_user.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';

// Mock classes
class MockUserRepository extends Mock implements UserRepository {}

void main() {
  group('GetUser', () {
    late GetUser usecase;
    late MockUserRepository mockRepository;

    setUp(() {
      mockRepository = MockUserRepository();
      usecase = GetUser(mockRepository);
    });

    const tUserId = 'user123';
    final tUser = User(
      userId: tUserId,
      email: 'test@example.com',
      userLastName: 'Doe',
      userFirstName: 'John',
      motDePasse: 'password123',
      profileImageUrl: 'https://test.com/profile.jpg',
    );

    test('should return Right(User) when repository returns user', () async {
      // Arrange
      when(() => mockRepository.getUser(any())).thenAnswer((_) async => Right(tUser));

      // Act
      final result = await usecase(tUserId);

      // Assert
      expect(result, isA<Right<Failure, User>>());
      result.fold(
        (failure) => fail('Should not return failure'),
        (user) => expect(user.userId, tUserId),
      );
      verify(() => mockRepository.getUser(tUserId)).called(1);
    });

    test('should return Left(ServerFailure) when repository throws exception', () async {
      // Arrange
      when(() => mockRepository.getUser(any())).thenThrow(Exception('Error'));

      // Act
      final result = await usecase(tUserId);

      // Assert
      expect(result, isA<Left<Failure, User>>());
      result.fold(
        (failure) => expect(failure, isA<ServerFailure>()),
        (user) => fail('Should not return user'),
      );
    });

    test('should call repository with correct userId', () async {
      // Arrange
      when(() => mockRepository.getUser(any())).thenAnswer((_) async => Right(tUser));

      // Act
      await usecase(tUserId);

      // Assert
      verify(() => mockRepository.getUser(tUserId)).called(1);
    });
  });
}

