import { z } from 'zod';

// ── Job Status ───────────────────────────────────────────────

export type JobStatus = 'enabled' | 'disabled' | 'running';
export type RunStatus = 'success' | 'failed' | 'skipped' | 'running';

// ── Job Definition Schema ────────────────────────────────────

export const JobDefinitionSchema = z.object({
  id: z.string().min(1),
  productId: z.string().min(1),
  name: z.string().min(1),
  description: z.string().optional(),
  cronExpression: z.string().min(1),
  status: z.enum(['enabled', 'disabled', 'running']).default('enabled'),
  lastRunAt: z.string().optional(),
  lastRunStatus: z.enum(['success', 'failed', 'skipped', 'running']).optional(),
  nextRunAt: z.string().optional(),
  createdAt: z.string(),
  updatedAt: z.string(),
  timeoutMs: z.number().default(300_000),
  retryOnFailure: z.boolean().default(false),
  maxRetries: z.number().default(0),
  metadata: z.record(z.unknown()).optional(),
});

export type JobDefinition = z.infer<typeof JobDefinitionSchema>;

export interface JobDefinitionDoc extends JobDefinition {
  _ts?: number;
  _etag?: string;
}

// ── Job Run Schema ───────────────────────────────────────────

export const JobRunSchema = z.object({
  id: z.string().min(1),
  jobName: z.string().min(1),
  productId: z.string().min(1),
  status: z.enum(['success', 'failed', 'skipped', 'running']),
  startedAt: z.string(),
  completedAt: z.string().optional(),
  durationMs: z.number().optional(),
  error: z.string().optional(),
  metrics: z.record(z.unknown()).optional(),
  triggeredBy: z.enum(['scheduler', 'manual']).default('scheduler'),
});

export type JobRun = z.infer<typeof JobRunSchema>;

export interface JobRunDoc extends JobRun {
  pk: string;
  _ts?: number;
  _etag?: string;
}

// ── Admin Schemas ────────────────────────────────────────────

export const TriggerJobSchema = z.object({
  jobName: z.string().min(1),
});

export const UpdateJobSchema = z.object({
  status: z.enum(['enabled', 'disabled']).optional(),
  cronExpression: z.string().min(1).optional(),
  timeoutMs: z.number().min(1000).max(600_000).optional(),
  description: z.string().optional(),
});

// ── Job Handler Type ─────────────────────────────────────────

export type JobHandler = (context: JobContext) => Promise<JobResult>;

export interface JobContext {
  jobName: string;
  runId: string;
  productId: string;
  log: {
    info: (...args: unknown[]) => void;
    warn: (...args: unknown[]) => void;
    error: (...args: unknown[]) => void;
  };
}

export interface JobResult {
  success: boolean;
  message?: string;
  metrics?: Record<string, unknown>;
}
