import { UserRepository } from '../user.repository';

// Create a simple mock for the repository that doesn't use complex Prisma mocking
describe('UserRepository', () => {
  let repository: UserRepository;

  beforeEach(() => {
    // Create a mock prisma client
    const mockPrisma = {
      user: {
        findUnique: jest.fn(),
      },
    };

    repository = new UserRepository(mockPrisma as any);
  });

  describe('inheritance', () => {
    it('should extend BaseRepository', () => {
      expect(repository).toBeInstanceOf(UserRepository);
    });

    it('should have access to base repository methods', () => {
      expect(typeof repository.findById).toBe('function');
    });
  });

  describe('findByEmail', () => {
    it('should be a function', () => {
      expect(typeof repository.findByEmail).toBe('function');
    });

    it('should call prisma.user.findUnique with correct parameters', async () => {
      const email = 'test@example.com';
      const mockUser = { id: '1', email };

      // Mock the prisma call
      const mockPrisma = (repository as any).prisma;
      mockPrisma.user.findUnique.mockResolvedValue(mockUser);

      const result = await repository.findByEmail(email);

      expect(result).toEqual(mockUser);
      expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({
        where: { email },
        include: {
          userRoles: {
            include: { role: true },
          },
          userPermissions: {
            include: { permission: true },
          },
        },
      });
    });
  });

  describe('findByUsername', () => {
    it('should be a function', () => {
      expect(typeof repository.findByUsername).toBe('function');
    });

    it('should call prisma.user.findUnique with username', async () => {
      const username = 'testuser';
      const mockUser = { id: '1', username };

      const mockPrisma = (repository as any).prisma;
      mockPrisma.user.findUnique.mockResolvedValue(mockUser);

      const result = await repository.findByUsername(username);

      expect(result).toEqual(mockUser);
      expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({
        where: { username },
      });
    });
  });

  describe('findWithPermissions', () => {
    it('should be a function', () => {
      expect(typeof repository.findWithPermissions).toBe('function');
    });

    it('should call prisma.user.findUnique with complex include', async () => {
      const userId = 'user-123';
      const mockUser = { id: userId };

      const mockPrisma = (repository as any).prisma;
      mockPrisma.user.findUnique.mockResolvedValue(mockUser);

      const result = await repository.findWithPermissions(userId);

      expect(result).toEqual(mockUser);
      expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({
        where: { id: userId },
        include: expect.objectContaining({
          userRoles: expect.objectContaining({
            where: expect.any(Object),
            include: expect.objectContaining({
              role: expect.objectContaining({
                include: expect.objectContaining({
                  permissions: expect.objectContaining({
                    include: expect.objectContaining({
                      permission: true,
                    }),
                  }),
                }),
              }),
            }),
          }),
          userPermissions: expect.objectContaining({
            where: expect.any(Object),
            include: expect.objectContaining({
              permission: true,
            }),
          }),
        }),
      });
    });
  });
});