import { NotFoundError } from '../../lib/errors.js';
import { getCollection } from '../../lib/datastore.js';
import type { ListRunsQuery, RunDoc, RunStepDoc } from './types.js';

function runsCollection() {
  return getCollection<RunDoc>('agent_runs', '/productId');
}

function stepsCollection() {
  return getCollection<RunStepDoc>('agent_run_steps', '/pk');
}

export async function createRun(doc: RunDoc): Promise<RunDoc> {
  return runsCollection().create(doc);
}

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

export async function getRun(id: string, productId: string): Promise<RunDoc> {
  const run = await runsCollection().findById(id, productId);
  if (!run) throw new NotFoundError(`Run '${id}' not found`);
  return run;
}

export async function listRuns(productId: string, query: ListRunsQuery): Promise<RunDoc[]> {
  return runsCollection().findMany({
    filter: {
      productId,
      ...(query.kind ? { kind: query.kind } : {}),
      ...(query.status ? { status: query.status } : {}),
    },
    sort: { createdAt: -1 },
    limit: query.limit,
  });
}

export async function createRunStep(doc: RunStepDoc): Promise<RunStepDoc> {
  return stepsCollection().create(doc);
}

export async function updateRunStep(
  id: string,
  runId: string,
  productId: string,
  updates: Partial<RunStepDoc>
): Promise<RunStepDoc> {
  const updated = await stepsCollection().update(id, `${productId}:${runId}`, {
    ...updates,
    updatedAt: new Date().toISOString(),
  });
  if (!updated) throw new NotFoundError(`Run step '${id}' not found`);
  return updated;
}

export async function listChildRuns(productId: string, parentRunId: string): Promise<RunDoc[]> {
  return runsCollection().findMany({
    filter: { productId, parentRunId },
    sort: { createdAt: -1 },
    limit: 100,
  });
}

export async function listRunSteps(productId: string, runId: string): Promise<RunStepDoc[]> {
  return stepsCollection().findMany({
    filter: {
      pk: `${productId}:${runId}`,
      runId,
    },
    sort: { order: 1 },
    limit: 100,
  });
}
