import { NotFoundError } from '../../lib/errors.js';
import { getCollection } from '../../lib/datastore.js';
import type { AgentDefinitionDoc, AgentVersionDoc, ListAgentsQuery } from './types.js';

function agentCollection() {
  return getCollection<AgentDefinitionDoc>('agent_registry', '/productId');
}

function versionCollection() {
  return getCollection<AgentVersionDoc>('agent_versions', '/agentId');
}

export async function createAgent(doc: AgentDefinitionDoc): Promise<AgentDefinitionDoc> {
  return agentCollection().create(doc);
}

export async function getAgent(id: string, productId: string): Promise<AgentDefinitionDoc> {
  const agent = await agentCollection().findById(id, productId);
  if (!agent) throw new NotFoundError(`Agent '${id}' not found`);
  return agent;
}

export async function listAgents(
  productId: string,
  query: ListAgentsQuery
): Promise<AgentDefinitionDoc[]> {
  return agentCollection().findMany({
    filter: {
      productId,
      ...(query.status ? { status: query.status } : {}),
      ...(query.visibility ? { visibility: query.visibility } : {}),
    },
    sort: { createdAt: -1 },
    limit: query.limit,
  });
}

export async function updateAgent(
  id: string,
  productId: string,
  updates: Partial<AgentDefinitionDoc>
): Promise<AgentDefinitionDoc> {
  const updated = await agentCollection().update(id, productId, {
    ...updates,
    updatedAt: new Date().toISOString(),
  });
  if (!updated) throw new NotFoundError(`Agent '${id}' not found`);
  return updated;
}

export async function createAgentVersion(doc: AgentVersionDoc): Promise<AgentVersionDoc> {
  return versionCollection().create(doc);
}

export async function listAgentVersions(agentId: string): Promise<AgentVersionDoc[]> {
  return versionCollection().findMany({
    filter: { agentId },
    sort: { version: -1 },
    limit: 100,
  });
}

export async function getAgentVersion(id: string, agentId: string): Promise<AgentVersionDoc> {
  const version = await versionCollection().findById(id, agentId);
  if (!version) throw new NotFoundError(`Agent version '${id}' not found`);
  return version;
}

export async function getAgentByKey(
  productId: string,
  key: string
): Promise<AgentDefinitionDoc | null> {
  const results = await agentCollection().findMany({
    filter: { productId, key },
    limit: 1,
  });
  return results[0] ?? null;
}

export async function updateAgentVersion(
  id: string,
  agentId: string,
  updates: Partial<AgentVersionDoc>
): Promise<AgentVersionDoc> {
  const updated = await versionCollection().update(id, agentId, updates);
  if (!updated) throw new NotFoundError(`Agent version '${id}' not found`);
  return updated;
}

export async function getPublishedVersion(agentId: string): Promise<AgentVersionDoc | null> {
  const results = await versionCollection().findMany({
    filter: { agentId, status: 'published' },
    sort: { version: -1 },
    limit: 1,
  });
  return results[0] ?? null;
}

export async function deleteAgent(id: string, productId: string): Promise<void> {
  await agentCollection().delete(id, productId);
}
