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.
/* =========================================================================
   CommonDashboard.js — STABILE SEMPLICE (ripristino sicuro)
   - NON nasconde elementi esistenti
   - Ripristina pulsante "Importa Wikitesto da URL"
   - Risposte sempre mostrate anche se il server manda text/plain
   - Renderer Markdown + Highlight "leggero"
   ========================================================================= */

/* Guardia anti doppio-caricamento */
if (window.__MP_DASHBOARD_SAFE__) {
  console.warn('CommonDashboard.js già caricato.');
} else {
  window.__MP_DASHBOARD_SAFE__ = true;

  (function () {
    console.log('🧭 CommonDashboard SAFE: init');

    /* ========== Loader minimale per marked + highlight ========== */
    function loadScript(src) {
      return new Promise((ok, no) => {
        const s = document.createElement('script'); s.src = src; s.onload = ok; s.onerror = no;
        document.head.appendChild(s);
      });
    }
    function loadStyle(href) {
      return new Promise((ok, no) => {
        const l = document.createElement('link'); l.rel = 'stylesheet'; l.href = href; l.onload = ok; l.onerror = no;
        document.head.appendChild(l);
      });
    }
    async function ensureRenderer() {
      if (!window.marked) {
        await loadScript('https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.2/marked.min.js');
      }
      if (!window.hljs) {
        await loadStyle('https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css');
        await loadScript('https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js');
      }
    }
    function renderMarkdownInto(el, md) {
      if (!el) return;
      if (window.marked) {
        el.innerHTML = window.marked.parse(String(md || ''));
        if (window.hljs) {
          el.querySelectorAll('pre code').forEach(c => { try { window.hljs.highlightElement(c); } catch {} });
        }
      } else {
        el.textContent = String(md || '');
      }
    }

    /* ========== Helper UI di chat, non nasconde nulla della tua pagina ========== */
    function $(sel) { return document.querySelector(sel); }
    function appendMsg(role, content) {
      const host = $('#mpai-chat'); if (!host) return;
      const box = document.createElement('div');
      box.className = 'mpai-msg ' + (role === 'assistant' ? 'assistant' : role === 'user' ? 'user' : 'error');
      box.innerHTML = `
        <div class="role">${role === 'assistant' ? 'GPT' : role === 'user' ? 'Tu' : 'Errore'}</div>
        <div class="content"><em>…</em></div>
        <div class="meta"></div>`;
      host.appendChild(box);
      host.scrollTop = host.scrollHeight;
      const c = box.querySelector('.content');
      renderMarkdownInto(c, String(content || ''));
    }
    function showTyping() {
      const host = $('#mpai-chat'); if (!host) return null;
      const box = document.createElement('div');
      box.className = 'mpai-msg assistant';
      box.innerHTML = `<div class="role">GPT</div><div class="content">…</div>`;
      host.appendChild(box);
      host.scrollTop = host.scrollHeight;
      return box;
    }
    function hideTyping(el) { try { el && el.remove(); } catch {} }

    /* ========== INVIO PROMPT — semplice e robusto ========== */
    window.sendPrompt = async function () {
      const ta = $('#mpai-input'); if (!ta) return;
      const content = (ta.value || '').trim();
      if (!content) { ta.focus(); return; }

      appendMsg('user', content);
      ta.value = '';
      const typing = showTyping();

      // Legge modello dall’UI se presente
      const modelSel = $('#mpai-model');
      const model = modelSel ? (modelSel.value || 'gpt-4o-2024-05-13') : 'gpt-4o-2024-05-13';

      // PAYLOAD minimale (non tocco la tua dropzone/filelist esistente)
      const payload = { model, prompt: content, temperature: 0.7 };

      try {
        const res = await fetch('/dashboard/api/openai_project_gpt.php', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          credentials: 'include',
          cache: 'no-store',
          body: JSON.stringify(payload)
        });

        const raw = await res.text();
        hideTyping(typing);

        // Mostra sempre qualcosa anche se è text/plain
        let out = '';
        try {
          const j = JSON.parse(raw);
          out = j.result || j.text || j.reply || j.message || j.output_text || JSON.stringify(j, null, 2);
        } catch {
          out = raw;
        }
        out = String(out || '').replace(/\\n/g, '\n');

        if (!res.ok) {
          appendMsg('error', `HTTP ${res.status} ${res.statusText}\n\n${out}`);
        } else {
          appendMsg('assistant', out || '[nessun testo]');
        }
      } catch (e) {
        hideTyping(typing);
        appendMsg('error', 'Errore rete/JS: ' + (e && e.message ? e.message : e));
      }
    };

    /* ========== BIND UI: non nascondo la tua dropzone né la lista file ========== */
    function bindUI() {
      const sendBtn = $('#mpai-send');
      if (sendBtn && !sendBtn.__bound) {
        sendBtn.__bound = true;
        sendBtn.addEventListener('click', window.sendPrompt);
      }
      // Invio con Cmd/Ctrl+Enter
      document.addEventListener('keydown', (e) => {
        if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {
          const ta = $('#mpai-input');
          if (ta && document.activeElement === ta) { e.preventDefault(); window.sendPrompt(); }
        }
      });
      console.log('🔗 SAFE bind ok');
    }

    /* ========== RIPRISTINO: Pulsante "Importa Wikitesto da URL" ========== */
    function ensureImportButton() {
      // NON lo nascondo più in nessun caso
      // Lo aggancio vicino al titolo "Masticationpedia AI" se esiste, altrimenti in alto nella pagina
      const target =
        Array.from(document.querySelectorAll('h2,h3,.section-title,.mpai-header,.mp-section-title'))
          .find(n => /Masticationpedia\s*AI/i.test(n.textContent || '')) ||
        document.querySelector('#contentSub') ||
        document.body;

      if (!target || document.getElementById('mp-btn-import-url')) return;

      const btn = document.createElement('button');
      btn.id = 'mp-btn-import-url';
      btn.textContent = 'Importa Wikitesto da URL';
      btn.title = 'Scarica una pagina MediaWiki e salvala tra i file';
      btn.style.cssText = 'margin-left:.5rem;padding:.35rem .7rem;border:1px solid #444;border-radius:10px;cursor:pointer;font-size:.9rem;';
      target.appendChild(btn);

      btn.addEventListener('click', () => openImportModal());
      console.log('✅ Pulsante "Importa Wikitesto da URL" ripristinato');
    }

    function openImportModal() {
      const modal = document.createElement('div');
      modal.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:99999;display:flex;align-items:center;justify-content:center;';
      modal.innerHTML = `
        <div style="background:#fff;max-width:720px;width:92%;padding:1rem;border-radius:12px;box-shadow:0 8px 30px rgba(0,0,0,.15);">
          <h3 style="margin:.2rem 0 1rem;">Importa Wikitesto da URL</h3>
          <label style="display:block;margin:.4rem 0 .2rem;">URL della pagina (MediaWiki / Wikipedia / GitHub raw):</label>
          <input id="mp-url" type="url" placeholder="https://staging.masticationpedia.org/wiki/Introduction" style="width:100%;padding:.6rem;border:1px solid #ccc;border-radius:8px;">
          <div id="mp-status" style="margin-top:.6rem;font-size:.9rem;opacity:.85;"></div>
          <div style="margin-top:1rem;display:flex;justify-content:flex-end;gap:.6rem;">
            <button id="mp-cancel" style="padding:.5rem 1rem;border:1px solid #666;border-radius:10px;background:#fff;cursor:pointer;">Annulla</button>
            <button id="mp-go" style="padding:.5rem 1rem;border:1px solid #333;border-radius:10px;background:#111;color:#fff;cursor:pointer;">Importa</button>
          </div>
        </div>`;
      document.body.appendChild(modal);

      const elUrl = modal.querySelector('#mp-url');
      const elStatus = modal.querySelector('#mp-status');
      modal.querySelector('#mp-cancel').onclick = () => modal.remove();
      modal.querySelector('#mp-go').onclick = async () => {
        const url = (elUrl.value || '').trim();
        if (!url) { elStatus.textContent = 'Inserisci una URL valida.'; elStatus.style.color = '#b00'; return; }
        elStatus.textContent = 'Import in corso...'; elStatus.style.color = '';

        try {
          const form = new FormData();
          form.append('url', url);
          form.append('save', '1'); // server salverà nel progetto di default

          const res = await fetch('/dashboard/api/fetch_wikitext.php', { method: 'POST', body: form, credentials: 'include' });
          const raw = await res.text();
          if (!res.ok) throw new Error('HTTP ' + res.status + ' ' + res.statusText + ' — ' + raw);
          let j = {};
          try { j = JSON.parse(raw); } catch { j = { ok:false, raw }; }
          if (!j.ok) throw new Error(j.error || 'Errore server');

          elStatus.innerHTML = '✅ Import riuscito: <code>' + j.relative + '</code> (' + j.bytes + ' bytes)<br><small>Origine: ' + j.resolved_url + '</small>';
          elStatus.style.color = '#0a0';
          setTimeout(() => modal.remove(), 1200);
        } catch (e) {
          elStatus.textContent = 'Errore: ' + (e && e.message ? e.message : e);
          elStatus.style.color = '#b00';
        }
      };
    }

    /* ========== AVVIO ========== */
    function boot() {
      ensureRenderer().then(() => {
        bindUI();
        ensureImportButton();
        console.log('✅ CommonDashboard SAFE: pronta');
      }).catch((e) => {
        console.warn('Renderer non caricato:', e);
        bindUI();
        ensureImportButton();
      });
    }

    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', boot);
    } else { boot(); }
  })();
}