import { PrismaClient } from '@prisma/client';

import { RoleRepository } from '../../../repositories/role.repository';
import { PermissionRepository } from '../../../repositories/role.repository';

describe('RBAC Integration Tests', () => {
  let prisma: PrismaClient;
  let roleRepo: RoleRepository;
  let permissionRepo: PermissionRepository;

  beforeAll(async () => {
    // Use test database
    prisma = new PrismaClient();

    // Initialize repositories
    roleRepo = new RoleRepository(prisma);
    permissionRepo = new PermissionRepository(prisma);
  });

  afterAll(async () => {
    await prisma.$disconnect();
  });

  beforeEach(async () => {
    // Clean up test data
    await prisma.$transaction([
      prisma.userPermission.deleteMany(),
      prisma.userRole.deleteMany(),
      prisma.rolePermission.deleteMany(),
      prisma.permission.deleteMany(),
      prisma.role.deleteMany(),
    ]);
  });

  describe('Permission Management', () => {
    it('should create and retrieve permissions', async () => {
      const permission = await permissionRepo.create({
        resource: 'users',
        action: 'read',
        scope: 'own',
      });

      expect(permission).toBeDefined();
      expect(permission.resource).toBe('users');
      expect(permission.action).toBe('read');
      expect(permission.scope).toBe('own');

      // Test finding by resource and action
      const found = await permissionRepo.findByResourceAction('users', 'read');
      expect(found).toBeDefined();
      expect(found?.id).toBe(permission.id);
    });
  });

  describe('Role Management', () => {
    it('should create roles successfully', async () => {
      const role = await roleRepo.create({
        name: 'test-admin',
        description: 'Test administrator role',
      });

      expect(role).toBeDefined();
      expect(role.name).toBe('test-admin');
      expect(role.description).toBe('Test administrator role');
    });

    it('should find roles by name', async () => {
      const roleName = 'test-moderator';
      await roleRepo.create({
        name: roleName,
        description: 'Test moderator role',
      });

      const found = await roleRepo.findByName(roleName);
      expect(found).toBeDefined();
      expect(found?.name).toBe(roleName);
    });
  });
});