// ── Gedeelde mechaniek van de template-merge-paden ───────────────────────────
// compromisSjabloon.ts en akteSjabloon.ts mergen elk hun eigen kantoorsjabloon
// (eigen ankers, eigen stijlen), maar de omringende OOXML-mechaniek is
// identiek: de body van document.xml opensplitsen, 'Wijzigingen bijhouden' en
// veldherberekening forceren in settings.xml, de spellingtaal van de
// docDefaults corrigeren in styles.xml, en het .docx met expliciete
// DEFLATE-compressie genereren. Eén module zodat die vier stappen op beide
// paden gegarandeerd gelijk blijven.

import type JSZip from "jszip";
import { zetSpellingtaalInStyles } from "./sjabloonTaal";

/** document.xml opgesplitst rond <w:body>: alles vóór, de body, alles erna. */
export interface GesplitsteBody {
  voor: string;
  body: string;
  na: string;
}

/** Splitst document.xml in (voor, body, na); null wanneer er geen body is. */
export function splitsBody(xml: string): GesplitsteBody | null {
  const bodyOpen = xml.indexOf("<w:body>");
  const bodyEinde = xml.lastIndexOf("</w:body>");
  if (bodyOpen < 0 || bodyEinde < 0) return null;
  return {
    voor: xml.slice(0, bodyOpen + "<w:body>".length),
    body: xml.slice(bodyOpen + "<w:body>".length, bodyEinde),
    na: xml.slice(bodyEinde),
  };
}

/**
 * Zet 'Wijzigingen bijhouden' (track changes) aan in word/settings.xml, zodat
 * de notaris/agent elke ingreep apart kan aanvaarden of weigeren, en laat Word
 * de velden (SEQ-clausulenummering, inhoudsopgave) herberekenen bij het openen
 * — zonder manueel Ctrl+A F9. Bestaande, eventueel uitgeschakelde instellingen
 * (w:val="false"/"0") worden geforceerd aan.
 */
export async function zetTrackChangesEnUpdateFields(zip: JSZip): Promise<void> {
  const settingsBestand = zip.file("word/settings.xml");
  if (!settingsBestand) return;
  let settings = await settingsBestand.async("string");
  if (/<w:trackChanges\b[^>]*\/>/.test(settings)) {
    settings = settings.replace(/<w:trackChanges\b[^>]*\/>/, "<w:trackChanges/>");
  } else if (/<w:settings\b[^>]*>/.test(settings)) {
    settings = settings.replace(/(<w:settings\b[^>]*>)/, `$1<w:trackChanges/>`);
  }
  if (/<w:updateFields\b[^>]*\/>/.test(settings)) {
    settings = settings.replace(/<w:updateFields\b[^>]*\/>/, `<w:updateFields w:val="true"/>`);
  } else if (/<w:settings\b[^>]*>/.test(settings)) {
    settings = settings.replace(/(<w:settings\b[^>]*>)/, `$1<w:updateFields w:val="true"/>`);
  }
  zip.file("word/settings.xml", settings);
}

/**
 * Corrigeert de docDefaults-spellingtaal in word/styles.xml naar de Belgische
 * documenttaal (nl-BE/fr-BE) — de sjablonen dragen van huis uit een weggedreven
 * taal (fr-FR, of nl-BE op het FR-aktesjabloon). Zie sjabloonTaal.ts.
 */
export async function zetSpellingtaalInZip(zip: JSZip, taal: "nl" | "fr"): Promise<void> {
  const stylesBestand = zip.file("word/styles.xml");
  if (!stylesBestand) return;
  zip.file("word/styles.xml", zetSpellingtaalInStyles(await stylesBestand.async("string"), taal));
}

/**
 * Genereert het .docx met expliciete DEFLATE-compressie: JSZip valt anders
 * terug op ongecomprimeerd (STORE) voor ALLE bestanden — ook de ongewijzigde
 * delen van het sjabloon — wat het bestand nodeloos 2 tot 3× groter maakt.
 */
export function genereerDocx(zip: JSZip): Promise<Buffer> {
  return zip.generateAsync({ type: "nodebuffer", compression: "DEFLATE" });
}
