import { z } from 'zod';

export const RunKindSchema = z.enum(['job', 'agent']);
export const RunStatusSchema = z.enum(['queued', 'running', 'succeeded', 'failed', 'cancelled']);
export const RunStepStatusSchema = z.enum([
  'pending',
  'running',
  'succeeded',
  'failed',
  'skipped',
  'cancelled',
]);

export const RunSchema = z.object({
  id: z.string().min(1),
  productId: z.string().min(1),
  kind: RunKindSchema,
  name: z.string().min(1),
  source: z.string().min(1),
  status: RunStatusSchema,
  triggeredBy: z.string().optional(),
  parentRunId: z.string().optional(),
  queueName: z.string().optional(),
  queueJobId: z.string().optional(),
  input: z.record(z.unknown()).optional(),
  output: z.record(z.unknown()).optional(),
  error: z.string().optional(),
  metadata: z.record(z.unknown()).optional(),
  createdAt: z.string(),
  startedAt: z.string().optional(),
  completedAt: z.string().optional(),
  updatedAt: z.string(),
});

export type RunDoc = z.infer<typeof RunSchema> & {
  _ts?: number;
  _etag?: string;
};

export const RunStepSchema = z.object({
  id: z.string().min(1),
  runId: z.string().min(1),
  productId: z.string().min(1),
  stepName: z.string().min(1),
  order: z.number().int().min(0),
  status: RunStepStatusSchema,
  input: z.record(z.unknown()).optional(),
  output: z.record(z.unknown()).optional(),
  error: z.string().optional(),
  metadata: z.record(z.unknown()).optional(),
  createdAt: z.string(),
  startedAt: z.string().optional(),
  completedAt: z.string().optional(),
  updatedAt: z.string(),
});

export type RunStepDoc = z.infer<typeof RunStepSchema> & {
  pk: string;
  _ts?: number;
  _etag?: string;
};

export const ListRunsQuerySchema = z.object({
  kind: RunKindSchema.optional(),
  status: RunStatusSchema.optional(),
  limit: z.coerce.number().min(1).max(100).default(20),
});

export type ListRunsQuery = z.infer<typeof ListRunsQuerySchema>;

export const CreateRunSchema = z.object({
  id: z.string().min(1),
  kind: RunKindSchema,
  name: z.string().min(1),
  source: z.string().min(1),
  triggeredBy: z.string().optional(),
  parentRunId: z.string().optional(),
  queueName: z.string().optional(),
  queueJobId: z.string().optional(),
  input: z.record(z.unknown()).optional(),
  metadata: z.record(z.unknown()).optional(),
});

export type CreateRunInput = z.infer<typeof CreateRunSchema>;

export const UpdateRunSchema = z.object({
  status: RunStatusSchema,
  output: z.record(z.unknown()).optional(),
  error: z.string().optional(),
});

export type UpdateRunInput = z.infer<typeof UpdateRunSchema>;

export const CreateRunStepSchema = z.object({
  stepName: z.string().min(1),
  order: z.number().int().min(0),
  input: z.record(z.unknown()).optional(),
  metadata: z.record(z.unknown()).optional(),
});

export type CreateRunStepInput = z.infer<typeof CreateRunStepSchema>;

export const UpdateRunStepSchema = z.object({
  status: RunStepStatusSchema,
  output: z.record(z.unknown()).optional(),
  error: z.string().optional(),
});

export type UpdateRunStepInput = z.infer<typeof UpdateRunStepSchema>;
