import { Injectable } from '@nestjs/common';
import { Prisma } from '@/generated/prisma/client';
import { PrismaService } from '@/prisma/prisma.service';

@Injectable()
export class PermissionsRepository {
  constructor(private readonly prisma: PrismaService) {}

  private readonly publicSelect = {
    id: true,
    name: true,
    guardName: true,
    createdAt: true,
    updatedAt: true,
  } satisfies Prisma.PermissionsSelect;

  // Find many permissions (optionally filtered by name).
  findMany(filter: { search?: string }) {
    const where: Prisma.PermissionsWhereInput = { deletedAt: null };
    if (filter.search) {
      where.name = { contains: filter.search, mode: 'insensitive' };
    }

    return this.prisma.permissions.findMany({
      where,
      orderBy: { createdAt: 'desc' },
      select: this.publicSelect,
    });
  }

  // Find a single permission by ID.
  findById(id: number) {
    return this.prisma.permissions.findFirst({
      where: { id, deletedAt: null },
      select: this.publicSelect,
    });
  }

  // Find a permission by its name within a guard (used for duplicate checks).
  findByName(name: string, guardName: string) {
    return this.prisma.permissions.findFirst({
      where: { name, guardName, deletedAt: null },
      select: this.publicSelect,
    });
  }

  // Resolve a set of permission IDs (used to validate assignments).
  findManyByIds(ids: number[]) {
    return this.prisma.permissions.findMany({
      where: { id: { in: ids }, deletedAt: null },
      select: this.publicSelect,
    });
  }

  // Insert a new permission row.
  create(data: Prisma.PermissionsCreateInput) {
    return this.prisma.permissions.create({
      data,
      select: this.publicSelect,
    });
  }

  // Update an existing permission row by ID.
  update(id: number, data: Prisma.PermissionsUpdateInput) {
    return this.prisma.permissions.update({
      where: { id },
      data,
      select: this.publicSelect,
    });
  }

  // "Soft delete" a permission.
  softDelete(id: number) {
    return this.prisma.permissions.update({
      where: { id },
      data: { deletedAt: new Date() },
      select: { id: true },
    });
  }
}
