import type { PrismaClient, McpInstance, InstanceStatus, Prisma } from '@prisma/client';
import type { IMcpInstanceRepository } from './interfaces.js';

export class McpInstanceRepository implements IMcpInstanceRepository {
  constructor(private prisma: PrismaClient) {}

  async findAll(serverId?: string): Promise<McpInstance[]> {
    const where: Prisma.McpInstanceWhereInput = {};
    if (serverId) {
      where.serverId = serverId;
    }
    return this.prisma.mcpInstance.findMany({
      where,
      include: { server: { select: { name: true } } },
      orderBy: { createdAt: 'desc' },
    });
  }

  async findById(id: string): Promise<McpInstance | null> {
    return this.prisma.mcpInstance.findUnique({
      where: { id },
      include: { server: { select: { name: true } } },
    });
  }

  async findByContainerId(containerId: string): Promise<McpInstance | null> {
    return this.prisma.mcpInstance.findFirst({ where: { containerId } });
  }

  async create(data: {
    serverId: string;
    containerId?: string;
    status?: InstanceStatus;
    port?: number;
    metadata?: Record<string, unknown>;
  }): Promise<McpInstance> {
    return this.prisma.mcpInstance.create({
      data: {
        serverId: data.serverId,
        containerId: data.containerId ?? null,
        status: data.status ?? 'STOPPED',
        port: data.port ?? null,
        metadata: (data.metadata ?? {}) as Prisma.InputJsonValue,
      },
    });
  }

  async updateStatus(
    id: string,
    status: InstanceStatus,
    fields?: { containerId?: string; port?: number; metadata?: Record<string, unknown>; healthStatus?: string; lastHealthCheck?: Date; events?: unknown[] },
  ): Promise<McpInstance> {
    const updateData: Prisma.McpInstanceUpdateInput = {
      status,
      version: { increment: 1 },
    };
    if (fields?.containerId !== undefined) {
      updateData.containerId = fields.containerId;
    }
    if (fields?.port !== undefined) {
      updateData.port = fields.port;
    }
    if (fields?.metadata !== undefined) {
      updateData.metadata = fields.metadata as Prisma.InputJsonValue;
    }
    if (fields?.healthStatus !== undefined) {
      updateData.healthStatus = fields.healthStatus;
    }
    if (fields?.lastHealthCheck !== undefined) {
      updateData.lastHealthCheck = fields.lastHealthCheck;
    }
    if (fields?.events !== undefined) {
      updateData.events = fields.events as unknown as Prisma.InputJsonValue;
    }
    return this.prisma.mcpInstance.update({
      where: { id },
      data: updateData,
    });
  }

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