import type { PrismaClient, RbacDefinition } from '@prisma/client';
import type { CreateRbacDefinitionInput, UpdateRbacDefinitionInput } from '../validation/rbac-definition.schema.js';

export interface IRbacDefinitionRepository {
  findAll(): Promise<RbacDefinition[]>;
  findById(id: string): Promise<RbacDefinition | null>;
  findByName(name: string): Promise<RbacDefinition | null>;
  create(data: CreateRbacDefinitionInput): Promise<RbacDefinition>;
  update(id: string, data: UpdateRbacDefinitionInput): Promise<RbacDefinition>;
  delete(id: string): Promise<void>;
}

export class RbacDefinitionRepository implements IRbacDefinitionRepository {
  constructor(private readonly prisma: PrismaClient) {}

  async findAll(): Promise<RbacDefinition[]> {
    return this.prisma.rbacDefinition.findMany({ orderBy: { name: 'asc' } });
  }

  async findById(id: string): Promise<RbacDefinition | null> {
    return this.prisma.rbacDefinition.findUnique({ where: { id } });
  }

  async findByName(name: string): Promise<RbacDefinition | null> {
    return this.prisma.rbacDefinition.findUnique({ where: { name } });
  }

  async create(data: CreateRbacDefinitionInput): Promise<RbacDefinition> {
    return this.prisma.rbacDefinition.create({
      data: {
        name: data.name,
        subjects: data.subjects,
        roleBindings: data.roleBindings,
      },
    });
  }

  async update(id: string, data: UpdateRbacDefinitionInput): Promise<RbacDefinition> {
    const updateData: Record<string, unknown> = {};
    if (data.subjects !== undefined) updateData['subjects'] = data.subjects;
    if (data.roleBindings !== undefined) updateData['roleBindings'] = data.roleBindings;
    return this.prisma.rbacDefinition.update({ where: { id }, data: updateData });
  }

  async delete(id: string): Promise<void> {
    await this.prisma.rbacDefinition.delete({ where: { id } });
  }
}
