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.
/* ======================= CommonTranslateUpdate.js (INTEGRAZIONE COMPLETA) ======================= */

console.log("🔄 Caricamento CommonTranslateUpdate.js...");

if (window.CommonTranslateUpdateLoaded) {
    console.warn("⚠️ CommonTranslateUpdate.js è già stato caricato.");
} else {
    window.CommonTranslateUpdateLoaded = true;
    window.linguaOrigine = localStorage.getItem("linguaOrigine") || document.documentElement.lang || "en";

    if (!window.apiKey) {
        window.apiKey = "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"; // Inserisci la tua API key qui
    }

    console.log("✅ CommonTranslateUpdate.js caricato correttamente!");
}
/* ------- Segmentazione --------*/
function segmentaBloccoMediaWiki(wikitesto) {
    const blocchiProtetti = [
    /{{Tooltip\|[^{}]*?\|[^{}]*?\|<small>[\s\S]*?<\/small>\|?}}/g,
    /{{Tooltip\|(?:[^{}]|{{[^{}]*}}|<[^>]*>|\[\[[^\]]+\]\]|%%[^%]+%%)+}}/g, // Tooltip con contenuto complesso
    /<ref[^>]*>[\s\S]*?<\/ref>/g,
    /<math>[\s\S]*?<\/math>/g,
    /<gallery[\s\S]*?<\/gallery>/g,
    /{{(?:[^{}]|\{\{[^{}]*\}\})*}}/g
];


    let placeholderMap = {};
    let placeholderIndex = 0;

    blocchiProtetti.forEach((regex) => {
        wikitesto = wikitesto.replace(regex, (match) => {
            const key = `%%SEGMENTO_${placeholderIndex++}%%`;
            placeholderMap[key] = match;
            return key;
        });
    });

    const segmenti = wikitesto
        .split(/\n(?==|===|{{CD1}})/)
        .map(seg => seg.trim())
        .filter(seg => seg.length > 0);

    const segmentiFinali = segmenti.map(seg => {
        Object.entries(placeholderMap).forEach(([key, valore]) => {
            seg = seg.replaceAll(key, valore);
        });
        return seg;
    });

    return segmentiFinali;
}


/* ======================= Ripristina segmenti salvati ======================= */
function ripristinaSegmenti(text) {
    if (!window.segmentiSalvati) return text;
    return text.replace(/%%SEGMENTO_(\d+)%%/g, function(match, index) {
        const segmento = window.segmentiSalvati[parseInt(index)];
        return segmento ? segmento : match;
    });
}


/* ======================= AVVIO TRADUZIONE ======================= */
async function traduciTestoUpdate() {
    const conferma = confirm("⚡ Vuoi tradurre il capitolo?");
    if (!conferma) return;

    const linguaScelta = prompt("🌍 Scegli la lingua:\nit = Italiano\nen = Inglese\nfr = Francese\nes = Spagnolo\nde = Tedesco\ntutte = Tutte le lingue", "en");
    if (!linguaScelta) return;

    const lingue = ["it", "en", "fr", "es", "de"];
    const lingueDaTradurre = linguaScelta === "tutte" ? lingue : [linguaScelta];
    localStorage.setItem("lingueDaTradurre", JSON.stringify(lingueDaTradurre));

    verificaURLCapitoli(lingueDaTradurre);
}

function verificaURLCapitoli(lingueDaTradurre) {
    let formHtml = `<form id="urlForm">`;
    for (let lang of lingueDaTradurre) {
        formHtml += `
        <label for="url_${lang}">${lang.toUpperCase()}:</label>
        <input type="text" id="url_${lang}" value="${localStorage.getItem(`urlCapitolo_${lang}`) || ""}" style="width:100%;margin-bottom:5px;"><br>`;
    }
    formHtml += `</form>`;

    let popup = document.createElement("div");
    popup.innerHTML = `
    <div id="popup-url-traduzione" style="position:fixed; top:50%; left:50%; transform:translate(-50%, -50%);
         background:white; padding:20px; border-radius:10px; box-shadow:0px 4px 6px rgba(0,0,0,0.2); z-index:2000; font-family:Arial, sans-serif;">

        <h3>🔍 Imposta gli URL per la traduzione</h3>

        <p>
          🧠 <b>Parole:</b> <span id="conteggio-parole">0</span><br>
          🔢 <b>Token stimati:</b> <span id="conteggio-token">0</span><br>
          💰 <b>Costo stimato:</b> <span id="costo-stimato">$0.0000</span>
        </p>

        ${formHtml}

        <div style="margin-top:10px; text-align:right;">
          <button id="salvaUrlBtn" type="button">✅ Salva URL</button>
          <button id="chiudiPopup" type="button">❌ Annulla</button>
        </div>
    </div>
    `;

    document.body.appendChild(popup);

    const testo = ottieniTestoDaEditor();
    const parole = testo.trim().split(/\s+/).length;
    const tokenStimati = Math.ceil(parole / 0.75);
    const costo = (tokenStimati * 0.00002).toFixed(4);

    try {
        document.getElementById("conteggio-parole").innerText = parole;
        document.getElementById("conteggio-token").innerText = tokenStimati;
        document.getElementById("costo-stimato").innerText = `$${costo}`;
    } catch (e) {
        console.warn("⚠️ Conteggio parole/token non aggiornato:", e);
    }

    setTimeout(() => {
        const salvaBtn = document.getElementById("salvaUrlBtn");
        const chiudiBtn = document.getElementById("chiudiPopup");

        if (salvaBtn) {
            salvaBtn.onclick = function () {
                lingueDaTradurre.forEach(lang => {
                    const newUrl = document.getElementById(`url_${lang}`).value.trim();
                    localStorage.setItem(`urlCapitolo_${lang}`, newUrl);
                });
                document.body.removeChild(popup);
                avviaTraduzioneConSegmentazione(lingueDaTradurre);
            };
        }

        if (chiudiBtn) {
            chiudiBtn.onclick = function () {
                document.body.removeChild(popup);
            };
        }
    }, 100);
}

function avviaTraduzioneConSegmentazione(lingueDaTradurre) {
    const testo = ottieniTestoDaEditor();
    const blocchi = segmentaBloccoMediaWiki(testo); // NUOVA FUNZIONE USATA QUI
    const errori = analizzaErroriSegmentazione(blocchi);
    sostituisciTestoSegmentato(blocchi, errori);
    mostraPopupConferma(blocchi, errori, lingueDaTradurre);
}

/*========= Errori ed invio ==========*/

function ottieniTestoDaEditor() {
    const area = document.getElementById("wpTextbox1");
    return area ? area.value.trim() : "";
}

function analizzaErroriSegmentazione(blocchi) {
    let errori = [];
    blocchi.forEach((b, i) => {
        let err = [];
        [["[", "]"], ["{", "}"], ["<", ">"]].forEach(([o, c]) => {
            const countO = (b.match(new RegExp(`\\${o}`, "g")) || []).length;
            const countC = (b.match(new RegExp(`\\${c}`, "g")) || []).length;
            if (countO !== countC) err.push(`${o}${c} non bilanciate`);
        });
        if (err.length) errori.push({ index: i + 1, dettagli: err });
    });
    return errori;
}

function sostituisciTestoSegmentato(blocchi, errori) {
    const area = document.getElementById("wpTextbox1");
    const finale = blocchi.map((b, i) => {
        const e = errori.find(x => x.index === i + 1);
        const evidenza = e ? `⚠️ ERRORI:\n- ${e.dettagli.join("\n- ")}\n\n` : "";
        return `${evidenza}🔹 BLOCCO ${i + 1}\n${b}`;
    });
    area.value = finale.join("\n\n==============================\n\n");
}

function mostraPopupConferma(blocchi, errori, lingueDaTradurre) {
    const popup = document.createElement("div");
    popup.style = `
        position: fixed;
        bottom: 20px;
        right: 20px;
        background: white;
        padding: 15px;
        border: 2px solid #444;
        box-shadow: 4px 4px 10px rgba(0,0,0,0.3);
        z-index: 9999;
        resize: both;
        overflow: auto;
        cursor: move;`;
    popup.innerHTML = `
        <b>✅ Segmentazione completata</b><br>
        🧠 Token stimati: ~${blocchi.length * 3000}<br>
        💰 Costo approssimativo: ~$${(blocchi.length * 3000 * 0.00002).toFixed(2)}<br>
        ${errori.length > 0
            ? `❗ <span style='color:red;'>${errori.length} errori rilevati. Procedere?</span><br>`
            : `<span style='color:green;'>✅ Nessun errore rilevato</span><br>`}
        <button id="btn-invia-traduzioni">✅ Invia Traduzioni</button>
        <button id="btn-salva-segmentato">💾 Salva localmente</button>
        <button onclick="this.parentNode.remove()">❌ Annulla</button>`;

    document.body.appendChild(popup);
    dragElement(popup);

    document.getElementById("btn-invia-traduzioni").onclick = () => {
        popup.remove();
        lingueDaTradurre.forEach(lang => inviaTraduzione(lang, blocchi));
    };

    document.getElementById("btn-salva-segmentato").onclick = () => {
        const testoSegmentato = document.getElementById("wpTextbox1").value.trim();
        localStorage.setItem("segmentatoDaInviare", testoSegmentato);
        alert("✅ Testo segmentato salvato localmente!");
    };
}

function ricostruisciTestoSegmentato(blocchi) {
    return blocchi.map(b => {
        return b.trim().match(/^={2,5}[^=]+={2,5}$/)
            ? `\n\n${b.trim()}\n\n`
            : b.trim();
    }).join("\n\n");
}

async function inviaTraduzione(lingua, blocchi) {
    
const urlAPI = "https://staging.masticationpedia.org/api.php";


    const urlDestinazione = localStorage.getItem(`urlCapitolo_${lingua}`);
    if (!urlDestinazione) return;

    const tokenRes = await fetch(`${urlAPI}?action=query&meta=tokens&type=csrf&format=json`, { credentials: "include" });
    const tokenData = await tokenRes.json();
    const csrfToken = tokenData.query.tokens.csrftoken;

    let testoTradotto = ricostruisciTestoSegmentato(
        await Promise.all(blocchi.map(b => traduciBlocco(b, lingua)))
    );
    testoTradotto = ripristinaSegmenti(testoTradotto); // ✅ AGGIUNTA QUESTA RIGA
    const formData = new URLSearchParams();
    formData.append("action", "edit");
    formData.append("title", urlDestinazione.split("/").pop());
    formData.append("text", testoTradotto);
    formData.append("format", "json");
    formData.append("token", csrfToken);

    const response = await fetch(urlAPI, {
        method: "POST",
        headers: { "Content-Type": "application/x-www-form-urlencoded" },
        body: formData,
        credentials: "include"
    });

    const data = await response.json();
    if (data.edit && data.edit.result === "Success") {
        alert(`✅ Traduzione inviata con successo a: ${urlDestinazione}`);
    } else {
        console.error("❌ Errore invio:", data);
    }
}

async function traduciBlocco(blocco, lingua) {
    try {
        const res = await fetch("https://api.openai.com/v1/chat/completions", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "Authorization": `Bearer ${window.apiKey}`
            },
            body: JSON.stringify({
                model: "gpt-4o-2024-05-13",
                messages: [
                    { role: "system", content: "You are a professional MediaWiki translator. Preserve all formatting, templates, and syntax. Do not translate the content inside <math>, <ref>, {{...}}, or [[...]]." },
                    { role: "user", content: `Translate this text into ${lingua}:\n\n${blocco}` }
                ],
                temperature: 0.2
            })
        });
        const data = await res.json();
        return data.choices[0].message.content;
    } catch (e) {
        console.error("❌ Traduzione fallita:", e);
        return "[Errore Traduzione]";
    }
}

function dragElement(elmnt) {
    let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
    elmnt.onmousedown = dragMouseDown;
    function dragMouseDown(e) {
        e = e || window.event; e.preventDefault();
        pos3 = e.clientX; pos4 = e.clientY;
        document.onmouseup = closeDragElement;
        document.onmousemove = elementDrag;
    }
    function elementDrag(e) {
        e = e || window.event; e.preventDefault();
        pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY;
        pos3 = e.clientX; pos4 = e.clientY;
        elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
        elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
    }
    function closeDragElement() {
        document.onmouseup = null;
        document.onmousemove = null;
    }
}