// src/lib/spec/audit/fix-prompt.ts — builder PUR du prompt « corriger avec
// votre agent ». Client-safe : aucune I/O, aucun import server-only — toutes
// les données (audit + items enrichis) arrivent en paramètres depuis le
// composant. Le squelette du prompt suit la locale de l'utilisateur (réglée
// dans les settings, résolue par next-intl) — anglais par défaut ; les
// constats d'audit embarqués restent tels que stockés (destinés à l'agent).
import type { Locale } from "@/i18n/config";

export type FixPromptItem = {
  itemId: string;
  title: string;
  specStatus: string;
  status: string;
  detail: string;
};

export type AuditFixPromptInput = {
  siteId: string;
  siteName: string;
  siteUrl: string;
  appUrl: string;
  score: number;
  ranAt: string | null;
  items: FixPromptItem[];
  /** Locale du squelette du prompt (settings utilisateur). Défaut : "en". */
  locale?: Locale;
};

type PromptStrings = {
  missionHeader: string;
  mission: (siteName: string, siteUrl: string) => string;
  auditLine: (ranAt: string, score: number, siteId: string) => string;
  connectionHeader: string;
  connectionIntro: string;
  connectionKeyNote: string;
  toFixHeader: (n: number) => string;
  toFixIntro: string;
  findingLabel: string;
  manualHeader: (n: number) => string;
  manualBody: (siteId: string) => string;
  naHeader: (n: number) => string;
  loopHeader: string;
  loopBody: (siteId: string) => string;
  guardrailsHeader: string;
  guardrails: string[];
};

const STRINGS: Record<Locale, PromptStrings> = {
  en: {
    missionHeader: "# MISSION",
    mission: (siteName, siteUrl) =>
      `Fix the site "${siteName}" (${siteUrl}) to bring it into compliance with The Website Specification, using the SEO Insight MCP server below.`,
    auditLine: (ranAt, score, siteId) =>
      `Audit from ${ranAt} — current score: ${score}/100. siteId: ${siteId}`,
    connectionHeader: "# MCP CONNECTION",
    connectionIntro:
      "Add this MCP server (the user creates their key in SEO Insight, Settings → API Keys):",
    connectionKeyNote:
      "Replace eli_xxxxxxxxxxxx with the real API key provided by the user. Never commit it.",
    toFixHeader: (n) => `# POINTS TO FIX (${n})`,
    toFixIntro:
      "For EACH point: call seo-insight.get_spec_topic(category, slug) for the detailed how-to, apply the minimal fix in the site's code, then move on to the next one.",
    findingLabel: "finding:",
    manualHeader: (n) =>
      `# TO CHECK MANUALLY (${n} point(s) to check manually)`,
    manualBody: (siteId) =>
      `The automated audit does not cover everything: call seo-insight.get_site_audit("${siteId}") for the list of items with status "manual", handle the ones that apply to the site's code (contrast, alt text, ARIA, forms…) via get_spec_topic, and flag to the user the ones that are about content or editorial choices.`,
    naHeader: (n) => `# NOT APPLICABLE TODAY (${n}) — evaluate if relevant`,
    loopHeader: "# VERIFICATION LOOP",
    loopBody: (siteId) =>
      `After fixing and deploying a batch of points: call seo-insight.run_site_audit("${siteId}") and compare the verdicts. Repeat until zero fail/warn. Note: a re-audit less than 60 s after the previous one returns the existing result (cooldown).`,
    guardrailsHeader: "# GUARDRAILS",
    guardrails: [
      "- Minimal changes: do not rewrite what already works.",
      "- Break nothing: check that the site builds/runs after each change.",
      "- Git discipline: one commit per fixed point, clear message.",
    ],
  },
  fr: {
    missionHeader: "# MISSION",
    mission: (siteName, siteUrl) =>
      `Corriger le site « ${siteName} » (${siteUrl}) pour le mettre en conformité avec The Website Specification, en t'appuyant sur le serveur MCP SEO Insight ci-dessous.`,
    auditLine: (ranAt, score, siteId) =>
      `Audit du ${ranAt} — score actuel : ${score}/100. siteId : ${siteId}`,
    connectionHeader: "# CONNEXION MCP",
    connectionIntro:
      "Ajoute ce serveur MCP (l'utilisateur crée sa clé dans SEO Insight, Réglages → Clés API) :",
    connectionKeyNote:
      "Remplace eli_xxxxxxxxxxxx par la clé API réelle fournie par l'utilisateur. Ne la committe jamais.",
    toFixHeader: (n) => `# POINTS À CORRIGER (${n})`,
    toFixIntro:
      "Pour CHAQUE point : appelle seo-insight.get_spec_topic(category, slug) pour la marche à suivre détaillée, applique la correction minimale dans le code du site, puis passe au suivant.",
    findingLabel: "constat :",
    manualHeader: (n) =>
      `# À VÉRIFIER MANUELLEMENT (${n} point(s) à vérifier manuellement)`,
    manualBody: (siteId) =>
      `L'audit automatique ne couvre pas tout : appelle seo-insight.get_site_audit("${siteId}") pour la liste des items en statut manual, traite ceux qui s'appliquent au code du site (contraste, alt text, ARIA, formulaires…) via get_spec_topic, et signale à l'utilisateur ceux qui relèvent du contenu ou de l'éditorial.`,
    naHeader: (n) =>
      `# NON APPLICABLES AUJOURD'HUI (${n}) — à évaluer si pertinent`,
    loopHeader: "# BOUCLE DE VÉRIFICATION",
    loopBody: (siteId) =>
      `Après avoir corrigé et déployé un lot de points : appelle seo-insight.run_site_audit("${siteId}") et compare les verdicts. Répète jusqu'à zéro fail/warn. Note : un re-audit à moins de 60 s du précédent renvoie le résultat existant (cooldown).`,
    guardrailsHeader: "# GARDE-FOUS",
    guardrails: [
      "- Modifications minimales : ne réécris pas ce qui fonctionne.",
      "- Ne casse rien : vérifie que le site build/tourne après chaque changement.",
      "- Discipline git : un commit par point corrigé, message clair.",
    ],
  },
};

export function buildAuditFixPrompt(input: AuditFixPromptInput): string {
  const s = STRINGS[input.locale ?? "en"] ?? STRINGS.en;
  const toFix = input.items.filter(
    (i) => i.status === "fail" || i.status === "warn",
  );
  const manualCount = input.items.filter((i) => i.status === "manual").length;
  const naIds = input.items
    .filter((i) => i.status === "na")
    .map((i) => i.itemId);

  const lines: string[] = [
    s.missionHeader,
    s.mission(input.siteName, input.siteUrl),
    s.auditLine(input.ranAt ?? "?", input.score, input.siteId),
    "",
    s.connectionHeader,
    s.connectionIntro,
    "```json",
    JSON.stringify(
      {
        mcpServers: {
          "seo-insight": {
            url: `${input.appUrl}/api/mcp`,
            headers: { Authorization: "Bearer eli_xxxxxxxxxxxx" },
          },
        },
      },
      null,
      2,
    ),
    "```",
    s.connectionKeyNote,
    "",
    s.toFixHeader(toFix.length),
    s.toFixIntro,
    ...toFix.map(
      (i) =>
        `- [${i.status}] ${i.itemId} (${i.specStatus}) — ${i.title}${i.detail ? ` · ${s.findingLabel} ${i.detail}` : ""}`,
    ),
    "",
    s.manualHeader(manualCount),
    s.manualBody(input.siteId),
    "",
  ];
  if (naIds.length > 0) {
    lines.push(s.naHeader(naIds.length), ...naIds.map((id) => `- ${id}`), "");
  }
  lines.push(
    s.loopHeader,
    s.loopBody(input.siteId),
    "",
    s.guardrailsHeader,
    ...s.guardrails,
  );
  return lines.join("\n");
}
