// ── Gedeelde basisvalidatie voor voorstel-POST-routes (MCP) ──────────────────
// De routes /api/modeldocumenten/voorstellen (modelonderdeel) en
// /api/modeldocumenten/modelvoorstellen (volledig modeldocument) — en elke
// toekomstige voorstelroute — valideren dezelfde basisvelden: titel,
// omschrijving, prioriteit en één verplicht JSON-tekstveld met de voorgestelde
// inhoud. Eén module zodat de regels en foutteksten nooit uiteenlopen.

import type { VoorstelPrioriteit } from "@/data/modeldocumenten";

export const PRIORITEITEN: VoorstelPrioriteit[] = ["hoog", "midden", "laag"];

/** Een string met inhoud, of undefined (voor optionele velden als bron/onderdeelId). */
export function optioneleString(waarde: unknown): string | undefined {
  return typeof waarde === "string" && waarde.trim() ? waarde : undefined;
}

/** De gevalideerde gedeelde basisvelden van een voorstel-POST. */
export interface VoorstelBasis {
  titel: string;
  omschrijving: string;
  prioriteit: VoorstelPrioriteit;
  bron?: string;
  /** De geparste waarde van het verplichte JSON-tekstveld (onderdeelJson/modelJson). */
  inhoud: unknown;
  /** De ruwe body, voor de routespecifieke velden (onderdeelId/modelId). */
  body: Record<string, unknown>;
}

/**
 * Valideert de gedeelde basisvelden van een voorstel-body en parseert het
 * verplichte JSON-tekstveld. Retourneert bij de eerste overtreding een
 * `{ fout }` (de route antwoordt daarmee als HTTP 400).
 */
export function valideerVoorstelBasis(
  rauweBody: unknown,
  jsonVeld: {
    naam: string;
    /** Volledige foutmelding wanneer het veld ontbreekt (incl. verwijzing naar de richtlijnen-route). */
    ontbreektFout: string;
  }
): VoorstelBasis | { fout: string } {
  const body = (rauweBody ?? {}) as Record<string, unknown>;
  const { titel, omschrijving, prioriteit, bron } = body;

  if (typeof titel !== "string" || !titel.trim()) {
    return { fout: "'titel' (string) is verplicht." };
  }
  if (typeof omschrijving !== "string" || !omschrijving.trim()) {
    return { fout: "'omschrijving' (string) is verplicht." };
  }
  if (typeof prioriteit !== "string" || !PRIORITEITEN.includes(prioriteit as VoorstelPrioriteit)) {
    return { fout: `'prioriteit' is verplicht en moet één van ${PRIORITEITEN.join(", ")} zijn.` };
  }
  const jsonTekst = body[jsonVeld.naam];
  if (typeof jsonTekst !== "string" || !jsonTekst.trim()) {
    return { fout: jsonVeld.ontbreektFout };
  }
  let inhoud: unknown;
  try {
    inhoud = JSON.parse(jsonTekst);
  } catch {
    return { fout: `'${jsonVeld.naam}' is geen geldige JSON.` };
  }

  return {
    titel,
    omschrijving,
    prioriteit: prioriteit as VoorstelPrioriteit,
    bron: optioneleString(bron),
    inhoud,
    body,
  };
}

/** De gedeelde GET-nota over de (niet-)persistentie van de voorstellenwachtrij. */
export function voorstellenNota(persistent: boolean): string {
  return persistent
    ? "Persistente opslag actief: neem voorstellen over via het tabblad " +
        "'Te valideren' in de modeldocumentenbibliotheek."
    : "Best-effort cache binnen deze serverinstantie: niet persistent over " +
        "deployments of meerdere instanties. Neem voorstellen over via het " +
        "tabblad 'Te valideren' in de modeldocumentenbibliotheek.";
}
