/**
 * Runner Jobs API Client
 * Handles runner-job-related API requests
 */

import { apiGet, type ApiResponse } from "./client";

/**
 * Runner job status enum (matches backend RunnerJobStatus)
 */
export enum RunnerJobStatus {
  PENDING = "PENDING",
  QUEUED = "QUEUED",
  RUNNING = "RUNNING",
  COMPLETED = "COMPLETED",
  FAILED = "FAILED",
  CANCELLED = "CANCELLED",
}

/**
 * Runner job response interface (matches Prisma RunnerJob model)
 */
export interface RunnerJob {
  id: string;
  workspaceId: string;
  agentTaskId: string | null;
  type: string;
  status: RunnerJobStatus;
  priority: number;
  progressPercent: number;
  version: number;
  result: Record<string, unknown> | null;
  error: string | null;
  createdAt: string;
  startedAt: string | null;
  completedAt: string | null;
}

/**
 * Filters for querying runner jobs
 */
export interface RunnerJobFilters {
  workspaceId?: string;
  status?: RunnerJobStatus | RunnerJobStatus[];
  type?: string;
  agentTaskId?: string;
  page?: number;
  limit?: number;
}

/**
 * Paginated runner jobs response
 */
export interface PaginatedRunnerJobs {
  data: RunnerJob[];
  meta?: {
    total?: number;
    page?: number;
    limit?: number;
  };
}

/**
 * Fetch runner jobs with optional filters
 */
export async function fetchRunnerJobs(filters?: RunnerJobFilters): Promise<RunnerJob[]> {
  const params = new URLSearchParams();

  if (filters?.status) {
    const statuses = Array.isArray(filters.status) ? filters.status : [filters.status];
    for (const s of statuses) {
      params.append("status", s);
    }
  }
  if (filters?.type) {
    params.append("type", filters.type);
  }
  if (filters?.agentTaskId) {
    params.append("agentTaskId", filters.agentTaskId);
  }
  if (filters?.page !== undefined) {
    params.append("page", String(filters.page));
  }
  if (filters?.limit !== undefined) {
    params.append("limit", String(filters.limit));
  }

  const queryString = params.toString();
  const endpoint = queryString ? `/api/runner-jobs?${queryString}` : "/api/runner-jobs";

  const response = await apiGet<ApiResponse<RunnerJob[]>>(endpoint, filters?.workspaceId);
  return response.data;
}

/**
 * Fetch a single runner job by ID
 */
export async function fetchRunnerJob(id: string, workspaceId?: string): Promise<RunnerJob> {
  return apiGet<RunnerJob>(`/api/runner-jobs/${id}`, workspaceId);
}

// ─── Job Steps ────────────────────────────────────────────────────────

/**
 * Job step phase enum (matches backend JobStepPhase)
 */
export enum JobStepPhase {
  SETUP = "SETUP",
  EXECUTION = "EXECUTION",
  VALIDATION = "VALIDATION",
  CLEANUP = "CLEANUP",
}

/**
 * Job step type enum (matches backend JobStepType)
 */
export enum JobStepType {
  COMMAND = "COMMAND",
  AI_ACTION = "AI_ACTION",
  GATE = "GATE",
  ARTIFACT = "ARTIFACT",
}

/**
 * Job step status enum (matches backend JobStepStatus)
 */
export enum JobStepStatus {
  PENDING = "PENDING",
  RUNNING = "RUNNING",
  COMPLETED = "COMPLETED",
  FAILED = "FAILED",
  SKIPPED = "SKIPPED",
}

/**
 * Job step response interface (matches Prisma JobStep model)
 */
export interface JobStep {
  id: string;
  jobId: string;
  ordinal: number;
  phase: JobStepPhase;
  name: string;
  type: JobStepType;
  status: JobStepStatus;
  output: string | null;
  tokensInput: number | null;
  tokensOutput: number | null;
  startedAt: string | null;
  completedAt: string | null;
  durationMs: number | null;
}

/**
 * Fetch job steps for a specific runner job
 */
export async function fetchJobSteps(jobId: string, workspaceId?: string): Promise<JobStep[]> {
  const response = await apiGet<ApiResponse<JobStep[]>>(
    `/api/runner-jobs/${jobId}/steps`,
    workspaceId
  );
  return response.data;
}
