import { type PrismaClient, type Secret, type Prisma } from '@prisma/client';
import type { ISecretRepository } from './interfaces.js';

export interface SecretRepoCreateInput {
  name: string;
  backendId: string;
  data?: Record<string, string>;
  externalRef?: string;
  keyNames?: string[];
}

export interface SecretRepoUpdateInput {
  data?: Record<string, string>;
  externalRef?: string;
  backendId?: string;
  keyNames?: string[];
}

export class SecretRepository implements ISecretRepository {
  constructor(private readonly prisma: PrismaClient) {}

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

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

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

  async findByBackend(backendId: string): Promise<Secret[]> {
    return this.prisma.secret.findMany({ where: { backendId }, orderBy: { name: 'asc' } });
  }

  async create(data: SecretRepoCreateInput): Promise<Secret> {
    return this.prisma.secret.create({
      data: {
        name: data.name,
        backendId: data.backendId,
        data: (data.data ?? {}) as Prisma.InputJsonValue,
        externalRef: data.externalRef ?? '',
        keyNames: (data.keyNames ?? []) as Prisma.InputJsonValue,
      },
    });
  }

  async update(id: string, data: SecretRepoUpdateInput): Promise<Secret> {
    const updateData: Prisma.SecretUpdateInput = {};
    if (data.data !== undefined) updateData.data = data.data as Prisma.InputJsonValue;
    if (data.externalRef !== undefined) updateData.externalRef = data.externalRef;
    if (data.backendId !== undefined) {
      updateData.backend = { connect: { id: data.backendId } };
    }
    if (data.keyNames !== undefined) updateData.keyNames = data.keyNames as Prisma.InputJsonValue;
    return this.prisma.secret.update({ where: { id }, data: updateData });
  }

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