import type { RunDoc, RunStepDoc } from './types.js';
import * as repo from './repository.js';

interface StartRunInput {
  id: string;
  productId: string;
  kind: RunDoc['kind'];
  name: string;
  source: string;
  triggeredBy?: string;
  parentRunId?: string;
  queueName?: string;
  queueJobId?: string;
  input?: Record<string, unknown>;
  metadata?: Record<string, unknown>;
}

interface StartRunStepInput {
  runId: string;
  productId: string;
  stepName: string;
  order: number;
  input?: Record<string, unknown>;
  metadata?: Record<string, unknown>;
}

export async function startRun(input: StartRunInput): Promise<RunDoc> {
  const now = new Date().toISOString();
  return repo.createRun({
    id: input.id,
    productId: input.productId,
    kind: input.kind,
    name: input.name,
    source: input.source,
    status: 'running',
    triggeredBy: input.triggeredBy,
    parentRunId: input.parentRunId,
    queueName: input.queueName,
    queueJobId: input.queueJobId,
    input: input.input,
    metadata: input.metadata,
    createdAt: now,
    startedAt: now,
    updatedAt: now,
  });
}

export async function completeRun(
  id: string,
  productId: string,
  output?: Record<string, unknown>
): Promise<RunDoc> {
  return repo.updateRun(id, productId, {
    status: 'succeeded',
    output,
    completedAt: new Date().toISOString(),
  });
}

export async function failRun(
  id: string,
  productId: string,
  error: string,
  output?: Record<string, unknown>
): Promise<RunDoc> {
  return repo.updateRun(id, productId, {
    status: 'failed',
    error,
    output,
    completedAt: new Date().toISOString(),
  });
}

export async function startRunStep(input: StartRunStepInput): Promise<RunStepDoc> {
  const now = new Date().toISOString();
  return repo.createRunStep({
    id: `${input.runId}:${input.stepName}`,
    pk: `${input.productId}:${input.runId}`,
    runId: input.runId,
    productId: input.productId,
    stepName: input.stepName,
    order: input.order,
    status: 'running',
    input: input.input,
    metadata: input.metadata,
    createdAt: now,
    startedAt: now,
    updatedAt: now,
  });
}

export async function completeRunStep(
  runId: string,
  productId: string,
  stepName: string,
  output?: Record<string, unknown>
): Promise<RunStepDoc> {
  return repo.updateRunStep(`${runId}:${stepName}`, runId, productId, {
    status: 'succeeded',
    output,
    completedAt: new Date().toISOString(),
  });
}

export async function failRunStep(
  runId: string,
  productId: string,
  stepName: string,
  error: string,
  output?: Record<string, unknown>
): Promise<RunStepDoc> {
  return repo.updateRunStep(`${runId}:${stepName}`, runId, productId, {
    status: 'failed',
    error,
    output,
    completedAt: new Date().toISOString(),
  });
}
