import { type PrismaClient, type McpServer, Prisma } from '@prisma/client';
import type { IMcpServerRepository } from './interfaces.js';
import type { CreateMcpServerInput, UpdateMcpServerInput } from '../validation/mcp-server.schema.js';

export class McpServerRepository implements IMcpServerRepository {
  constructor(private readonly prisma: PrismaClient) {}

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

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

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

  async create(data: CreateMcpServerInput): Promise<McpServer> {
    return this.prisma.mcpServer.create({
      data: {
        name: data.name,
        description: data.description,
        packageName: data.packageName ?? null,
        runtime: data.runtime ?? null,
        dockerImage: data.dockerImage ?? null,
        transport: data.transport,
        repositoryUrl: data.repositoryUrl ?? null,
        externalUrl: data.externalUrl ?? null,
        command: data.command ?? Prisma.DbNull,
        containerPort: data.containerPort ?? null,
        replicas: data.replicas,
        env: data.env,
        healthCheck: (data.healthCheck ?? Prisma.JsonNull) as Prisma.InputJsonValue,
      },
    });
  }

  async update(id: string, data: UpdateMcpServerInput): Promise<McpServer> {
    const updateData: Record<string, unknown> = {};
    if (data.description !== undefined) updateData['description'] = data.description;
    if (data.packageName !== undefined) updateData['packageName'] = data.packageName;
    if (data.runtime !== undefined) updateData['runtime'] = data.runtime;
    if (data.dockerImage !== undefined) updateData['dockerImage'] = data.dockerImage;
    if (data.transport !== undefined) updateData['transport'] = data.transport;
    if (data.repositoryUrl !== undefined) updateData['repositoryUrl'] = data.repositoryUrl;
    if (data.externalUrl !== undefined) updateData['externalUrl'] = data.externalUrl;
    if (data.command !== undefined) updateData['command'] = data.command;
    if (data.containerPort !== undefined) updateData['containerPort'] = data.containerPort;
    if (data.replicas !== undefined) updateData['replicas'] = data.replicas;
    if (data.env !== undefined) updateData['env'] = data.env;
    if (data.healthCheck !== undefined) updateData['healthCheck'] = (data.healthCheck ?? Prisma.JsonNull) as Prisma.InputJsonValue;

    return this.prisma.mcpServer.update({ where: { id }, data: updateData });
  }

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