// Keep existing autofill listener
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.action === "autofill-f24") {
    try {
      const payload = request.payload;
      let filledCount = 0;

      // 1. Detailed autofill for DropPoint F24 fields (contribuente details and erario grid)
      if (payload.cognome || payload.nome || payload.dataNascita || (payload.erario && payload.erario.length > 0)) {
        fillDropPointF24(payload);
        filledCount += 10;
      }

      // 2. Generic fallback fill
      const inputs = Array.from(document.querySelectorAll("input, textarea, select"));

      inputs.forEach(input => {
        if (input.type === "hidden" || input.style.display === "none" || input.offsetWidth === 0) return;

        const name = (input.name || "").toLowerCase();
        const id = (input.id || "").toLowerCase();
        const placeholder = (input.placeholder || "").toLowerCase();
        
        let labelText = "";
        if (input.labels && input.labels.length) {
          labelText = Array.from(input.labels).map(l => l.textContent).join(" ").toLowerCase();
        } else {
          const parentLabel = input.closest("label");
          if (parentLabel) {
            labelText = parentLabel.textContent.toLowerCase();
          }
        }

        const matchString = `${name} ${id} ${placeholder} ${labelText}`;

        if (payload.cf && (matchString.includes("codice fiscale") || matchString.includes("cf") || matchString.includes("codicefiscale") || name.includes("taxcode"))) {
          setInputValue(input, payload.cf);
          filledCount++;
        }
        else if (payload.clientName && (matchString.includes("cognome") || matchString.includes("nome") || matchString.includes("cliente") || matchString.includes("contribuente") || matchString.includes("denominazione") || matchString.includes("ragione sociale"))) {
          if (matchString.includes("cognome") && !matchString.includes("nome")) {
            const parts = payload.clientName.split(" ");
            setInputValue(input, parts[0]);
          } else if (matchString.includes("nome") && !matchString.includes("cognome")) {
            const parts = payload.clientName.split(" ");
            setInputValue(input, parts.slice(1).join(" ") || parts[0]);
          } else {
            setInputValue(input, payload.clientName);
          }
          filledCount++;
        }
        else if (payload.amount && (matchString.includes("importo") || matchString.includes("saldo") || matchString.includes("euro") || matchString.includes("da versare") || name.includes("amount") || name.includes("total"))) {
          if (input.type === "number") {
            setInputValue(input, payload.amount);
          } else {
            setInputValue(input, payload.amount.toString().replace(".", ","));
          }
          filledCount++;
        }
      });

      if (filledCount > 0) {
        sendResponse({ success: true, filledCount });
      } else {
        sendResponse({ success: false, error: "Nessun campo F24 riconosciuto trovato nella pagina corrente." });
      }
    } catch (e) {
      sendResponse({ success: false, error: e.message });
    }
  }
  return true;
});

function setInputValue(input, value) {
  if (!input) return;
  input.focus();
  input.value = value;
  input.dispatchEvent(new Event("input", { bubbles: true }));
  input.dispatchEvent(new Event("change", { bubbles: true }));
  input.dispatchEvent(new Event("keyup", { bubbles: true }));
  input.blur();
}

// =========================================================================
// DROPPOINT LIVE INTEGRATION WIDGET
// =========================================================================
(function initDropPointIntegration() {
  const isDropPoint = location.hostname.includes("drop-point") || location.hostname.includes("droppoint") || location.hostname.includes("dropoint");
  if (!isDropPoint) return;

  function start() {
    console.log("Inizializzazione widget di integrazione DropPoint...");
    const body = document.body;
    if (!body) {
      setTimeout(start, 100);
      return;
    }



    // Shadow DOM Container Injection
    const container = document.createElement("div");
    container.id = "gpp-ext-root";
    container.style.position = "fixed";
    container.style.bottom = "20px";
    container.style.right = "20px";
    container.style.zIndex = "2147483647"; // Max z-index
    body.appendChild(container);

    // Sandbox Parser Iframe Injection
    const parserIframe = document.createElement("iframe");
    parserIframe.src = chrome.runtime.getURL("f24-parser.html");
    parserIframe.style.display = "none";
    parserIframe.id = "gpp-parser-iframe";
    body.appendChild(parserIframe);

    const shadow = container.attachShadow({ mode: "open" });

  // Shadow DOM structure
  shadow.innerHTML = `
    <style>
      .card {
        font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
        width: 320px;
        background: rgba(255, 255, 255, 0.98);
        backdrop-filter: blur(10px);
        border: 1px solid rgba(37, 95, 159, 0.2);
        box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
        border-radius: 12px;
        padding: 16px;
        box-sizing: border-box;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        display: flex;
        flex-direction: column;
        gap: 10px;
      }
      .card.collapsed {
        width: 48px;
        height: 48px;
        padding: 0;
        border-radius: 50%;
        justify-content: center;
        align-items: center;
        overflow: hidden;
        cursor: pointer;
        background: #255f9f;
        color: #fff;
        display: flex;
        box-shadow: 0 4px 15px rgba(37, 95, 159, 0.4);
      }
      .card.collapsed:hover {
        transform: scale(1.06);
        background: #1d4d82;
      }
      .card.collapsed .full-ui {
        display: none;
      }
      .card.collapsed .collapsed-ui {
        display: block;
      }
      .collapsed-ui {
        font-size: 20px;
        font-weight: bold;
        display: none;
      }
      .full-ui {
        display: flex;
        flex-direction: column;
        gap: 10px;
        width: 100%;
      }
      .header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        border-bottom: 1px solid #e2e8f0;
        padding-bottom: 6px;
        margin-bottom: 2px;
      }
      .header h4 {
        margin: 0;
        font-size: 13px;
        color: #255f9f;
        font-weight: 800;
        text-transform: uppercase;
        letter-spacing: 0.5px;
      }
      .close-btn {
        background: none;
        border: none;
        font-size: 16px;
        cursor: pointer;
        color: #94a3b8;
        padding: 0;
        line-height: 1;
      }
      .close-btn:hover {
        color: #475569;
      }
      .form-group {
        display: flex;
        flex-direction: column;
        gap: 4px;
      }
      .form-group label {
        font-size: 10px;
        font-weight: 700;
        color: #64748b;
        text-transform: uppercase;
        letter-spacing: 0.3px;
      }
      .form-group input, .form-group select {
        padding: 7px 10px;
        border: 1px solid #cbd5e1;
        border-radius: 6px;
        font-size: 13px;
        background: #fff;
        box-sizing: border-box;
        width: 100%;
        color: #1e293b;
      }
      .form-group input:focus, .form-group select:focus {
        border-color: #255f9f;
        outline: none;
        box-shadow: 0 0 0 2px rgba(37, 95, 159, 0.1);
      }
      .row {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 8px;
      }
      .btn-submit {
        background: #255f9f;
        color: #fff;
        border: none;
        border-radius: 6px;
        padding: 9px;
        font-weight: 700;
        cursor: pointer;
        font-size: 12px;
        transition: all 0.2s;
        width: 100%;
        margin-top: 4px;
      }
      .btn-submit:hover {
        background: #1d4d82;
      }
      .btn-submit:disabled {
        background: #94a3b8;
        cursor: not-allowed;
      }
      .btn-scrape {
        background: #f59e0b;
        color: #fff;
        border: none;
        border-radius: 6px;
        padding: 9px;
        font-weight: 700;
        cursor: pointer;
        font-size: 12px;
        transition: all 0.2s;
        width: 100%;
        margin-top: 4px;
      }
      .btn-scrape:hover {
        background: #d97706;
      }
      .btn-scan {
        background: #10b981;
        color: #fff;
        border: none;
        border-radius: 6px;
        padding: 10px;
        font-weight: 700;
        cursor: pointer;
        font-size: 12px;
        transition: all 0.2s;
        width: 100%;
        margin-top: 4px;
        margin-bottom: 4px;
        text-transform: uppercase;
        letter-spacing: 0.5px;
        box-shadow: 0 4px 10px rgba(16, 185, 129, 0.2);
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
      }
      .btn-scan:hover {
        background: #059669;
        transform: translateY(-1px);
        box-shadow: 0 6px 15px rgba(16, 185, 129, 0.3);
      }
      .btn-scan:active {
        transform: translateY(0);
      }
      .f24-dropzone {
        border: 2px dashed rgba(37, 95, 159, 0.4);
        background: #f8fafc;
        border-radius: 8px;
        padding: 12px;
        text-align: center;
        cursor: pointer;
        transition: all 0.2s ease-in-out;
        margin-bottom: 8px;
      }
      .f24-dropzone:hover {
        background: #eff6ff;
        border-color: #255f9f;
        transform: translateY(-1px);
      }
      .dropzone-text span {
        display: block;
        font-size: 11px;
        font-weight: bold;
        color: #1e293b;
      }
      .dropzone-text small {
        display: block;
        font-size: 9px;
        color: #64748b;
        margin-top: 2px;
      }
      .progress-bar {
        background: #e2e8f0;
        border-radius: 6px;
        height: 18px;
        position: relative;
        overflow: hidden;
        margin-bottom: 8px;
        text-align: center;
      }
      .progress-fill {
        background: #255f9f;
        height: 100%;
        width: 0%;
        transition: width 0.2s ease;
        position: absolute;
        top: 0;
        left: 0;
      }
      .progress-text {
        position: relative;
        font-size: 10px;
        font-weight: bold;
        color: #1e293b;
        line-height: 18px;
        z-index: 2;
      }
      .hidden {
        display: none !important;
      }
      .status-banner {
        font-size: 11px;
        text-align: center;
        font-weight: 700;
        padding: 6px;
        border-radius: 6px;
        margin-top: 4px;
        display: none;
      }
      .status-banner.success {
        display: block;
        background: #d1fae5;
        color: #065f46;
        border: 1px solid #a7f3d0;
      }
      .status-banner.error {
        display: block;
        background: #fee2e2;
        color: #991b1b;
        border: 1px solid #fecaca;
      }
      .status-banner.info {
        display: block;
        background: #eff6ff;
        color: #1e40af;
        border: 1px solid #bfdbfe;
      }
    </style>
    
    <div id="widgetCard" class="card collapsed">
      <div class="collapsed-ui">DP</div>
      
      <div class="full-ui">
        <div class="header">
          <h4>DropPoint Link</h4>
          <button type="button" id="closeBtn" class="close-btn">&times;</button>
        </div>
        
        <div class="form-group">
          <label>Tipo Servizio</label>
          <select id="opType">
            <option value="Bollettino postale">Bollettino postale</option>
            <option value="PagoPA">PagoPA</option>
            <option value="MAV / RAV">MAV / RAV</option>
            <option value="Pagamento F24">Pagamento F24</option>
            <option value="Bonifico ordinario">Bonifico ordinario</option>
            <option value="Bonifico immediato">Bonifico immediato</option>
            <option value="Bollo auto">Bollo auto</option>
            <option value="Ricarica telefonica">Ricarica telefonica</option>
            <option value="Servizi finanziari">Servizi finanziari</option>
            <option value="Altro servizio DropPoint">Altro servizio DropPoint</option>
          </select>
        </div>

        <!-- Drag & Drop F24 Scanner zone (only visible for F24 payments) -->
        <div id="extF24Dropzone" class="f24-dropzone hidden">
          <div class="dropzone-text">
            <span>📄 Trascina qui l'F24 scansionato o Clicca</span>
            <small>Lettura automatica ed autocompilazione istantanea</small>
          </div>
          <input type="file" id="extF24File" accept="application/pdf,image/*" style="display:none;">
        </div>
        <button type="button" id="scanF24Btn" class="btn-scan hidden">SCAN F24</button>
        <div id="extF24Progress" class="progress-bar hidden">
          <div class="progress-fill" style="width: 0%"></div>
          <span class="progress-text">Lettura in corso...</span>
        </div>
        
        <div class="form-group">
          <label>Cliente / Nominativo</label>
          <input type="text" id="customerName" placeholder="Nome o Ragione Sociale">
        </div>
        
        <div class="form-group">
          <label>Riferimento / Transazione</label>
          <input type="text" id="reference" placeholder="Codice o ID pagamento">
        </div>
        
        <div class="row">
          <div class="form-group">
            <label>Importo (€)</label>
            <input type="number" id="revenue" step="0.01" value="0.00">
          </div>
          <div class="form-group">
            <label>Costo DropPoint (€)</label>
            <input type="number" id="cost" step="0.01" value="0.00">
          </div>
        </div>
        
        <div class="row">
          <div class="form-group">
            <label>Commissione Extra (€)</label>
            <input type="number" id="fee" step="0.01" value="0.00">
          </div>
          <div class="form-group">
            <label>Stato</label>
            <select id="status">
              <option value="Completata">Completata</option>
              <option value="In attesa">In attesa</option>
              <option value="Sospesa">Sospesa</option>
            </select>
          </div>
        </div>
        
        <div class="form-group">
          <label>Note aggiuntive</label>
          <input type="text" id="notes" placeholder="Rilevato da estensione">
        </div>

        <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px;">
          <button type="button" id="scrapeBtn" class="btn-scrape">Rileva Dati</button>
          <button type="button" id="submitBtn" class="btn-submit">Registra</button>
        </div>
        
        <div id="statusBanner" class="status-banner"></div>
      </div>
    </div>
  `;

  // Elements references
  const widgetCard = shadow.getElementById("widgetCard");
  const closeBtn = shadow.getElementById("closeBtn");
  const scrapeBtn = shadow.getElementById("scrapeBtn");
  const submitBtn = shadow.getElementById("submitBtn");
  const statusBanner = shadow.getElementById("statusBanner");

  // Inputs references
  const opType = shadow.getElementById("opType");
  const customerName = shadow.getElementById("customerName");
  const reference = shadow.getElementById("reference");
  const revenue = shadow.getElementById("revenue");
  const cost = shadow.getElementById("cost");
  const fee = shadow.getElementById("fee");
  const statusSelect = shadow.getElementById("status");
  const notes = shadow.getElementById("notes");

  // F24 File Upload references
  const dropzone = shadow.getElementById("extF24Dropzone");
  const fileInput = shadow.getElementById("extF24File");
  const scanF24Btn = shadow.getElementById("scanF24Btn");
  const progressBar = shadow.getElementById("extF24Progress");
  const progressFill = shadow.querySelector(".progress-fill");
  const progressText = shadow.querySelector(".progress-text");

  // Toggle F24 zone visibility based on service type
  function handleWidgetTypeChange() {
    const isF24 = opType.value === "Pagamento F24";
    if (isF24) {
      dropzone.classList.remove("hidden");
      scanF24Btn.classList.remove("hidden");
    } else {
      dropzone.classList.add("hidden");
      scanF24Btn.classList.add("hidden");
      progressBar.classList.add("hidden");
    }
  }

  // Set worker source for PDFJS locally from extension resources
  if (typeof pdfjsLib !== 'undefined') {
    pdfjsLib.GlobalWorkerOptions.workerSrc = chrome.runtime.getURL("lib/pdf.worker.js");
  }

  // F24 File Handler using Sandbox Iframe
  function handleFile(file) {
    progressBar.classList.remove("hidden");
    progressFill.style.width = "0%";
    progressText.textContent = "Caricamento file...";

    const reader = new FileReader();
    reader.onload = function() {
      try {
        const iframe = document.getElementById("gpp-parser-iframe");
        if (!iframe) {
          throw new Error("Sandbox di scansione non pronta.");
        }
        
        progressText.textContent = "Invio alla sandbox...";
        iframe.contentWindow.postMessage({
          action: "parse-f24-file",
          fileData: this.result,
          fileName: file.name,
          fileType: file.type
        }, "*");
      } catch (err) {
        console.error("Errore avvio parsing:", err);
        progressBar.classList.add("hidden");
        showBanner("error", "Errore: " + err.message);
        setTimeout(hideBanner, 4000);
      }
    };
    reader.onerror = function() {
      progressBar.classList.add("hidden");
      showBanner("error", "Errore lettura file locale.");
      setTimeout(hideBanner, 3000);
    };
    reader.readAsDataURL(file);
  }

  // Listen for sandbox events
  window.addEventListener("message", (event) => {
    if (!event.data) return;

    if (event.data.action === "f24-parse-progress") {
      progressFill.style.width = `${event.data.progress}%`;
      progressText.textContent = `Scansione: ${event.data.progress}%`;
    } 
    else if (event.data.action === "f24-parse-result") {
      progressBar.classList.add("hidden");
      
      if (event.data.success) {
        const parsed = event.data.data;
        console.log("F24 sandboxed parse result:", parsed);

        customerName.value = `${parsed.cognome} ${parsed.nome}`.trim();
        reference.value = parsed.cf;
        revenue.value = parsed.amount.toFixed(2);
        notes.value = `F24 auto-rilevato da scanner. ${parsed.erario.length} tributi.`;
        opType.value = "Pagamento F24";

        fillDropPointF24(parsed);

        showBanner("success", "F24 scansionato e compilato!");
        setTimeout(hideBanner, 2000);
      } else {
        console.error("Scansione fallita nella sandbox:", event.data.error);
        showBanner("error", "Errore scansione: " + event.data.error);
        setTimeout(hideBanner, 4000);
      }
    }
  });

  // Local PDF parser
  function parsePdfTextLocal(arrayBuffer) {
    return new Promise(async (resolve, reject) => {
      try {
        const typedarray = new Uint8Array(arrayBuffer);
        const loadingTask = pdfjsLib.getDocument({ data: typedarray });
        const pdf = await loadingTask.promise;
        let textContent = "";
        for (let i = 1; i <= pdf.numPages; i++) {
          const page = await pdf.getPage(i);
          const content = await page.getTextContent();
          const pageText = content.items.map(item => item.str).join(" ");
          textContent += pageText + "\n";
        }
        resolve(textContent);
      } catch (err) {
        reject(err);
      }
    });
  }

  // Local PDF to Canvas renderer for OCR
  function renderPdfToCanvasLocal(arrayBuffer) {
    return new Promise(async (resolve, reject) => {
      try {
        const typedarray = new Uint8Array(arrayBuffer);
        const loadingTask = pdfjsLib.getDocument({ data: typedarray });
        const pdf = await loadingTask.promise;
        const page = await pdf.getPage(1);
        const viewport = page.getViewport({ scale: 1.5 });
        const canvas = document.createElement("canvas");
        canvas.width = viewport.width;
        canvas.height = viewport.height;
        const context = canvas.getContext("2d");
        await page.render({ canvasContext: context, viewport: viewport }).promise;
        resolve(canvas);
      } catch (err) {
        reject(err);
      }
    });
  }

  // Local OCR runner using Tesseract
  function runOcrLocal(fileOrCanvas) {
    return new Promise((resolve, reject) => {
      if (typeof Tesseract === 'undefined') {
        return reject(new Error("Libreria OCR Tesseract non caricata."));
      }
      Tesseract.recognize(
        fileOrCanvas,
        'ita',
        { logger: m => {
            if (m.status === "recognizing") {
              progressFill.style.width = `${Math.round(m.progress * 100)}%`;
              progressText.textContent = `Analisi in corso: ${Math.round(m.progress * 100)}%`;
            }
          }
        }
      ).then(({ data: { text } }) => {
        resolve(text);
      }).catch(err => {
        reject(err);
      });
    });
  }

  // Helper to dynamically locate and fill the F24 fields on the DropPoint portal
  function fillDropPointF24(data) {
    console.log("Inizio compilazione modulo DropPoint F24 con i dati:", data);

    // 1. Codice Fiscale (checks if the form split it into 16 separate inputs or single input)
    const cfInputs = Array.from(document.querySelectorAll('input')).filter(i => {
      const name = (i.name || '').toLowerCase();
      const id = (i.id || '').toLowerCase();
      const parentText = i.closest('div') ? i.closest('div').innerText.toLowerCase() : '';
      return (parentText.includes("codice fiscale") || name.includes("cf") || id.includes("cf") || name.includes("codfisc") || id.includes("codfisc")) && 
             (i.maxLength === 1 || i.getAttribute('maxlength') === '1');
    });

    if (cfInputs.length === 16 && data.cf && data.cf.length === 16) {
      cfInputs.forEach((input, index) => {
        setInputValue(input, data.cf[index]);
      });
    } else {
      const cfInput = Array.from(document.querySelectorAll('input')).find(i => {
        const name = (i.name || '').toLowerCase();
        const id = (i.id || '').toLowerCase();
        const placeholder = (i.placeholder || '').toLowerCase();
        const parentText = i.closest('label') ? i.closest('label').innerText.toLowerCase() : '';
        return name.includes("cf") || name.includes("fiscale") || id.includes("cf") || id.includes("fiscale") || 
               placeholder.includes("codice fiscale") || parentText.includes("codice fiscale");
      });
      if (cfInput && data.cf) {
        setInputValue(cfInput, data.cf);
      }
    }

    // 1b. Anno non coincidente
    if (data.annoNonCoincidente !== undefined) {
      const coincCheckbox = Array.from(document.querySelectorAll('input[type="checkbox"]')).find(i => {
        const parentText = i.closest('div') ? i.closest('div').innerText.toLowerCase() : '';
        const name = (i.name || '').toLowerCase();
        const id = (i.id || '').toLowerCase();
        return parentText.includes("coincidente") || name.includes("coincidente") || id.includes("coincidente");
      });
      if (coincCheckbox) {
        coincCheckbox.checked = !!data.annoNonCoincidente;
        coincCheckbox.dispatchEvent(new Event("change", { bubbles: true }));
      }
    }

    // 2. Cognome
    const cognomeInput = Array.from(document.querySelectorAll('input')).find(i => {
      const name = (i.name || '').toLowerCase();
      const id = (i.id || '').toLowerCase();
      const placeholder = (i.placeholder || '').toLowerCase();
      const parentText = i.closest('div') ? i.closest('div').innerText.toLowerCase() : '';
      return name.includes("cognome") || id.includes("cognome") || placeholder.includes("cognome") || parentText.includes("cognome");
    });
    if (cognomeInput && data.cognome) {
      setInputValue(cognomeInput, data.cognome);
    }

    // 3. Nome
    const nomeInput = Array.from(document.querySelectorAll('input')).find(i => {
      const name = (i.name || '').toLowerCase();
      const id = (i.id || '').toLowerCase();
      const placeholder = (i.placeholder || '').toLowerCase();
      const parentText = i.closest('div') ? i.closest('div').innerText.toLowerCase() : '';
      return (name.includes("nome") || id.includes("nome") || placeholder.includes("nome") || parentText.includes("nome")) && 
             !(name.includes("cognome") || id.includes("cognome"));
    });
    if (nomeInput && data.nome) {
      setInputValue(nomeInput, data.nome);
    }

    // 4. Data di nascita
    const birthDateInput = Array.from(document.querySelectorAll('input')).find(i => {
      const name = (i.name || '').toLowerCase();
      const id = (i.id || '').toLowerCase();
      const placeholder = (i.placeholder || '').toLowerCase();
      const parentText = i.closest('div') ? i.closest('div').innerText.toLowerCase() : '';
      return name.includes("nascita") && (name.includes("data") || id.includes("data") || placeholder.includes("data") || parentText.includes("data"));
    });
    if (birthDateInput && data.dataNascita) {
      setInputValue(birthDateInput, data.dataNascita);
    }

    // 5. Sesso (M / F)
    if (data.sesso) {
      const sessoRadios = Array.from(document.querySelectorAll('input[type="radio"]')).filter(i => {
        const parentText = i.closest('div') ? i.closest('div').innerText.toLowerCase() : '';
        return parentText.includes("sesso") || i.name.toLowerCase().includes("sesso");
      });
      if (sessoRadios.length) {
        const targetVal = data.sesso.toUpperCase();
        sessoRadios.forEach(radio => {
          const labelText = radio.closest('label') ? radio.closest('label').innerText.toUpperCase() : '';
          const value = (radio.value || '').toUpperCase();
          if (labelText.includes(targetVal) || value.includes(targetVal)) {
            radio.checked = true;
            radio.dispatchEvent(new Event("change", { bubbles: true }));
          }
        });
      } else {
        const sessoSelect = Array.from(document.querySelectorAll('select')).find(s => s.name.toLowerCase().includes("sesso") || s.id.toLowerCase().includes("sesso"));
        if (sessoSelect) {
          setInputValue(sessoSelect, data.sesso);
        }
      }
    }

    // 6. Comune di nascita
    const comuneInput = Array.from(document.querySelectorAll('input')).find(i => {
      const name = (i.name || '').toLowerCase();
      const id = (i.id || '').toLowerCase();
      const parentText = i.closest('div') ? i.closest('div').innerText.toLowerCase() : '';
      return (name.includes("comune") || id.includes("comune") || parentText.includes("comune")) && 
             (name.includes("nascita") || id.includes("nascita") || parentText.includes("nascita")) &&
             !parentText.includes("domicilio");
    });
    if (comuneInput && data.comuneNascita) {
      setInputValue(comuneInput, data.comuneNascita);
    }

    // 7. Provincia di nascita
    const provInput = Array.from(document.querySelectorAll('input')).find(i => {
      const name = (i.name || '').toLowerCase();
      const id = (i.id || '').toLowerCase();
      const parentText = i.closest('div') ? i.closest('div').innerText.toLowerCase() : '';
      return (name.includes("provincia") || name.includes("prov") || id.includes("provincia") || id.includes("prov") || parentText.includes("provincia")) && 
             (name.includes("nascita") || id.includes("nascita") || parentText.includes("nascita")) &&
             !parentText.includes("domicilio");
    });
    if (provInput && data.provNascita) {
      setInputValue(provInput, data.provNascita);
    }

    // 8. Domicilio fiscale Comune
    const domComuneInput = Array.from(document.querySelectorAll('input')).find(i => {
      const name = (i.name || '').toLowerCase();
      const id = (i.id || '').toLowerCase();
      const placeholder = (i.placeholder || '').toLowerCase();
      const parentText = i.closest('div') ? i.closest('div').innerText.toLowerCase() : '';
      return (name.includes("domicilio") || id.includes("domicilio") || placeholder.includes("domicilio") || parentText.includes("domicilio")) &&
             (name.includes("comune") || id.includes("comune") || placeholder.includes("comune") || parentText.includes("comune"));
    });
    if (domComuneInput && data.domicilioComune) {
      setInputValue(domComuneInput, data.domicilioComune);
    }

    // 9. Domicilio fiscale Provincia
    const domProvInput = Array.from(document.querySelectorAll('input')).find(i => {
      const name = (i.name || '').toLowerCase();
      const id = (i.id || '').toLowerCase();
      const placeholder = (i.placeholder || '').toLowerCase();
      const parentText = i.closest('div') ? i.closest('div').innerText.toLowerCase() : '';
      return (name.includes("domicilio") || id.includes("domicilio") || placeholder.includes("domicilio") || parentText.includes("domicilio")) &&
             (name.includes("provincia") || name.includes("prov") || id.includes("provincia") || id.includes("prov") || parentText.includes("provincia")) &&
             !name.includes("nascita") && !id.includes("nascita");
    });
    if (domProvInput && data.domicilioProv) {
      setInputValue(domProvInput, data.domicilioProv);
    }

    // 10. Via
    const viaInput = Array.from(document.querySelectorAll('input')).find(i => {
      const name = (i.name || '').toLowerCase();
      const id = (i.id || '').toLowerCase();
      const placeholder = (i.placeholder || '').toLowerCase();
      const parentText = i.closest('div') ? i.closest('div').innerText.toLowerCase() : '';
      return (name.includes("via") || name.includes("indirizzo") || id.includes("via") || id.includes("indirizzo") || 
              placeholder.includes("via") || placeholder.includes("indirizzo") || parentText.includes("via") || parentText.includes("indirizzo")) &&
             !parentText.includes("nascita");
    });
    if (viaInput && data.domicilioVia) {
      setInputValue(viaInput, data.domicilioVia);
    }

    // 11. Numero Civico
    const civicoInput = Array.from(document.querySelectorAll('input')).find(i => {
      const name = (i.name || '').toLowerCase();
      const id = (i.id || '').toLowerCase();
      const placeholder = (i.placeholder || '').toLowerCase();
      const parentText = i.closest('div') ? i.closest('div').innerText.toLowerCase() : '';
      return (name.includes("civico") || name.includes("numero") || id.includes("civico") || id.includes("numero") || 
              placeholder.includes("civico") || placeholder.includes("numero") || parentText.includes("civico") || parentText.includes("numero")) &&
             !parentText.includes("nascita");
    });
    if (civicoInput && data.domicilioCivico) {
      setInputValue(civicoInput, data.domicilioCivico);
    }

    // 12. Sezioni Tributi (Erario, INPS, Regioni, IMU, Altri)
    if (data.erario && data.erario.length > 0) {
      const headings = Array.from(document.querySelectorAll('h1, h2, h3, h4, div, span'));
      
      const sectionsConfig = {
        "ERARIO": {
          keywords: ["SEZIONE ERARIO"],
          rowSize: 5,
          mapRow: (inputs, rowData, startIdx) => {
            if (inputs[startIdx]) setInputValue(inputs[startIdx], rowData.tributo);
            if (inputs[startIdx + 1]) setInputValue(inputs[startIdx + 1], rowData.rateazione);
            if (inputs[startIdx + 2]) setInputValue(inputs[startIdx + 2], rowData.anno);
            if (inputs[startIdx + 3]) {
              const debInput = inputs[startIdx + 3];
              const val = typeof rowData.debito === 'number' ? rowData.debito : parseFloat(rowData.debito || 0);
              setInputValue(debInput, debInput.type === "number" ? val : val.toFixed(2).replace(".", ","));
            }
            if (inputs[startIdx + 4]) {
              const credInput = inputs[startIdx + 4];
              const val = typeof rowData.credito === 'number' ? rowData.credito : parseFloat(rowData.credito || 0);
              setInputValue(credInput, credInput.type === "number" ? val : val.toFixed(2).replace(".", ","));
            }
          }
        },
        "INPS": {
          keywords: ["SEZIONE INPS", "INPS"],
          rowSize: 7,
          mapRow: (inputs, rowData, startIdx) => {
            if (inputs[startIdx]) setInputValue(inputs[startIdx], rowData.sede);
            if (inputs[startIdx + 1]) setInputValue(inputs[startIdx + 1], rowData.tributo); // causale
            if (inputs[startIdx + 2]) setInputValue(inputs[startIdx + 2], rowData.matricola);
            if (inputs[startIdx + 3]) setInputValue(inputs[startIdx + 3], rowData.periodoDa);
            if (inputs[startIdx + 4]) setInputValue(inputs[startIdx + 4], rowData.periodoA);
            if (inputs[startIdx + 5]) {
              const debInput = inputs[startIdx + 5];
              const val = typeof rowData.debito === 'number' ? rowData.debito : parseFloat(rowData.debito || 0);
              setInputValue(debInput, debInput.type === "number" ? val : val.toFixed(2).replace(".", ","));
            }
            if (inputs[startIdx + 6]) {
              const credInput = inputs[startIdx + 6];
              const val = typeof rowData.credito === 'number' ? rowData.credito : parseFloat(rowData.credito || 0);
              setInputValue(credInput, credInput.type === "number" ? val : val.toFixed(2).replace(".", ","));
            }
          }
        },
        "REGIONI": {
          keywords: ["SEZIONE REGIONI", "REGIONI"],
          rowSize: 6,
          mapRow: (inputs, rowData, startIdx) => {
            if (inputs[startIdx]) setInputValue(inputs[startIdx], rowData.regione);
            if (inputs[startIdx + 1]) setInputValue(inputs[startIdx + 1], rowData.tributo);
            if (inputs[startIdx + 2]) setInputValue(inputs[startIdx + 2], rowData.rateazione);
            if (inputs[startIdx + 3]) setInputValue(inputs[startIdx + 3], rowData.anno);
            if (inputs[startIdx + 4]) {
              const debInput = inputs[startIdx + 4];
              const val = typeof rowData.debito === 'number' ? rowData.debito : parseFloat(rowData.debito || 0);
              setInputValue(debInput, debInput.type === "number" ? val : val.toFixed(2).replace(".", ","));
            }
            if (inputs[startIdx + 5]) {
              const credInput = inputs[startIdx + 5];
              const val = typeof rowData.credito === 'number' ? rowData.credito : parseFloat(rowData.credito || 0);
              setInputValue(credInput, credInput.type === "number" ? val : val.toFixed(2).replace(".", ","));
            }
          }
        },
        "IMU": {
          keywords: ["IMU E ALTRI TRIBUTI LOCALI", "IMU E ALTRI TRIBUTI", "SEZIONE IMU", "TRIBUTI LOCALI"],
          rowSize: 12,
          mapRow: (inputs, rowData, startIdx) => {
            if (inputs[startIdx]) setInputValue(inputs[startIdx], rowData.ente);
            
            // Checkboxes
            const ravv = inputs[startIdx + 1];
            if (ravv && ravv.type === 'checkbox') { ravv.checked = rowData.ravv === "X"; ravv.dispatchEvent(new Event('change', { bubbles: true })); }
            const acc = inputs[startIdx + 2];
            if (acc && acc.type === 'checkbox') { acc.checked = rowData.acc === "X"; acc.dispatchEvent(new Event('change', { bubbles: true })); }
            const sal = inputs[startIdx + 3];
            if (sal && sal.type === 'checkbox') { sal.checked = rowData.sal === "X"; sal.dispatchEvent(new Event('change', { bubbles: true })); }
            const immob = inputs[startIdx + 4];
            if (immob && immob.type === 'checkbox') { immob.checked = rowData.immob === "X"; immob.dispatchEvent(new Event('change', { bubbles: true })); }
            
            if (inputs[startIdx + 5]) setInputValue(inputs[startIdx + 5], rowData.immobili);
            if (inputs[startIdx + 6]) setInputValue(inputs[startIdx + 6], rowData.tributo);
            if (inputs[startIdx + 7]) setInputValue(inputs[startIdx + 7], rowData.rateazione);
            if (inputs[startIdx + 8]) setInputValue(inputs[startIdx + 8], rowData.anno);
            if (inputs[startIdx + 9]) setInputValue(inputs[startIdx + 9], rowData.detrazione);
            if (inputs[startIdx + 10]) {
              const debInput = inputs[startIdx + 10];
              const val = typeof rowData.debito === 'number' ? rowData.debito : parseFloat(rowData.debito || 0);
              setInputValue(debInput, debInput.type === "number" ? val : val.toFixed(2).replace(".", ","));
            }
            if (inputs[startIdx + 11]) {
              const credInput = inputs[startIdx + 11];
              const val = typeof rowData.credito === 'number' ? rowData.credito : parseFloat(rowData.credito || 0);
              setInputValue(credInput, credInput.type === "number" ? val : val.toFixed(2).replace(".", ","));
            }
          }
        },
        "INAIL": {
          keywords: ["INAIL", "SEZIONE INAIL"],
          rowSize: 7,
          mapRow: (inputs, rowData, startIdx) => {
            if (inputs[startIdx]) setInputValue(inputs[startIdx], rowData.sede);
            if (inputs[startIdx + 1]) setInputValue(inputs[startIdx + 1], rowData.ditta);
            if (inputs[startIdx + 2]) setInputValue(inputs[startIdx + 2], rowData.cc);
            if (inputs[startIdx + 3]) setInputValue(inputs[startIdx + 3], rowData.riferimento);
            if (inputs[startIdx + 4]) setInputValue(inputs[startIdx + 4], rowData.tributo); // causale
            if (inputs[startIdx + 5]) {
              const debInput = inputs[startIdx + 5];
              const val = typeof rowData.debito === 'number' ? rowData.debito : parseFloat(rowData.debito || 0);
              setInputValue(debInput, debInput.type === "number" ? val : val.toFixed(2).replace(".", ","));
            }
            if (inputs[startIdx + 6]) {
              const credInput = inputs[startIdx + 6];
              const val = typeof rowData.credito === 'number' ? rowData.credito : parseFloat(rowData.credito || 0);
              setInputValue(credInput, credInput.type === "number" ? val : val.toFixed(2).replace(".", ","));
            }
          }
        },
        "ALTRI": {
          keywords: ["ALTRI ENTI PREVIDENZIALI", "ALTRI ENTI", "ALTRIENTI"],
          rowSize: 8,
          mapRow: (inputs, rowData, startIdx) => {
            if (inputs[startIdx]) setInputValue(inputs[startIdx], rowData.ente);
            if (inputs[startIdx + 1]) setInputValue(inputs[startIdx + 1], rowData.sede);
            if (inputs[startIdx + 2]) setInputValue(inputs[startIdx + 2], rowData.tributo); // causale
            if (inputs[startIdx + 3]) setInputValue(inputs[startIdx + 3], rowData.posizione);
            if (inputs[startIdx + 4]) setInputValue(inputs[startIdx + 4], rowData.periodoDa);
            if (inputs[startIdx + 5]) setInputValue(inputs[startIdx + 5], rowData.periodoA);
            if (inputs[startIdx + 6]) {
              const debInput = inputs[startIdx + 6];
              const val = typeof rowData.debito === 'number' ? rowData.debito : parseFloat(rowData.debito || 0);
              setInputValue(debInput, debInput.type === "number" ? val : val.toFixed(2).replace(".", ","));
            }
            if (inputs[startIdx + 7]) {
              const credInput = inputs[startIdx + 7];
              const val = typeof rowData.credito === 'number' ? rowData.credito : parseFloat(rowData.credito || 0);
              setInputValue(credInput, credInput.type === "number" ? val : val.toFixed(2).replace(".", ","));
            }
          }
        }
      };

      // Raggruppa per sezione
      const sectionsData = {};
      data.erario.forEach(item => {
        const sec = (item.sezione || "ERARIO").toUpperCase();
        if (!sectionsData[sec]) sectionsData[sec] = [];
        sectionsData[sec].push(item);
      });

      // Esegui il popolamento
      for (const [secName, secItems] of Object.entries(sectionsData)) {
        const config = sectionsConfig[secName] || sectionsConfig["ERARIO"];
        
        // Trova l'header della sezione
        let sectionHeader = null;
        for (const kw of config.keywords) {
          for (const h of headings) {
            if (h.innerText && h.innerText.toUpperCase().includes(kw)) {
              sectionHeader = h;
              break;
            }
          }
          if (sectionHeader) break;
        }

        let sectionInputs = [];
        if (sectionHeader) {
          let container = sectionHeader.parentElement;
          for (let i = 0; i < 4; i++) {
            if (container && container.querySelectorAll('input').length > 0) {
              break;
            }
            if (container) container = container.parentElement;
          }
          if (container) {
            sectionInputs = Array.from(container.querySelectorAll('input')).filter(i => {
              return i.type !== 'hidden' && i.style.display !== 'none' && i.offsetWidth > 0;
            });
          }
        }

        if (sectionInputs.length >= config.rowSize) {
          for (let r = 0; r < secItems.length; r++) {
            const rowData = secItems[r];
            const startIdx = r * config.rowSize;
            if (startIdx < sectionInputs.length) {
              config.mapRow(sectionInputs, rowData, startIdx);
            }
          }
        } else if (secName === "ERARIO") {
          // Fallback ERARIO
          const allInputs = Array.from(document.querySelectorAll('input'));
          const tributi = allInputs.filter(i => i.placeholder.toLowerCase().includes("tributo") || i.name.toLowerCase().includes("tributo") || i.id.toLowerCase().includes("tributo"));
          const rateazioni = allInputs.filter(i => i.placeholder.toLowerCase().includes("rateazione") || i.placeholder.toLowerCase().includes("regione") || i.name.toLowerCase().includes("rateazione") || i.id.toLowerCase().includes("rateazione"));
          const anni = allInputs.filter(i => i.placeholder.toLowerCase().includes("anno") || i.name.toLowerCase().includes("anno") || i.id.toLowerCase().includes("anno"));
          const debiti = allInputs.filter(i => i.placeholder.toLowerCase().includes("debito") || i.placeholder.toLowerCase().includes("versati") || i.name.toLowerCase().includes("debito") || i.id.toLowerCase().includes("debito") || i.name.toLowerCase().includes("importo"));
          
          for (let r = 0; r < secItems.length; r++) {
            const rowData = secItems[r];
            if (tributi[r]) setInputValue(tributi[r], rowData.tributo);
            if (rateazioni[r]) setInputValue(rateazioni[r], rowData.rateazione);
            if (anni[r]) setInputValue(anni[r], rowData.anno);
            if (debiti[r]) {
              const val = typeof rowData.debito === 'number' ? rowData.debito : parseFloat(rowData.debito || 0);
              setInputValue(debiti[r], debiti[r].type === "number" ? val : val.toFixed(2).replace(".", ","));
            }
          }
        }
      }
    }
  }

  // Local Detailed F24 text parser (advanced token-based algorithm)
  function parseDetailedF24TextLocal(text) {
    const normalizedText = text.replace(/[ \t]+/g, "  ").toUpperCase();
    
    // 1. Codice Fiscale
    const cfRegex = /\b([A-Z]{6}[0-9LMNPQRSTUV]{2}[A-Z][0-9LMNPQRSTUV]{2}[A-Z][0-9LMNPQRSTUV]{3}[A-Z]|[0-9]{11})\b/i;
    const cfMatch = text.match(cfRegex);
    const cf = cfMatch ? cfMatch[1].toUpperCase() : "";

    // 2. Data di nascita
    const dateRegex = /\b(\d{2})[\/\-\.](\d{2})[\/\-\.](\d{4})\b/;
    const dateMatch = text.match(dateRegex);
    const dataNascita = dateMatch ? dateMatch[0] : "";

    // 3. Sesso
    let sesso = "";
    const sessoMatch = normalizedText.match(/\b(M|F)\b/);
    if (sessoMatch) {
      sesso = sessoMatch[1];
    }

    // 4. Cognome e Nome
    let cognome = "";
    let nome = "";
    const cognomeMatch = normalizedText.match(/COGNOME O RAGIONE SOCIALE\s*:\s*([^\n]+)/i) || normalizedText.match(/COGNOME O RAGIONE SOCIALE\s+([^\n]+)/i);
    if (cognomeMatch) {
      cognome = cognomeMatch[1].replace(/(?:DATI\s+ANAGRAFICI|NOME|CODICE\s+FISCALE)/g, "").trim().split(/  +/)[0];
    }
    const nomeMatch = normalizedText.match(/NOME\s*:\s*([^\n]+)/i) || normalizedText.match(/NOME\s+([^\n]+)/i);
    if (nomeMatch) {
      nome = nomeMatch[1].replace(/(?:DATI\s+ANAGRAFICI|COGNOME|DATA|COMUNE)/g, "").trim().split(/  +/)[0];
    }

    // Fallback for names if not matched individually
    let clientName = "";
    const nameLabels = [
      /(?:COGNOME,\s+NOME,\s+DENOMINAZIONE\s+O\s+RAGIONE\s+SOCIALE|DENOMINAZIONE\s+O\s+RAGIONE\s+SOCIALE|COGNOME\s+E\s+NOME\s+O\s+DENOMINAZIONE|COGNOME\s+E\s+NOME)/i
    ];
    for (const label of nameLabels) {
      const match = normalizedText.match(new RegExp(label.source + "\\s*([^\\n]+)", "i"));
      if (match && match[1]) {
        let candidate = match[1].trim();
        candidate = candidate.replace(/(?:DATI\s+ANAGRAFICI|CODICE\s+FISCALE|SESSO|COMUNE|DATA|PROVINCIA|DOMICILIO|STATO|FIRMA)/g, "").trim();
        candidate = candidate.split(/  +/)[0]; 
        if (candidate.length > 3) {
          clientName = candidate;
          break;
        }
      }
    }

    if (clientName && (!cognome || !nome)) {
      const parts = clientName.split(" ");
      if (parts.length >= 2) {
        cognome = parts[0];
        nome = parts.slice(1).join(" ");
      } else {
        cognome = clientName;
      }
    }

    // 5. Comune e Provincia di nascita
    let comuneNascita = "";
    let provNascita = "";
    const comuneMatch = normalizedText.match(/(?:COMUNE|STATO\s+ESTERO)\s+DI\s+NASCITA\s*([^\n]+)/i) || normalizedText.match(/NASCITA\s+([A-Z\s]+)\s+\b([A-Z]{2})\b/i);
    if (comuneMatch) {
      let candidate = comuneMatch[1].trim().split(/  +/)[0];
      candidate = candidate.replace(/(?:PROV|DOMICILIO|CODICE)/g, "").trim();
      comuneNascita = candidate;
    }
    const provMatch = normalizedText.match(/\b([A-Z]{2})\b\s*(?:DOMICILIO|CODICE FISCALE)/i) || normalizedText.match(/NASCITA\s+[A-Z\s]+\s+\b([A-Z]{2})\b/i);
    if (provMatch) {
      provNascita = provMatch[1];
    }

    // 6. Domicilio fiscale Comune e Provincia
    let domicilioComune = "";
    let domicilioProv = "";
    const domComuneMatch = normalizedText.match(/DOMICILIO\s+FISCALE\s+([A-Z\s\-]+)\s+\b([A-Z]{2})\b/i) || normalizedText.match(/COMUNE\s+DOMICILIO\s+FISCALE\s+([A-Z\s\-]+)\s+\b([A-Z]{2})\b/i);
    if (domComuneMatch) {
      domicilioComune = domComuneMatch[1].trim();
      domicilioProv = domComuneMatch[2].trim();
    }

    // 7. Via e Numero Civico del Domicilio Fiscale
    let domicilioVia = "";
    let domicilioCivico = "";
    const viaMatch = normalizedText.match(/VIA\s+E\s+NUMERO\s+CIVICO\s*([^\n]+)/i) || normalizedText.match(/DOMICILIO\s+FISCALE\s+-\s+VIA\s+([^\n]+)/i);
    if (viaMatch) {
      let streetPart = viaMatch[1].trim().split(/  +/)[0];
      const numMatch = streetPart.match(/\b(\d+)\b[^\d]*$/) || streetPart.match(/\bN\.\s*(\d+)\b/i) || streetPart.match(/\bCIVICO\s*(\d+)\b/i);
      if (numMatch) {
        domicilioCivico = numMatch[1];
        domicilioVia = streetPart.substring(0, streetPart.indexOf(numMatch[0])).trim();
        domicilioVia = domicilioVia.replace(/[\,\/\-\s]+$/, "");
      } else {
        domicilioVia = streetPart;
      }
    }

    // 8. Sezione Erario (advanced token parsing)
    const erario = [];
    const lines = normalizedText.split("\n");
    for (const line of lines) {
      const yearMatch = line.match(/\b(202\d|203\d)\b/);
      if (!yearMatch) continue;

      const year = yearMatch[1];
      const tokens = line.split(/\s+/).filter(Boolean);
      
      const tribute = tokens.find(t => /^\d{4}$/.test(t) && t !== year);
      if (!tribute) continue;

      let rateazione = "0000";
      const yearIdx = tokens.indexOf(year);
      const tribIdx = tokens.indexOf(tribute);
      if (tribIdx !== -1 && yearIdx !== -1 && yearIdx > tribIdx + 1) {
        const possibleRate = tokens[tribIdx + 1];
        if (/^\d{2,4}$/.test(possibleRate)) {
          rateazione = possibleRate.padStart(4, '0');
        }
      }

      const amounts = tokens.filter(t => /^\d+[\.,]\d{2}$/.test(t) || (/^\d+$/.test(t) && t.length <= 4 && tokens.indexOf(t) > yearIdx));
      let debito = 0;
      let credito = 0;

      if (amounts.length > 0) {
        const debStr = amounts[0].replace(/\./g, "").replace(",", ".");
        debito = parseFloat(debStr) || 0;
      }
      if (amounts.length > 1) {
        const credStr = amounts[1].replace(/\./g, "").replace(",", ".");
        credito = parseFloat(credStr) || 0;
      }

      if (tribute && debito > 0) {
        erario.push({
          tributo,
          rateazione,
          anno: year,
          debito,
          credito
        });
      }
    }

    // 9. Saldo Finale
    let amount = 0;
    const saldoLabels = [
      /(?:SALDO\s+FINALE|SALDO\s+DA\s+VERSARE|TOTALE\s+DEBITO|VERSAMENTO|SALDO|TOTALE)[^\d]*(\d{1,3}(?:\.\d{3})*,\d{2}|\d+,\d{2})/i,
      /(\d{1,3}(?:\.\d{3})*,\d{2}|\d+,\d{2})\b[^\d]*$/
    ];

    for (const label of saldoLabels) {
      const match = normalizedText.match(label);
      if (match && match[1]) {
        amount = parseFloat(match[1].replace(/\./g, "").replace(",", "."));
        if (amount > 0) break;
      }
    }

    return {
      cf,
      cognome,
      nome,
      dataNascita,
      sesso,
      comuneNascita,
      provNascita,
      domicilioComune,
      domicilioProv,
      domicilioVia,
      domicilioCivico,
      erario,
      amount
    };
  }

  // Dropzone click & drag handlers
  dropzone.addEventListener("click", () => {
    fileInput.click();
  });

  fileInput.addEventListener("change", (e) => {
    if (e.target.files.length) {
      handleFile(e.target.files[0]);
    }
  });

  dropzone.addEventListener("dragover", (e) => {
    e.preventDefault();
    dropzone.style.background = "#eff6ff";
    dropzone.style.borderColor = "#255f9f";
  });

  dropzone.addEventListener("dragleave", () => {
    dropzone.style.background = "#f8fafc";
    dropzone.style.borderColor = "rgba(37, 95, 159, 0.4)";
  });

  dropzone.addEventListener("drop", (e) => {
    e.preventDefault();
    dropzone.style.background = "#f8fafc";
    dropzone.style.borderColor = "rgba(37, 95, 159, 0.4)";
    if (e.dataTransfer.files.length) {
      handleFile(e.dataTransfer.files[0]);
    }
  });

  // Toggle Collapse/Expand
  widgetCard.addEventListener("click", (e) => {
    if (widgetCard.classList.contains("collapsed")) {
      widgetCard.classList.remove("collapsed");
      runScraping();
      handleWidgetTypeChange();
    }
  });

  closeBtn.addEventListener("click", (e) => {
    e.stopPropagation(); // Avoid re-opening
    widgetCard.classList.add("collapsed");
  });

  scrapeBtn.addEventListener("click", (e) => {
    e.stopPropagation();
    runScraping();
    handleWidgetTypeChange();
    showBanner("info", "Dati letti dalla pagina!");
    setTimeout(hideBanner, 1500);
  });

  scanF24Btn.addEventListener("click", async (e) => {
    e.stopPropagation();
    
    let serverUrl = "http://localhost:4173";
    if (chrome.storage && chrome.storage.local) {
      const res = await new Promise(r => chrome.storage.local.get(["serverUrl"], r));
      if (res.serverUrl) {
        serverUrl = res.serverUrl;
      }
    }

    progressBar.classList.remove("hidden");
    progressFill.style.width = "50%";
    progressText.textContent = "Scansione in corso...";
    showBanner("info", "Avvio scanner locale...");

    try {
      const res = await fetch(`${serverUrl}/api/scan-f24`);
      if (!res.ok) {
        const errText = await res.text();
        throw new Error(errText || `Errore HTTP ${res.status}`);
      }

      const result = await res.json();
      progressBar.classList.add("hidden");

      if (result.success) {
        const parsed = result.data;
        console.log("F24 scanned data:", parsed);

        customerName.value = `${parsed.cognome} ${parsed.nome}`.trim();
        reference.value = parsed.cf;
        revenue.value = parsed.amount.toFixed(2);
        notes.value = "F24 scansionato da hardware.";
        opType.value = "Pagamento F24";

        fillDropPointF24(parsed);

        showBanner("success", "F24 scansionato e compilato!");
        setTimeout(hideBanner, 3000);
      } else {
        throw new Error(result.error || "Scansione fallita.");
      }
    } catch (err) {
      console.error("Errore scansione fisica:", err);
      progressBar.classList.add("hidden");
      showBanner("error", "Errore scansione: " + err.message);
      setTimeout(hideBanner, 5000);
    }
  });

  opType.addEventListener("change", handleWidgetTypeChange);
  
  // Call widget type check initially
  handleWidgetTypeChange();

  // Submit to Server
  submitBtn.addEventListener("click", async (e) => {
    e.stopPropagation();
    submitBtn.disabled = true;
    showBanner("info", "Invio in corso...");

    // Get Server URL from storage
    let serverUrl = "http://localhost:4173";
    if (chrome.storage && chrome.storage.local) {
      const res = await new Promise(r => chrome.storage.local.get(["serverUrl"], r));
      if (res.serverUrl) {
        serverUrl = res.serverUrl;
      }
    }

    const payload = {
      platformCode: "DROPPOINT",
      type: opType.value,
      customerName: customerName.value.trim(),
      reference: reference.value.trim(),
      revenue: parseFloat(revenue.value) || 0,
      cost: parseFloat(cost.value) || 0,
      fee: parseFloat(fee.value) || 0,
      status: statusSelect.value,
      notes: notes.value.trim(),
      refund: 0
    };

    try {
      // Get session token dynamically from background worker using cookies permission
      let sessionToken = null;
      try {
        const tokenResponse = await new Promise((resolve) => {
          chrome.runtime.sendMessage({ action: "get-session-token", url: serverUrl }, (response) => {
            if (chrome.runtime.lastError) {
              console.warn("Errore di runtime per recupero cookie:", chrome.runtime.lastError);
              resolve(null);
            } else {
              resolve(response);
            }
          });
        });
        if (tokenResponse && tokenResponse.token) {
          sessionToken = tokenResponse.token;
        }
      } catch (tokenErr) {
        console.warn("Impossibile recuperare il cookie di sessione:", tokenErr);
      }

      const headers = {
        "Content-Type": "application/json"
      };
      if (sessionToken) {
        headers["Authorization"] = `Bearer ${sessionToken}`;
      }

      const res = await fetch(`${serverUrl}/api/operations`, {
        method: "POST",
        headers: headers,
        body: JSON.stringify(payload),
        credentials: "include" // Send cookies for session auth if allowed by browser
      });

      if (!res.ok) {
        const errText = await res.text();
        throw new Error(errText || `Errore HTTP ${res.status}`);
      }

      const result = await res.json();
      showBanner("success", "Operazione registrata!");
      setTimeout(() => {
        hideBanner();
        widgetCard.classList.add("collapsed");
      }, 1800);
    } catch (err) {
      console.error("Errore invio operazione:", err);
      showBanner("error", `Invio fallito. Verifica di essere connesso al gestionale.`);
    } finally {
      submitBtn.disabled = false;
    }
  });

  // Scraper Function
  function runScraping() {
    const data = scrapeDropPointPage();
    
    opType.value = data.type;
    customerName.value = data.customerName;
    reference.value = data.reference;
    revenue.value = data.revenue.toFixed(2);
    cost.value = data.cost.toFixed(2);
    fee.value = data.fee.toFixed(2);
    notes.value = data.notes;
  }

  // Scraper core logic
  function scrapeDropPointPage() {
    const data = {
      type: "Bollettino postale",
      customerName: "",
      reference: "",
      revenue: 0,
      cost: 0,
      fee: 0,
      notes: "Rilevato da estensione DropPoint"
    };

    const pageText = document.body.innerText.toLowerCase();
    
    // 1. Detect service type
    if (pageText.includes("pagopa")) {
      data.type = "PagoPA";
    } else if (pageText.includes("mav") || pageText.includes("rav")) {
      data.type = "MAV / RAV";
    } else if (pageText.includes("f24")) {
      data.type = "Pagamento F24";
    } else if (pageText.includes("ricarica")) {
      data.type = "Ricarica telefonica";
    } else if (pageText.includes("bonifico")) {
      data.type = "Bonifico ordinario";
    } else if (pageText.includes("bollo auto")) {
      data.type = "Bollo auto";
    }

    // 2. Parse Amount (revenue)
    const amountRegexes = [
      /(\d+[\.,]\d{2})\s*(?:€|EUR)/i,
      /(?:€|EUR)\s*(\d+[\.,]\d{2})/i,
      /importo\s*(?:da versare|totale|dovuto|pagato)?:?\s*(\d+[\.,]\d{2})/i
    ];

    for (const regex of amountRegexes) {
      const match = pageText.match(regex);
      if (match) {
        const val = parseFloat(match[1].replace(".", "").replace(",", "."));
        if (val > 0) {
          data.revenue = val;
          break;
        }
      }
    }

    // Scan form fields on page
    const inputs = Array.from(document.querySelectorAll("input"));
    inputs.forEach(input => {
      const name = (input.name || "").toLowerCase();
      const id = (input.id || "").toLowerCase();
      const val = input.value || "";
      if (!val) return;

      if (name.includes("amount") || name.includes("importo") || id.includes("amount") || id.includes("importo")) {
        const num = parseFloat(val.replace(",", "."));
        if (num > 0 && !data.revenue) {
          data.revenue = num;
        }
      }
      if (name.includes("cf") || name.includes("fiscale") || name.includes("taxcode")) {
        if (val.length === 16 && !data.reference) {
          data.reference = val;
        }
      }
      if (name.includes("cognome") || name.includes("nome") || name.includes("client") || name.includes("nome")) {
        if (!data.customerName) {
          data.customerName = val;
        }
      }
    });

    // 3. Scan reference codes or transaction IDs
    const refRegexes = [
      /(?:codice transazione|id transazione|ricevuta n\.|numero transazione|codice operazione):?\s*([a-z0-9\-]{6,24})/i,
      /iuv:?\s*(\d{10,18})/i
    ];
    for (const regex of refRegexes) {
      const match = pageText.match(regex);
      if (match) {
        data.reference = match[1].trim();
        break;
      }
    }

    // Heuristics for default costs
    if (data.type === "PagoPA") {
      data.cost = 1.30; // standard DropPoint cost
      data.fee = 0.70; // standard margin
    } else if (data.type === "Bollettino postale") {
      data.cost = 1.50;
      data.fee = 0.50;
    } else if (data.type === "Ricarica telefonica") {
      data.cost = data.revenue * 0.98; // 2% margin
      data.fee = 0.00;
    }

    return data;
  }

  // Banner UI Helpers
  function showBanner(type, msg) {
    statusBanner.className = `status-banner ${type}`;
    statusBanner.textContent = msg;
  }

  function hideBanner() {
    statusBanner.className = "status-banner";
    statusBanner.textContent = "";
  }

  // Listen to messages from popup or page events to trigger scraping
  chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
    if (msg.action === "get-scraped-data") {
      sendResponse(scrapeDropPointPage());
    }
  });

    // Watch for page changes (e.g. AJAX loads) to re-scrape
    let oldHref = document.location.href;
    const observer = new MutationObserver((mutations) => {
      if (oldHref !== document.location.href) {
        oldHref = document.location.href;
        // Scrape again if page URL changed (SPA routing)
        runScraping();
      }
    });
    observer.observe(body, { childList: true, subtree: true });

    // SPA safety observer: re-inject if the page clears the body
    const bodyObserver = new MutationObserver(() => {
      if (!document.getElementById("gpp-ext-root")) {
        body.appendChild(container);
      }
    });
    bodyObserver.observe(body, { childList: true });
  }

  start();
})();

// --- INTEGRAZIONE INPOST ---

console.log("Estensione Posta Privata v1.2 - Modulo InPost Caricato con successo su: " + window.locatio// 1. Rispondi al ping di presenza del portale Gestionale
window.addEventListener("CheckInpostExtension", () => {
  window.dispatchEvent(new CustomEvent("InpostExtensionActive"));
});

// Auto-login se siamo sul portale InPost e ci sono i campi di login
if (window.location.href.includes("pla.inpost.it")) {
  setTimeout(() => {
    const usernameInput = document.querySelector("input[name*='username'], input[name*='login'], input[name*='email'], input[type='text']");
    const passwordInput = document.querySelector("input[type='password']");
    if (usernameInput && passwordInput && !document.body.innerText.toLowerCase().includes("esci") && !document.body.innerText.toLowerCase().includes("logout")) {
      console.log("Eseguo autologin automatico...");
      usernameInput.focus();
      usernameInput.value = "ITCNA 06636P";
      usernameInput.dispatchEvent(new Event("input", { bubbles: true }));
      usernameInput.dispatchEvent(new Event("change", { bubbles: true }));
      
      passwordInput.focus();
      passwordInput.value = "divisione.porta.morbido";
      passwordInput.dispatchEvent(new Event("input", { bubbles: true }));
      passwordInput.dispatchEvent(new Event("change", { bubbles: true }));
      
      setTimeout(() => {
        const loginBtn = document.querySelector("button[type='submit'], button, input[type='submit']");
        if (loginBtn) loginBtn.click();
      }, 500);
    }
  }, 1500);
}

// 2. Ascolta l'evento di scansione effettuata nel Gestionale per inoltrarla al background
window.addEventListener("InpostScanRegistered", (e) => {
  if (e.detail) {
    chrome.runtime.sendMessage({
      action: "forward-inpost-scan",
      barcode: e.detail.barcode,
      pin: e.detail.pin || null,
      opType: e.detail.action,
      scanId: e.detail.scanId
    });
  }
});

// Fallback robusto con postMessage per superare isolamenti di contesto in Chrome
window.addEventListener("message", (event) => {
  if (event.data) {
    if (event.data.type === "CheckInpostExtension") {
      window.postMessage({ type: "InpostExtensionActive" }, "*");
    }
    if (event.data.type === "InpostScanRegistered") {
      chrome.runtime.sendMessage({
        action: "forward-inpost-scan",
        barcode: event.data.barcode,
        pin: event.data.pin || null,
        opType: event.data.action,
        scanId: event.data.scanId
      });
    }
    if (event.data.type === "ForwardDropPointPayment") {
      chrome.runtime.sendMessage({
        action: "forward-droppoint-payment",
        payload: event.data.payload
      });
    }
  }
});

// 3. Ascolta aggiornamenti dal background per notificare la pagina del Gestionale
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.action === "inpost-status-update" || request.action === "inpost-error") {
    const payload = {
      scanId: request.scanId,
      status: request.status || "Errore",
      error: request.error || null
    };
    window.dispatchEvent(new CustomEvent("InpostStatusUpdate", { detail: payload }));
    window.postMessage({ type: "InpostStatusUpdate", detail: payload }, "*");
  }
  
  // 4. Se siamo sul portale InPost, gestisci l'autocompilazione del barcode
  if (request.action === "process-inpost-scan") {
    try {
      const runScan = (attemptsLeft) => {
        const usernameInput = document.querySelector("input[name*='username'], input[name*='login'], input[name*='email'], input[type='text']");
        const passwordInput = document.querySelector("input[type='password']");
        
        // Se c'è la schermata di login, esegui il login prima e riprova dopo 3.5 secondi
        if (usernameInput && passwordInput && !document.body.innerText.toLowerCase().includes("esci") && !document.body.innerText.toLowerCase().includes("logout")) {
          if (attemptsLeft <= 0) {
            throw new Error("Impossibile accedere al portale InPost. Verifica le credenziali.");
          }
          
          usernameInput.focus();
          usernameInput.value = "ITCNA 06636P";
          usernameInput.dispatchEvent(new Event("input", { bubbles: true }));
          usernameInput.dispatchEvent(new Event("change", { bubbles: true }));
          
          passwordInput.focus();
          passwordInput.value = "divisione.porta.morbido";
          passwordInput.dispatchEvent(new Event("input", { bubbles: true }));
          passwordInput.dispatchEvent(new Event("change", { bubbles: true }));
          
          setTimeout(() => {
            const loginBtn = document.querySelector("button[type='submit'], button, input[type='submit']");
            if (loginBtn) loginBtn.click();
          }, 500);
          
          setTimeout(() => {
            runScan(attemptsLeft - 1);
          }, 3500);
          return;
        }

        // Clicca sul menu corretto
        findAndClickInpostMenu(request.opType);
        
        setTimeout(() => {
          const input = findInpostBarcodeInput();
          if (input) {
            input.focus();
            input.value = request.barcode;
            input.dispatchEvent(new Event("input", { bubbles: true }));
            input.dispatchEvent(new Event("change", { bubbles: true }));
            input.dispatchEvent(new Event("keyup", { bubbles: true }));
            
            // Bottone invia/conferma
            const buttons = Array.from(document.querySelectorAll("button, input[type='submit'], input[type='button']"));
            const submitBtn = buttons.find(b => {
              const txt = (b.textContent || b.value || "").toLowerCase();
              return txt.includes("conferma") || txt.includes("invia") || txt.includes("ok") || txt.includes("cerca") || txt.includes("avanti");
            });
            
            if (submitBtn) {
              submitBtn.click();
            } else {
              const form = input.closest("form");
              if (form) {
                form.dispatchEvent(new Event("submit", { bubbles: true }));
              } else {
                const enterEvent = new KeyboardEvent("keydown", {
                  bubbles: true, cancelable: true, key: "Enter", code: "Enter", keyCode: 13
                });
                input.dispatchEvent(enterEvent);
              }
            }
            
            // Gestione PIN se operazione di consegna
            if ((request.opType === "consegna" || request.opType === "deliver") && request.pin) {
              const checkAndFillPin = (pinAttempts) => {
                const pinInput = document.querySelector("input[name*='pin'], input[id*='pin'], input[placeholder*='pin'], input[placeholder*='codice']");
                if (pinInput && pinInput.value !== request.pin) {
                  pinInput.focus();
                  pinInput.value = request.pin;
                  pinInput.dispatchEvent(new Event("input", { bubbles: true }));
                  pinInput.dispatchEvent(new Event("change", { bubbles: true }));
                  
                  setTimeout(() => {
                    const btns = Array.from(document.querySelectorAll("button, input[type='submit']"));
                    const confirmBtn = btns.find(b => {
                      const txt = (b.textContent || b.value || "").toLowerCase();
                      return txt.includes("conferma") || txt.includes("ok") || txt.includes("invia") || txt.includes("avanti");
                    });
                    if (confirmBtn) confirmBtn.click();
                  }, 500);
                  
                  // Notifica successo finale dopo inserimento PIN
                  chrome.runtime.sendMessage({
                    action: "report-inpost-status",
                    senderTabId: request.senderTabId,
                    scanId: request.scanId,
                    status: "Sincronizzato"
                  });
                } else {
                  if (pinAttempts > 0) {
                    setTimeout(() => checkAndFillPin(pinAttempts - 1), 500);
                  } else {
                    // Se non appare il campo PIN, inviamo comunque sincronizzato per il barcode
                    chrome.runtime.sendMessage({
                      action: "report-inpost-status",
                      senderTabId: request.senderTabId,
                      scanId: request.scanId,
                      status: "Sincronizzato"
                    });
                  }
                }
              };
              setTimeout(() => checkAndFillPin(10), 1500);
            } else {
              // Notifica successo per ritiro semplice
              chrome.runtime.sendMessage({
                action: "report-inpost-status",
                senderTabId: request.senderTabId,
                scanId: request.scanId,
                status: "Sincronizzato"
              });
            }
          } else {
            if (attemptsLeft > 0) {
              setTimeout(() => runScan(attemptsLeft - 1), 1500);
            } else {
              chrome.runtime.sendMessage({
                action: "report-inpost-status",
                senderTabId: request.senderTabId,
                scanId: request.scanId,
                status: "Errore",
                error: "Campo barcode non trovato nel portale InPost"
              });
            }
          }
        }, 1000);
      };
      
      runScan(2);
    } catch (err) {
      chrome.runtime.sendMessage({
        action: "report-inpost-status",
        senderTabId: request.senderTabId,
        scanId: request.scanId,
        status: "Errore",
        error: err.message
      });
    }
  }

  if (request.action === "autofill-payment") {
    try {
      const payload = request.payload;
      navigateToDropPointService(payload.type);
      setTimeout(() => {
        if (payload.type && payload.type.toLowerCase().includes("f24")) {
          fillDropPointF24(payload);
        } else {
          fillDropPointPaymentFields(payload);
        }
      }, 1000);
      sendResponse({ success: true });
    } catch (err) {
      sendResponse({ error: err.message });
    }
  }
  return true;
});

function findAndClickInpostMenu(action) {
  const isArrive = action === "arrive" || action === "ritira" || action === "accetta" || action === "drop-off";
  const textToFind = isArrive ? "ritira" : "consegna";
  const elements = Array.from(document.querySelectorAll("a, button, div, span, p, li"));
  const btn = elements.find(el => {
    const txt = el.textContent.toLowerCase();
    return txt.includes(textToFind) && txt.includes("pacco") && el.children.length === 0;
  }) || elements.find(el => el.textContent.toLowerCase().includes(textToFind) && el.children.length === 0);
  
  if (btn) {
    btn.click();
  }
}

function findInpostBarcodeInput() {
  if (document.activeElement && document.activeElement.tagName === "INPUT" && document.activeElement.type === "text") {
    return document.activeElement;
  }
  return document.querySelector("input[name*='barcode'], input[id*='barcode'], input[placeholder*='barcode'], input[placeholder*='codice'], input[placeholder*='etichetta'], input[type='text']");
}

function navigateToDropPointService(type) {
  const normalizedType = type.toLowerCase();
  const links = Array.from(document.querySelectorAll("a, button, div, span"));
  
  let targetText = "";
  if (normalizedType.includes("pagopa")) {
    targetText = "pagopa";
  } else if (normalizedType.includes("bollettino")) {
    targetText = "bollettino";
  } else if (normalizedType.includes("mav") || normalizedType.includes("rav")) {
    targetText = "mav";
  } else if (normalizedType.includes("f24")) {
    targetText = "f24";
  }
  
  if (targetText) {
    const btn = links.find(l => {
      const txt = l.textContent.toLowerCase();
      return txt.includes(targetText) && l.children.length === 0;
    }) || links.find(l => l.textContent.toLowerCase().includes(targetText));
    if (btn) btn.click();
  }
}

function fillDropPointPaymentFields(payload) {
  const inputs = Array.from(document.querySelectorAll("input, select, textarea"));
  
  inputs.forEach(input => {
    if (input.type === "hidden" || input.style.display === "none" || input.offsetWidth === 0) return;
    
    const name = (input.name || "").toLowerCase();
    const id = (input.id || "").toLowerCase();
    const placeholder = (input.placeholder || "").toLowerCase();
    
    let labelText = "";
    if (input.labels && input.labels.length) {
      labelText = Array.from(input.labels).map(l => l.textContent).join(" ").toLowerCase();
    } else {
      const parentLabel = input.closest("label");
      if (parentLabel) labelText = parentLabel.textContent.toLowerCase();
    }
    
    const matchString = `${name} ${id} ${placeholder} ${labelText}`;
    
    // Compilazione PagoPA
    if (payload.type.toLowerCase().includes("pagopa")) {
      if (matchString.includes("avviso") || matchString.includes("iuv") || matchString.includes("codice avviso") || name.includes("code") || name.includes("iuv")) {
        setInputValue(input, payload.reference);
      }
      else if (matchString.includes("fiscale") || matchString.includes("cf") || matchString.includes("ente") || matchString.includes("creditore") || name.includes("cf")) {
        setInputValue(input, payload.cfEnte || "");
      }
      else if (matchString.includes("importo") || matchString.includes("saldo") || matchString.includes("euro") || name.includes("amount") || name.includes("revenue")) {
        setInputValue(input, String(payload.revenue));
      }
    }
    // Compilazione Bollettino Postale
    else if (payload.type.toLowerCase().includes("bollettino")) {
      if (matchString.includes("conto") || matchString.includes("cc") || matchString.includes("c/c") || name.includes("conto") || name.includes("cc")) {
        setInputValue(input, payload.contoCorrente || "");
      }
      else if (matchString.includes("codice") || matchString.includes("numero bollettino") || matchString.includes("identificativo") || name.includes("code") || name.includes("reference")) {
        setInputValue(input, payload.reference);
      }
      else if (matchString.includes("tipologia") || matchString.includes("tipo") || name.includes("type")) {
        setInputValue(input, payload.bollettinoType || "896");
      }
      else if (matchString.includes("importo") || matchString.includes("euro") || name.includes("amount")) {
        setInputValue(input, String(payload.revenue));
      }
    }
    // Compilazione MAV/RAV
    else if (payload.type.toLowerCase().includes("mav") || payload.type.toLowerCase().includes("rav")) {
      if (matchString.includes("codice") || matchString.includes("mav") || matchString.includes("rav") || name.includes("code") || name.includes("mav") || name.includes("rav")) {
        setInputValue(input, payload.reference);
      }
      else if (matchString.includes("importo") || matchString.includes("euro") || name.includes("amount")) {
        setInputValue(input, String(payload.revenue));
      }
    }
  });
}
