Nota: dopo aver pubblicato, potrebbe essere necessario pulire la cache del proprio browser per vedere i cambiamenti.

  • Firefox / Safari: tieni premuto il tasto delle maiuscole Shift e fai clic su Ricarica, oppure premi Ctrl-F5 o Ctrl-R (⌘-R su Mac)
  • Google Chrome: premi Ctrl-Shift-R (⌘-Shift-R su un Mac)
  • Edge: tieni premuto il tasto Ctrl e fai clic su Aggiorna, oppure premi Ctrl-F5.
/* ======================= CommonTranslate.js (server-proxy) ======================= */
console.log("🔄 Caricamento CommonTranslate.js…");

/* Evita doppi caricamenti */
if (window.CommonTranslateLoaded) {
  console.warn("⚠️ CommonTranslate.js è già stato caricato.");
} else {
  window.CommonTranslateLoaded = true;

  /* === Config di base (senza API key nel client) === */
  window.linguaOrigine = document.documentElement.lang || "en";
  const API_PROXY = "/dashboard/api/openai_project_gpt.php";   // il “cameriere”
  const MODEL_DEFAULT = "gpt-4o";                               // il server userà questo
  console.log("✅ CommonTranslate.js pronto (via proxy).");
}

/* ======================= Azione principale ======================= */
async function traduciTesto() {
  const area = document.getElementById("wpTextbox1");
  if (!area) { alert("Campo editor non trovato."); return; }

  const start = area.selectionStart;
  const end   = area.selectionEnd;
  const sel   = area.value.slice(start, end).trim();
  const tutto = !sel;

  // 1) cosa tradurre
  const onlySel = confirm("📝 Vuoi tradurre SOLO il testo selezionato?\n\n✅ OK = solo selezione\n❌ Annulla = tutto il testo");
  if (onlySel && !sel) {
    alert("⚠️ Nessuna selezione. Premi Annulla per tradurre tutto.");
    return;
  }
  const testo = tutto ? area.value : sel;

  // 2) lingua di destinazione
  const lingua = prompt(
    "🌍 Scegli la lingua di traduzione (it, en, fr, es, de):",
    "it"
  );
  if (!lingua) { console.warn("⚠️ Lingua non indicata."); return; }

  // 3) segmentazione e (se tutto) pre-check
  const blocchi = segmentaTesto(testo);
  console.log(`🧩 Segmentazione: ${blocchi.length} blocchi`);

  if (tutto) {
    const errori = analizzaErroriSegmentazione(blocchi);
    sostituisciTestoSegmentato(blocchi, errori);
    mostraPopupConferma(blocchi, errori, lingua, tutto);
    return; // la traduzione parte dal popup
  }

  // 4) traduzione diretta (solo selezione)
  const tradotto = await inviaTraduzione(blocchi, lingua, tutto);

  // 5) inserimento nel campo editor
  if (tutto) {
    area.value = tradotto;
  } else {
    const prima = area.value.slice(0, start);
    const dopo  = area.value.slice(end);
    area.value  = prima + tradotto + dopo;
    area.selectionStart = start;
    area.selectionEnd   = start + tradotto.length;
  }

  // 6) notifica a MW
  area.dispatchEvent(new Event("input",  { bubbles: true }));
  area.dispatchEvent(new Event("change", { bubbles: true }));

  console.log("✅ Traduzione completata e inserita.");
}

/* ======================= Utility ======================= */
function segmentaTesto(testo, maxChars = 6000) {
  // segmentazione semplice per blocchi “morbidi” su spazi
  const re = new RegExp(`.{1,${maxChars}}(?=\\s|$)`, "gs");
  return testo.match(re) || [testo];
}

function analizzaErroriSegmentazione(blocchi) {
  const errors = [];
  const count = (s, ch) => (s.match(new RegExp(`\\${ch}`, "g")) || []).length;
  const braces = [["[", "]"], ["{", "}"], ["<", ">"]];
  blocchi.forEach((b, i) => {
    const e = [];
    braces.forEach(([o, c]) => {
      const co = count(b, o), cc = count(b, c);
      if (co !== cc) e.push(`Parentesi ${o}${c} non bilanciate: ${co} ${o}, ${cc} ${c}`);
    });
    if (e.length) errors.push({ index: i + 1, dettagli: e });
  });
  return errors;
}

function sostituisciTestoSegmentato(blocchi, errori) {
  const area = document.getElementById("wpTextbox1");
  if (!area) return;
  const text = blocchi.map((b, i) => {
    const err = errori.find(x => x.index === i + 1);
    const head = err ? `⚠️ ERRORI:\n- ${err.dettagli.join("\n- ")}\n\n` : "";
    return `${head}🔹 BLOCCO ${i + 1}\n` + b;
  }).join("\n\n==============================\n\n");
  area.value = text;
  console.log("✍️ Testo segmentato inserito nel campo.");
}

function mostraPopupConferma(blocchi, errori, lingua, tutto) {
  const popup = document.createElement("div");
  popup.id = "popup-conferma-traduzione";
  popup.style = `
    position: fixed; bottom: 20px; right: 20px;
    background: #fff; padding: 15px; border: 2px solid #444;
    box-shadow: 4px 4px 10px rgba(0,0,0,.3); z-index: 9999;
  `;
  popup.innerHTML = `
    <b>✅ Segmentazione completata</b><br>
    Blocchi: ${blocchi.length}<br>
    ${errori.length ? `<span style="color:#c00;">❗ ${errori.length} blocchi con parentesi non bilanciate</span><br>` : `✅ Nessun errore strutturale<br>`}
    <button id="btn-invia-traduzione">✅ Invia traduzione</button>
    <button id="btn-close-popup">❌ Annulla</button>
  `;
  document.body.appendChild(popup);

  document.getElementById("btn-close-popup").onclick = () => popup.remove();
  document.getElementById("btn-invia-traduzione").onclick = async () => {
    popup.remove();
    try { await inviaTraduzione(blocchi, lingua, tutto); }
    catch (e) {
      console.error("❌ Errore invio traduzione:", e);
      alert("Errore durante l’invio:\n" + (e?.message || e));
    }
  };
}

/* ======================= Traduzione via “cameriere” ======================= */
async function inviaTraduzione(blocchi, lingua, tutto = true) {
  const area = document.getElementById("wpTextbox1");
  if (!area) return "";

  let risultato = "";
  console.log("🧪 inviaTraduzione() → blocchi:", blocchi.length, "lingua:", lingua);

  for (let i = 0; i < blocchi.length; i++) {
    console.log(`🚀 Invio blocco ${i + 1}/${blocchi.length}…`);
    const trad = await traduciBloccoProxy(blocchi[i], lingua);
    risultato += (trad || "[Errore Traduzione]") + "\n\n";
  }

  const tradotto = risultato.trim();
  if (tutto) {
    area.value = tradotto;
  } else {
    const start = area.selectionStart;
    const end   = area.selectionEnd;
    const prima = area.value.slice(0, start);
    const dopo  = area.value.slice(end);
    area.value  = prima + tradotto + dopo;
    area.selectionStart = start;
    area.selectionEnd   = start + tradotto.length;
  }

  area.dispatchEvent(new Event("input",  { bubbles: true }));
  area.dispatchEvent(new Event("change", { bubbles: true }));

  console.log("✅ Traduzione completata.");
  return tradotto;
}

async function traduciBloccoProxy(blocco, lingua) {
  // Prompt “sicuro”: il server riceve solo il prompt, non la key
  const system = "You are a professional MediaWiki translator. Preserve all templates, links, tags and wiki syntax exactly; translate only human-readable text. Keep headings and parameters unchanged.";
  const user   = `Translate the following MediaWiki wikitext into ${lingua}. Keep formatting/templates/links untouched:\n\n${blocco}`;

  const prompt = [
    { role: "system", content: system },
    { role: "user",   content: user   }
  ];

  try {
    const res = await fetch(API_PROXY, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        prompt: JSON.stringify(prompt), // il “cameriere” inoltra come chat
        model:  MODEL_DEFAULT
      })
    });

    const data = await res.json().catch(() => ({}));
    if (!res.ok || data.status !== "ok") {
      const msg = data?.error || `HTTP ${res.status}`;
      throw new Error(msg);
    }

    // Il cameriere risponde con {status:"ok", result:"…"}
    return (data.result || "").trim();
  } catch (err) {
    console.error("❌ Errore da proxy:", err);
    return "[Errore Traduzione]";
  }
}

/* ======================= UI: pulsante in editor ======================= */
$(function () {
  const area = $("#wpTextbox1");
  if (!area.length) return;

  if (!$("#pulsanteTraduci").length) {
    area.after('<button id="pulsanteTraduci" class="btn">🧠 Traduci contenuto</button>');
    $("#pulsanteTraduci").on("click", traduciTesto);
  }
});