import * as z from "zod";

// Frontière réseau du **socle jobs** (`api/app/jobs/schemas.py`, spec « socle jobs » §3).
// Rien d'ici ne connaît un module métier : `progress` et `report` sont du jsonb de forme
// libre, laissé tel quel au rendu du module qui a enfilé le job (imports, plus tard crawl
// et GSC). Les dates sont typées `z.string()` — le web ne fait que les réafficher.

/** Statuts du socle (`api/app/jobs/models.py`) ; `done` et `failed` sont terminaux. */
export const JOB_STATUS_LABELS: Record<string, string> = {
  queued: "En file",
  running: "En cours",
  done: "Terminé",
  failed: "Échec",
};

// `z.record(z.string(), z.unknown())` plutôt qu'un schéma fermé : le jsonb évoluera côté
// api (compteurs ajoutés au fil des modules) sans qu'une page web casse au parse.
const freeform = z.record(z.string(), z.unknown());

export const jobSchema = z.object({
  id: z.uuid(),
  type: z.string(),
  status: z.string(),
  progress: freeform.nullable(),
  report: freeform.nullable(),
  error: z.string().nullable(),
  created_at: z.string(),
  started_at: z.string().nullable(),
  finished_at: z.string().nullable(),
});

export type Job = z.infer<typeof jobSchema>;

/** Un job terminé n'est plus interrogé : c'est ce qui arrête le polling (spec §7.3). */
export function isJobFinished(status: string): boolean {
  return status === "done" || status === "failed";
}
