const GetUserByIdQueryHandler = require('../../../src/application/user/queries/GetUserByIdQueryHandler');
const GetUserByIdQuery = require('../../../src/application/user/queries/GetUserByIdQuery');

describe('GetUserByIdQueryHandler', () => {
  let handler;
  let mockPrisma;

  beforeEach(() => {
    // Mock Prisma
    mockPrisma = {
      user: {
        findUnique: jest.fn()
      }
    };

    handler = new GetUserByIdQueryHandler(mockPrisma);

    // Reset all mocks
    jest.clearAllMocks();
  });

  describe('handle - success cases', () => {
    it('should return user by ID successfully', async () => {
      // Arrange
      const query = new GetUserByIdQuery(1);
      
      mockPrisma.user.findUnique.mockResolvedValue({
        id: 1,
        name: 'John Doe',
        email: 'john@example.com',
        password: 'hashed_password',
        createdAt: new Date(),
        updatedAt: new Date()
      });

      // Act
      const result = await handler.handle(query);

      // Assert
      expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({
        where: { id: 1 }
      });
      expect(result).toEqual({
        id: 1,
        name: 'John Doe',
        email: 'john@example.com',
        createdAt: expect.any(Date),
        updatedAt: expect.any(Date)
      });
      expect(result.password).toBeUndefined(); // Password should not be returned
    });
  });

  describe('handle - validation errors', () => {
    it('should throw error if userId is invalid (NaN)', async () => {
      // Arrange
      const query = new GetUserByIdQuery('invalid');

      // Act & Assert
      await expect(handler.handle(query)).rejects.toThrow('Valid user ID is required');
    });

    it('should throw error if userId is null', async () => {
      // Arrange
      const query = new GetUserByIdQuery(null);

      // Act & Assert
      await expect(handler.handle(query)).rejects.toThrow('Valid user ID is required');
    });

    it('should throw error if userId is undefined', async () => {
      // Arrange
      const query = new GetUserByIdQuery(undefined);

      // Act & Assert
      await expect(handler.handle(query)).rejects.toThrow('Valid user ID is required');
    });
  });

  describe('handle - error cases', () => {
    it('should throw error if user not found', async () => {
      // Arrange
      const query = new GetUserByIdQuery(999);
      
      mockPrisma.user.findUnique.mockResolvedValue(null);

      // Act & Assert
      await expect(handler.handle(query)).rejects.toThrow('User not found');
    });
  });
});
