import { z } from "zod";

/** Query params accepted by `GET /internal/tech-steps/audit-batch` and `GET /internal/tech-steps/pending-corrections` — both just a bound on how much work one call asks for, so the worker controls its own batch size rather than the server guessing. */
export const workerBatchQuerySchema = z.object({
  limit: z.coerce.number().int().positive().max(500).default(50),
});
/** Inferred TS type for {@link workerBatchQuerySchema}'s validated output. */
export type WorkerBatchQueryInput = z.infer<typeof workerBatchQuerySchema>;

/** `locale` param `GET /internal/tech-steps/audit-batch` also accepts, on top of {@link workerBatchQuerySchema} — which of `TECH_STEP_TRAINING_DATA`'s locales to sample steps' clauses against (see `tech-step-matcher.ts`'s `matchTechStepSpans` for the same parameter on the read side). No closed enum here (unlike `recipeVisibilitySchema`) — the training data's own locale list can grow without a schema change. */
export const auditBatchQuerySchema = workerBatchQuerySchema.extend({
  locale: z.string().min(2).default("fr"),
});
/** Inferred TS type for {@link auditBatchQuerySchema}'s validated output. */
export type AuditBatchQueryInput = z.infer<typeof auditBatchQuerySchema>;

/**
 * One suggestion in the batch `POST /internal/tech-steps/training-suggestions`
 * accepts — `techStepKey` (not an id) since the worker never has direct DB
 * access to resolve one itself; the API resolves it, and rejects the whole
 * batch with `TECH_STEP_NOT_FOUND` if any key is unknown (see
 * `tech-step-worker.service.ts`). `sourceCorrectionId` is required when
 * `sourceType` is `"correction"` (that's the whole point of that source —
 * it exists *because of* one specific correction) and must be absent
 * otherwise — enforced by the refinement below, not by two separate
 * schemas, so the error message can point at exactly which field is wrong.
 */
const trainingSuggestionSchema = z
  .object({
    techStepKey: z.string().min(1),
    locale: z.string().min(2),
    suggestedSynonyms: z.array(z.string().trim().min(1)),
    suggestedUtterances: z.array(z.string().trim().min(1)),
    sourceType: z.enum(["correction", "llm_audit"]),
    sourceCorrectionId: z.number().int().positive().nullable().optional(),
  })
  .refine(
    (input) =>
      input.sourceType === "correction"
        ? input.sourceCorrectionId !== null && input.sourceCorrectionId !== undefined
        : input.sourceCorrectionId === null || input.sourceCorrectionId === undefined,
    {
      message:
        "sourceCorrectionId is required when sourceType is 'correction', and must be absent otherwise",
      path: ["sourceCorrectionId"],
    },
  );

/** Payload accepted by `POST /internal/tech-steps/training-suggestions` — a batch, not one suggestion per call, since the worker's audit/correction jobs naturally produce several at once per run and there's no reason to round-trip once per suggestion. */
export const submitTrainingSuggestionsSchema = z.object({
  suggestions: z.array(trainingSuggestionSchema).min(1),
});
/** Inferred TS type for {@link submitTrainingSuggestionsSchema}'s validated output. */
export type SubmitTrainingSuggestionsInput = z.infer<typeof submitTrainingSuggestionsSchema>;
