(function(){
    'use strict';

    const __pageBindings = [];
    const on = (target, eventName, handler, options) => {
        if (!target || typeof target.addEventListener !== 'function') return;
        target.addEventListener(eventName, handler, options || false);
        __pageBindings.push([target, eventName, handler, options || false]);
    };
    window.ICY_PAGE_CLEANUPS = window.ICY_PAGE_CLEANUPS || [];
    window.ICY_PAGE_CLEANUPS.push(() => {
        __pageBindings.forEach(([target, eventName, handler, options]) => {
            try { target.removeEventListener(eventName, handler, options); } catch (_) {}
        });
    });

    const state = {
        env: 'production', rows: [], currentId: null, currentDocument: null,
        currentOrigin: 'issued',
        operationType: null, operationId: null, previewData: null, searchTimer: null,
        paging: window.IcyBillingTable.createPaging('10')
    };
    const layers = {detail:'documentLayerDetail', adjustment:'documentLayerAdjustment', preview:'documentLayerPreview', confirm:'documentLayerConfirm', result:'documentLayerResult'};
    const $ = (id) => document.getElementById(id);
    const esc = (v) => String(v == null ? '' : v).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#039;'}[c]));
    const money = (v) => new Intl.NumberFormat('es-CL',{style:'currency',currency:'CLP',maximumFractionDigits:0}).format(Number(v||0));
    const currencyMoney = (v, code) => {
        code=String(code||'CLP').toUpperCase();
        const digits=code==='CLP'?0:2;
        try{return new Intl.NumberFormat('es-CL',{style:'currency',currency:code,minimumFractionDigits:digits,maximumFractionDigits:digits}).format(Number(v||0));}
        catch(e){return code+' '+Number(v||0).toFixed(digits);}
    };
    const documentMoney = (row, value) => currencyMoney(value, row&&row.currency_code?row.currency_code:'CLP');
    const clpAmount = (row, field) => {
        const clpField = `${field}_clp`;
        if (row && row[clpField] != null && row[clpField] !== '') return Number(row[clpField] || 0);
        const amount = Number(row && row[field] != null ? row[field] : 0);
        const currency = String(row && row.currency_code ? row.currency_code : 'CLP').toUpperCase();
        if (currency === 'CLP') return amount;
        const rate = Number(row && row.exchange_rate_value ? row.exchange_rate_value : 0);
        return rate > 0 ? amount * rate : 0;
    };
    const documentBreakdown = (row) => {
        const rawNet = Math.max(0, clpAmount(row, 'net_amount'));
        const total = Math.max(0, clpAmount(row, 'total_amount'));
        const taxCode = String(row && row.document_type_taxbureau ? row.document_type_taxbureau : '');
        const localType = Number(row && row.document_type_id ? row.document_type_id : 0);
        const exemptDocument = Number(row && row.is_tax_exempt || 0) === 1
            || (row && row.document_family === 'export')
            || ['34', '41', '110', '111'].includes(taxCode)
            || [32, 33, 41, 46].includes(localType);
        const reportedIva = Math.max(0, clpAmount(row, 'taxes_amount'));
        const exempt = exemptDocument ? (rawNet > 0 ? rawNet : total) : 0;
        const net = exemptDocument ? 0 : rawNet;
        const iva = exemptDocument ? 0 : (reportedIva > 0 ? reportedIva : Math.max(0, total - net));
        const other = Math.max(0, total - net - exempt - iva);
        const financial = Number(row && row.is_financial_document || 0) === 1;
        const paid = financial ? Math.min(total, Math.max(0, Number(row.paid_amount || 0))) : 0;
        const unpaid = financial
            ? Math.min(total, Math.max(0, row.balance_amount != null ? Number(row.balance_amount || 0) : total - paid))
            : 0;
        return {net, exempt, iva, other, total, paid, unpaid};
    };
    const collectionMoney = (row, kind) => {
        if(row && row.currency_code && row.currency_code!=='CLP' && row['foreign_'+kind+'_amount']!=null) return currencyMoney(row['foreign_'+kind+'_amount'], row.currency_code);
        const field=kind==='total'?'collection_total':kind+'_amount';
        return money(row&&row[field]!=null?row[field]:0);
    };
    const dateText = (v) => { if(!v) return '-'; const p=String(v).slice(0,10).split('-'); return p.length===3?`${p[2]}-${p[1]}-${p[0]}`:String(v); };
    const today = () => new Date().toISOString().slice(0,10);

    function icons(){ if(window.lucide && window.lucide.createIcons) window.lucide.createIcons(); }
    function modalFooter(rightActions, leftActions=''){
        return `${leftActions ? `<div class="modal-footer-actions-left">${leftActions}</div>` : ''}<div class="modal-footer-actions-right">${rightActions || ''}</div>`;
    }
    async function jsonFetch(url, options){
        const r=await fetch(url,options||{}); let p=null; try{p=await r.json();}catch(e){}
        if(!r.ok || !p || p.success===false) throw new Error(p&&p.message?p.message:`Error HTTP ${r.status}`);
        return p;
    }
    function setLayer(name){
        Object.entries(layers).forEach(([key,id])=>{ const el=$(id); if(el) el.classList.toggle('active',key===name); });
        const body=$(layers[name])?.querySelector('.product-modal-body'); if(body) body.scrollTop=0; icons();
    }
    function syncModalBodyLock(){
        const hasOpenModal = Array.from(document.querySelectorAll('.product-modal-backdrop.show')).some((modal) => modal.getAttribute('aria-hidden') !== 'true');
        document.body.classList.toggle('is-modal-open', hasOpenModal);
    }
    function openModal(){ const m=$('documentModal'); m.style.display='flex'; m.classList.add('show'); m.setAttribute('aria-hidden','false'); syncModalBodyLock(); icons(); }
    function closeModal(){ const m=$('documentModal'); m.classList.remove('show'); m.setAttribute('aria-hidden','true'); setTimeout(()=>{if(!m.classList.contains('show'))m.style.display='none';},120); syncModalBodyLock(); state.operationId=null; state.previewData=null; }
    function steps(active){ return `<div class="documents-flow-steps">${[['adjustment','1. Preparar'],['preview','2. Preview'],['confirm','3. Confirmar'],['result','4. Resultado']].map(([k,l])=>`<div class="documents-flow-step${k===active?' active':''}">${l}</div>`).join('')}</div>`; }
    function familyLabel(row){ const f=row.document_family||'other',type=Number(row.document_type_id||0); if(f==='credit_note')return type===48?'Nota de crédito de exportación':'Nota de crédito'; if(f==='debit_note')return type===47?'Nota de débito de exportación':'Nota de débito'; if(f==='dispatch_guide')return'Guía de despacho'; if(f==='export')return'Factura de exportación'; if(f==='invoice')return Number(row.is_tax_exempt||0)===1||[32,33].includes(type)?'Factura exenta':'Factura afecta'; if(f==='receipt')return row.document_label||'Boleta'; return row.document_label||`DTE ${row.document_type_taxbureau||row.document_type_id||''}`; }
    function financialLabel(v){ return ({por_cobrar:'Por cobrar',por_pagar:'Por pagar',atrasado:'Atrasado',vencido:'Vencido',parcial:'Parcial',pagado:'Pagado',anulado:'Anulado',rechazado:'Rechazado',incobrable:'Incobrable',pending:'Pendiente'}[v]||v||'-'); }
    function operationLabel(v){return v==='credit_note'?'Nota de crédito':'Nota de débito';}
    function statusLabel(v){return ({draft:'Borrador',preview_ready:'Preview listo',issuing:'Emitiendo',issued:'Emitida',error:'Error',pending_local_commit:'Pendiente cierre local',remote_uncertain:'Resultado remoto incierto',cancelled:'Cancelada'}[v]||v||'-');}

    const documentGroups = [
        {key:'issued', title:'Documentos emitidos', description:'Todos los documentos tributarios emitidos por ICYLAB.'},
        {key:'received', title:'Documentos recibidos', description:'Todos los documentos tributarios recibidos desde proveedores.'}
    ];
    function groupKey(row){ return row && row.document_origin === 'received' ? 'received' : 'issued'; }
    function sortValue(row, column) {
        const amounts = ['net', 'exempt', 'iva', 'other', 'total', 'paid', 'unpaid'].includes(column)
            ? documentBreakdown(row)
            : null;
        if (amounts) return amounts[column];
        if (column === 'issue_date') return String(row.issue_date || '').slice(0, 10);
        if (column === 'folio') return row.document_number || '';
        if (column === 'receiver') return row.counterparty_name || row.customer_legal_name || row.customer_name || row.receiver_legal_name || row.issuer_name || '';
        if (column === 'tax_id') return row.counterparty_tax_id || row.receiver_tax_id_code || row.issuer_tax_id_code || '';
        if (column === 'status') return financialLabel(row.collection_status || row.payment_status);
        return row[column] == null ? '' : row[column];
    }
    function sortHead(label, type, column, group, className = '') {
        const sort = window.IcyBillingTable.sortState(state.paging, group.key);
        const ariaSort = sort && sort.column === column ? sort.direction : 'none';
        return `<th class="${esc(className)}" aria-sort="${esc(ariaSort)}"><button type="button" class="icy-table-sort-button" data-sort-type="${esc(type)}" data-billing-sort-key="${esc(column)}"><span>${esc(label)}</span><span class="icy-table-sort-indicator" aria-hidden="true"></span></button></th>`;
    }
    function documentActions(row) {
        const id = Number(row.id || 0);
        const origin = groupKey(row);
        const canAdjust = origin === 'issued' && ['invoice', 'export'].includes(row.document_family || '') && Number(row.document_status == null ? 1 : row.document_status) !== 0;
        const pdfUrl = origin === 'received'
            ? `/modules/billing/payable_file.php?id=${id}&env=${encodeURIComponent(state.env)}&type=pdf`
            : `/modules/billing/document_file.php?id=${id}&kind=pdf`;
        const xmlUrl = origin === 'received'
            ? `/modules/billing/payable_file.php?id=${id}&env=${encodeURIComponent(state.env)}&type=xml`
            : `/modules/billing/document_file.php?id=${id}&kind=xml`;
        return `<details class="billing-row-actions" data-billing-row-actions data-close-outside>
            <summary aria-label="Acciones del documento ${esc(row.document_number || '')}"><i data-lucide="file-text"></i><i data-lucide="chevron-down"></i></summary>
            <div class="billing-row-actions__panel">
                <button type="button" class="document-open-btn" data-id="${id}" data-origin="${origin}"><i data-lucide="eye"></i>Ver detalle</button>
                <a target="_blank" rel="noopener" href="${esc(pdfUrl)}"><i data-lucide="file-down"></i>PDF</a>
                <a target="_blank" rel="noopener" href="${esc(xmlUrl)}"><i data-lucide="code-xml"></i>XML</a>
                ${canAdjust ? `<button type="button" data-document-adjustment-id="${id}" data-adjustment-type="credit_note"><i data-lucide="file-minus-2"></i>Emitir nota de crédito</button><button type="button" data-document-adjustment-id="${id}" data-adjustment-type="debit_note"><i data-lucide="file-plus-2"></i>Emitir nota de débito</button>` : ''}
            </div>
        </details>`;
    }
    function documentTotals(rows) {
        return rows.reduce((totals, row) => {
            const values = documentBreakdown(row);
            Object.keys(totals).forEach((key) => { totals[key] += Number(values[key] || 0); });
            return totals;
        }, {net: 0, exempt: 0, iva: 0, other: 0, total: 0, paid: 0, unpaid: 0});
    }
    function documentsTable(rows, group){
        const orderedRows = window.IcyBillingTable.sortedRows(rows, state.paging, group.key, sortValue);
        const page = window.IcyBillingTable.pageFor(orderedRows, state.paging, group.key);
        const totals = documentTotals(orderedRows);
        const dateLabel = group.key === 'received' ? 'Documento' : 'Emisión';
        const counterpartyLabel = group.key === 'received' ? 'Emisor' : 'Receptor';
        const body=page.rows.length?page.rows.map(r=>{ const amounts=documentBreakdown(r);
            const counterpartyName=r.counterparty_name||r.customer_legal_name||r.customer_name||r.receiver_legal_name||r.issuer_name||'-';
            const counterpartyTaxId=r.counterparty_tax_id||r.receiver_tax_id_code||r.issuer_tax_id_code||'-';
            return `<tr>
            <td class="crm-mobile-hidden" data-sort-value="${esc(String(r.issue_date||'').slice(0,10))}">${esc(dateText(r.issue_date))}</td>
            <td class="col-folio crm-mobile-primary" data-sort-value="${esc(r.document_number||'')}"><div class="crm-ui-cell-stack"><strong>${esc(r.document_number||'-')}</strong><small>${esc(familyLabel(r))}</small></div></td>
            <td class="col-client crm-mobile-primary" data-sort-value="${esc(counterpartyName)}"><div class="crm-ui-cell-stack"><strong>${esc(counterpartyName)}</strong><small>${esc(counterpartyTaxId||'Sin RUT')}</small></div></td>
            <td class="crm-mobile-hidden" data-sort-value="${esc(counterpartyTaxId)}">${esc(counterpartyTaxId)}</td>
            <td class="documents-money crm-mobile-hidden" data-sort-value="${amounts.net}">${money(amounts.net)}</td>
            <td class="documents-money crm-mobile-hidden" data-sort-value="${amounts.exempt}">${money(amounts.exempt)}</td>
            <td class="documents-money crm-mobile-hidden" data-sort-value="${amounts.iva}">${money(amounts.iva)}</td>
            <td class="documents-money crm-mobile-hidden" data-sort-value="${amounts.other}">${money(amounts.other)}</td>
            <td class="documents-money crm-mobile-hidden" data-sort-value="${amounts.total}"><strong>${money(amounts.total)}</strong></td>
            <td class="documents-money crm-mobile-hidden" data-sort-value="${amounts.paid}">${money(amounts.paid)}</td>
            <td class="documents-money crm-mobile-metric" data-sort-value="${amounts.unpaid}"><strong>${money(amounts.unpaid)}</strong></td>
            <td class="crm-mobile-hidden" data-sort-value="${esc(financialLabel(r.collection_status||r.payment_status))}"><span class="documents-financial-status ${esc(r.collection_status||r.payment_status||'neutral')}">${esc(financialLabel(r.collection_status||r.payment_status))}</span></td>
            <td class="col-action crm-ui-action-cell">${documentActions(r)}</td>
        </tr>`; }).join(''):`<tr class="empty-state-row"><td colspan="13" class="documents-muted">Sin documentos ${group.key==='received'?'recibidos':'emitidos'} para los filtros seleccionados.</td></tr>`;
        const headers=[
            sortHead(dateLabel,'date','issue_date',group,'crm-mobile-hidden'),
            sortHead('Folio','text','folio',group,'crm-mobile-primary'),
            sortHead(counterpartyLabel,'text','receiver',group,'crm-mobile-primary'),
            sortHead('RUT','text','tax_id',group,'crm-mobile-hidden'),
            sortHead('Neto','number','net',group,'crm-mobile-hidden'),
            sortHead('Exento','number','exempt',group,'crm-mobile-hidden'),
            sortHead('IVA','number','iva',group,'crm-mobile-hidden'),
            sortHead('Otros','number','other',group,'crm-mobile-hidden'),
            sortHead('Total','number','total',group,'crm-mobile-hidden'),
            sortHead('Pagado','number','paid',group,'crm-mobile-hidden'),
            sortHead('Impago','number','unpaid',group,'crm-mobile-metric'),
            sortHead('Estado','text','status',group,'crm-mobile-hidden'),
            '<th class="crm-ui-action-cell">Acciones</th>'
        ].join('');
        const footer = `<tfoot><tr><th colspan="4">Total ${orderedRows.length.toLocaleString('es-CL')} documentos</th><td>${money(totals.net)}</td><td>${money(totals.exempt)}</td><td>${money(totals.iva)}</td><td>${money(totals.other)}</td><td>${money(totals.total)}</td><td>${money(totals.paid)}</td><td>${money(totals.unpaid)}</td><td colspan="2"></td></tr></tfoot>`;
        return `<section class="card billing-document-group crm-ui-table-card" data-document-group="${esc(group.key)}"><header class="billing-document-group-header"><div><h3>${esc(group.title)}</h3><p>${esc(group.description)}</p></div><span class="billing-document-group-count">${orderedRows.length}</span></header>${window.IcyBillingTable.controls(page,group.title)}<div class="billing-document-group-scroll crm-ui-table-scroll billing-reference-table-scroll"><table class="table documents-table billing-responsive-table billing-crm-table crm-ui-table crm-ui-mobile-table billing-reference-table" data-billing-group="${esc(group.key)}"><thead><tr>${headers}</tr></thead><tbody>${body}</tbody>${footer}</table></div></section>`;
    }
    async function loadDocuments(){
        state.env=$('documentsEnv')?.value||'production';
        const params=new URLSearchParams({env:state.env,search:$('documentsSearch').value.trim(),origin:$('documentsOrigin').value,family:$('documentsFamily').value,from:$('documentsFrom').value,to:$('documentsTo').value});
        $('documentsGroups').innerHTML='<section class="card billing-document-group"><div class="billing-document-loading">Cargando documentos...</div></section>'; $('documentsLoadError').style.display='none';
        try{ const p=await jsonFetch('/modules/billing/documents_list_ajax.php?'+params); state.rows=p.data.rows||[]; window.IcyBillingTable.resetPaging(state.paging); renderRows(); }
        catch(e){ state.rows=[]; renderRows(); $('documentsLoadError').textContent='Error al cargar documentos: '+e.message; $('documentsLoadError').style.display='block'; }
    }
    function renderRows(){
        const selected=$('documentsOrigin').value||'all';
        const groups=selected==='all'?documentGroups:documentGroups.filter(g=>g.key===selected);
        $('documentsGroups').innerHTML=groups.map(group=>documentsTable(state.rows.filter(r=>groupKey(r)===group.key),group)).join('');
        icons();
    }

    async function openDetail(id, origin='issued'){
        state.currentId=Number(id); state.currentOrigin=origin==='received'?'received':'issued'; state.currentDocument=null; state.operationId=null; state.previewData=null;
        $('documentDetailTitle').textContent=state.currentOrigin==='received'?'Documento recibido':'Documento emitido'; $('documentDetailSubtitle').textContent=''; $('documentDetailBody').innerHTML='<p>Cargando...</p>'; $('documentDetailFooter').innerHTML='';
        setLayer('detail'); openModal();
        try{ const p=await jsonFetch(`/modules/billing/document_detail_ajax.php?id=${encodeURIComponent(id)}&env=${encodeURIComponent(state.env)}&origin=${encodeURIComponent(state.currentOrigin)}`); state.currentDocument=p.document; renderDetail(p.document); }
        catch(e){ $('documentDetailBody').innerHTML=`<div class="documents-layer-error show">${esc(e.message)}</div>`; }
    }
    function renderReceivedDetail(d){
        const amounts=documentBreakdown(d);
        const counterpartyName=d.counterparty_name||d.supplier_name||d.issuer_name||'-';
        const counterpartyTaxId=d.counterparty_tax_id||d.supplier_tax_id||d.issuer_tax_id_code||'-';
        const status=financialLabel(d.collection_status||d.payment_status);
        const fileBase=`/modules/billing/payable_file.php?id=${Number(d.id)}&env=${encodeURIComponent(state.env)}`;
        $('documentDetailTitle').textContent=`${familyLabel(d)} ${d.document_number||''}`.trim();
        $('documentDetailSubtitle').textContent=`Recibido · ${counterpartyName} · ${counterpartyTaxId} · ${d.environment}`;
        $('documentDetailBody').innerHTML=`
            <div class="documents-summary crm-ui-summary-grid">
                <div class="crm-ui-summary-card"><span>Neto</span><strong>${money(amounts.net)}</strong></div>
                <div class="crm-ui-summary-card"><span>Exento</span><strong>${money(amounts.exempt)}</strong></div>
                <div class="crm-ui-summary-card"><span>IVA</span><strong>${money(amounts.iva)}</strong></div>
                <div class="crm-ui-summary-card"><span>Total documento</span><strong>${money(amounts.total)}</strong></div>
                <div class="crm-ui-summary-card"><span>Pagado</span><strong>${money(amounts.paid)}</strong></div>
                <div class="crm-ui-summary-card"><span>Estado</span><strong>${esc(status)}</strong></div>
            </div>
            <div class="documents-grid crm-ui-form-grid">
                <div class="documents-section crm-ui-section">
                    <h3>Documento recibido</h3>
                    <p><strong>Emisor:</strong> ${esc(counterpartyName)}</p>
                    <p><strong>RUT:</strong> ${esc(counterpartyTaxId)}</p>
                    <p><strong>Fecha documento:</strong> ${dateText(d.document_date||d.issue_date)}</p>
                    <p><strong>Fecha recepción:</strong> ${dateText(d.receive_date)}</p>
                    <div class="documents-file-actions"><a class="btn btn-secondary" target="_blank" rel="noopener" href="${fileBase}&type=pdf">Ver PDF</a><a class="btn btn-secondary" target="_blank" rel="noopener" href="${fileBase}&type=xml">Ver XML</a></div>
                </div>
                <div class="documents-section crm-ui-section">
                    <h3>Trazabilidad</h3>
                    <p><strong>FACTO inbox_document_id:</strong> ${esc(d.inbox_document_id||'-')}</p>
                    <p><strong>FACTO document_id:</strong> ${esc(d.document_id||'-')}</p>
                    <p><strong>Tipo FACTO / SII:</strong> ${esc(d.document_type_id||'-')} / ${esc(d.document_type_taxbureau||'-')}</p>
                    <p><strong>Estado recepción:</strong> ${esc(d.icylab_reception_status||d.inbox_document_status||'-')}</p>
                    <p><strong>Vencimiento:</strong> ${dateText(d.due_date||d.payment_due_date)}</p>
                </div>
            </div>`;
        $('documentDetailFooter').innerHTML=modalFooter('<button class="btn btn-outline documents-flow-close" title="Cerrar" aria-label="Cerrar"><i data-lucide="x"></i><span>Cerrar</span></button>');
        icons();
    }
    function renderDetail(d){
        if((d.document_origin||state.currentOrigin)==='received'){renderReceivedDetail(d);return;}
        $('documentDetailTitle').textContent=`${familyLabel(d)} ${d.document_number||''}`.trim();
        $('documentDetailSubtitle').textContent=`${d.customer_legal_name||d.customer_name||d.receiver_legal_name||'-'} · ${d.receiver_tax_id_code||'-'} · ${d.environment}`;
        const lines=(d.lines||[]).map(l=>`<tr><td>${esc(l.sku||'-')}</td><td>${esc(l.description||'-')}</td><td>${esc(l.quantity)}</td><td>${esc(l.unit_measure||'-')}</td><td>${documentMoney(d,l.unit_price)}</td><td>${documentMoney(d,l.total_amount)}</td></tr>`).join('')||'<tr><td colspan="6" class="documents-muted">Sin líneas locales registradas.</td></tr>';
        const refs=(d.references||[]).map(r=>`<tr><td>${esc(r.reference_code||'-')}</td><td>${esc(r.referenced_document_number||r.reference_document_number||'-')}</td><td>${esc(r.reference_reason||'-')}</td><td>${documentMoney(d,r.amount||0)}</td><td>${dateText(r.created_at)}</td></tr>`).join('')||'<tr><td colspan="5" class="documents-muted">Sin referencias registradas.</td></tr>';
        const ops=(d.operations||[]).map(o=>`<tr><td>${esc(operationLabel(o.operation_type))}</td><td>${esc(statusLabel(o.status))}</td><td>${esc(o.document_number||'-')}</td><td>${documentMoney(d,o.total_amount)}</td><td>${esc(o.reason||'-')}</td><td>${dateText(o.issued_at||o.created_at)}</td><td>${o.status==='pending_local_commit'?`<button class="btn btn-secondary btn-sm repair-operation-btn" data-operation-id="${Number(o.id)}">Reparar cierre</button>`:''}</td></tr>`).join('')||'<tr><td colspan="7" class="documents-muted">Sin operaciones de notas tributarias.</td></tr>';
        const guides=(d.dispatch_guides||[]).map(g=>`<tr><td>${esc(g.source_document_number||'-')}</td><td>${esc(statusLabel(g.status))}</td><td>${esc(g.document_number||'-')}</td><td>${dateText(g.issue_date||g.created_at)}</td><td>${esc(g.dispatch_district||'-')} · ${esc(g.dispatch_city||'-')}</td><td><div class="documents-file-actions">${g.pdf_file_path?`<a class="btn btn-secondary btn-sm" target="_blank" href="/modules/billing/dispatch_guide_file.php?guide_id=${Number(g.id)}&kind=pdf&stage=issued">PDF</a>`:''}${g.xml_file_path?`<a class="btn btn-secondary btn-sm" href="/modules/billing/dispatch_guide_file.php?guide_id=${Number(g.id)}&kind=xml&stage=issued">XML</a>`:''}${g.transfer_copy_pdf_file_path?`<a class="btn btn-secondary btn-sm" target="_blank" href="/modules/billing/dispatch_guide_file.php?guide_id=${Number(g.id)}&kind=transfer_pdf&stage=issued">Cedible</a>`:''}${g.status==='pending_local_commit'?`<button class="btn btn-secondary btn-sm repair-dispatch-guide-btn" data-guide-id="${Number(g.id)}">Reparar cierre</button>`:''}</div></td></tr>`).join('')||'<tr><td colspan="6" class="documents-muted">Sin guías relacionadas.</td></tr>';
        $('documentDetailBody').innerHTML=`
            <div class="documents-summary crm-ui-summary-grid"><div class="crm-ui-summary-card"><span>Neto</span><strong>${documentMoney(d,d.net_amount)}</strong></div><div class="crm-ui-summary-card"><span>IVA / impuestos</span><strong>${documentMoney(d,d.taxes_amount)}</strong></div><div class="crm-ui-summary-card"><span>Total documento</span><strong>${documentMoney(d,d.total_amount)}</strong></div><div class="crm-ui-summary-card"><span>Pagado</span><strong>${collectionMoney(d,'paid')}</strong></div><div class="crm-ui-summary-card"><span>Saldo ajustado</span><strong>${collectionMoney(d,'balance')}</strong></div><div class="crm-ui-summary-card"><span>Estado</span><strong>${esc(financialLabel(d.collection_status||d.payment_status))}</strong></div></div>
            <div class="documents-grid crm-ui-form-grid"><div class="documents-section crm-ui-section"><h3>Documento</h3><p><strong>Cliente:</strong> ${esc(d.customer_legal_name||d.customer_name||d.receiver_legal_name||'-')}</p><p><strong>RUT:</strong> ${esc(d.receiver_tax_id_code||'-')}</p><p><strong>Fecha:</strong> ${dateText(d.issue_date)}</p><p><strong>Cotización:</strong> ${esc(d.quote_number||'-')}</p><div class="documents-file-actions"><a class="btn btn-secondary" target="_blank" rel="noopener" href="/modules/billing/document_file.php?id=${Number(d.id)}&kind=pdf">Ver PDF</a><a class="btn btn-secondary" target="_blank" rel="noopener" href="/modules/billing/document_file.php?id=${Number(d.id)}&kind=xml">Ver XML</a></div><small class="documents-muted">Si el archivo no está local, se recuperará desde FACTO.</small></div><div class="documents-section crm-ui-section"><h3>Trazabilidad</h3><p><strong>FACTO document_id:</strong> ${esc(d.document_id||'-')}</p><p><strong>Tipo FACTO / SII:</strong> ${esc(d.document_type_id||'-')} / ${esc(d.document_type_taxbureau||'-')}</p><p><strong>Vencimiento:</strong> ${dateText(d.due_date||d.payment_due_date)}</p>${d.currency_code&&d.currency_code!=='CLP'?`<p><strong>Moneda:</strong> ${esc(d.currency_code||'-')}</p><p><strong>Tipo de cambio:</strong> ${esc(d.exchange_rate_value||'-')} CLP</p><p><strong>Fecha tasa:</strong> ${dateText(d.exchange_rate_date||d.collection_exchange_rate_date)}</p><p><strong>Fuente:</strong> ${esc(d.exchange_rate_source||d.collection_exchange_rate_source||'-')}</p><p><strong>Calidad:</strong> ${esc(d.exchange_rate_status||d.collection_exchange_rate_status||'-')}</p><p><strong>Total equivalente:</strong> ${d.total_amount_clp!=null?money(d.total_amount_clp):'Pendiente'}</p><p><strong>País receptor:</strong> ${esc(d.receiver_country_id||'-')}</p>`:''}</div></div>
            ${d.dispatch_guide?`<div class="documents-section crm-ui-section"><h3>Datos de guía</h3><div class="documents-grid crm-ui-form-grid"><div><p><strong>Tipo:</strong> ${esc(d.dispatch_guide.guide_type||'-')}</p><p><strong>Traslado:</strong> ${esc(d.dispatch_guide.transfer_type||'-')}</p><p><strong>Origen:</strong> ${esc(d.dispatch_guide.source_document_number||'-')}</p></div><div><p><strong>Destino:</strong> ${esc(d.dispatch_guide.dispatch_address||'-')}</p><p><strong>Comuna / ciudad:</strong> ${esc((d.dispatch_guide.dispatch_district||'-')+' / '+(d.dispatch_guide.dispatch_city||'-'))}</p></div></div></div>`:''}
            <div class="documents-section crm-ui-section"><h3>Detalle</h3><div class="documents-scroll-table crm-ui-inner-table-wrap"><table class="documents-lines crm-ui-inner-table"><thead><tr><th>SKU</th><th>Descripción</th><th>Cantidad</th><th>Unidad</th><th>Precio</th><th>Total</th></tr></thead><tbody>${lines}</tbody></table></div></div>
            <div class="documents-section crm-ui-section"><h3>Referencias tributarias</h3><div class="documents-scroll-table crm-ui-inner-table-wrap"><table class="documents-history documents-history--references crm-ui-inner-table"><thead><tr><th>Código</th><th>Documento</th><th>Motivo</th><th>Monto</th><th>Fecha</th></tr></thead><tbody>${refs}</tbody></table></div></div>
            <div class="documents-section crm-ui-section"><h3>Notas tributarias</h3><div class="documents-scroll-table crm-ui-inner-table-wrap"><table class="documents-history documents-history--notes crm-ui-inner-table"><thead><tr><th>Tipo</th><th>Estado</th><th>Folio</th><th>Monto</th><th>Motivo</th><th>Fecha</th><th></th></tr></thead><tbody>${ops}</tbody></table></div></div>
            <div class="documents-section crm-ui-section"><h3>Guías relacionadas</h3><div class="documents-scroll-table crm-ui-inner-table-wrap"><table class="documents-history documents-history--guides crm-ui-inner-table"><thead><tr><th>Origen</th><th>Estado</th><th>Folio</th><th>Fecha</th><th>Destino</th><th></th></tr></thead><tbody>${guides}</tbody></table></div></div>`;
        const footerActions=[];
        if(d.can_create_guide) footerActions.push('<button class="btn btn-outline create-dispatch-guide-btn" title="Guía de despacho" aria-label="Guía de despacho" data-source-type="invoice" data-source-id="'+Number(d.id)+'"><i data-lucide="truck"></i><span>Guía de despacho</span></button>');
        if(d.can_adjust){
            footerActions.push('<button class="btn btn-outline" title="Nota de crédito" aria-label="Nota de crédito" data-adjustment="credit_note"><i data-lucide="file-minus-2"></i><span>Nota de crédito</span></button>');
            footerActions.push('<button class="btn btn-primary" title="Nota de débito" aria-label="Nota de débito" data-adjustment="debit_note"><i data-lucide="file-plus-2"></i><span>Nota de débito</span></button>');
        }
        if(!footerActions.length) footerActions.push('<button class="btn btn-outline documents-flow-close" title="Cerrar" aria-label="Cerrar"><i data-lucide="x"></i><span>Cerrar</span></button>');
        $('documentDetailFooter').innerHTML=modalFooter(footerActions.join(''));
        icons();
    }

    function openAdjustment(type){
        state.operationType=type; state.operationId=null; state.previewData=null;
        const d=state.currentDocument; const isExport=Number(d.document_type_id)===46; const label=(type==='credit_note'?'nota de crédito':'nota de débito')+(isExport?' de exportación':'');
        $('adjustmentLayerTitle').textContent=`Preparar ${label}`; $('adjustmentLayerSubtitle').textContent=`${isExport?'Factura de exportación':'Factura'} ${d.document_number} · ${d.customer_legal_name||d.customer_name||d.receiver_legal_name||''}`;
        $('adjustmentLayerBody').innerHTML=`${steps('adjustment')}<div id="adjustmentError" class="documents-layer-error"></div><div class="documents-warning">La operación se ejecutará en FACTO ${esc(state.env)}. La referencia incluirá document_id y fecha de la factura origen.${isExport?' El monto se ingresa en '+esc(d.currency_code||'moneda del documento')+'.':''}</div><div class="documents-grid crm-ui-form-grid"><div class="documents-field crm-ui-field"><label>Documento origen</label><div class="documents-readonly">${isExport?'Factura de exportación':'Factura'} ${esc(d.document_number)} · document_id ${esc(d.document_id)}</div></div><div class="documents-field crm-ui-field"><label>Fecha emisión nota</label><input id="adjustmentIssueDate" type="date" value="${today()}"></div><div class="documents-field crm-ui-field"><label>Tipo de corrección</label><select id="adjustmentMode">${type==='credit_note'?'<option value="partial">Corrección parcial de monto</option><option value="full">Anulación completa</option>':'<option value="partial">Aumento de monto</option>'}</select></div><div class="documents-field crm-ui-field"><label>Monto total del ajuste ${isExport?'('+esc(d.currency_code||'')+')':''}</label><input id="adjustmentAmount" type="number" min="${isExport?'0.01':'1'}" step="${isExport?'0.01':'1'}" value="${type==='credit_note'?'':0}"></div></div><div class="documents-field crm-ui-field"><label>Motivo tributario</label><textarea id="adjustmentReason" maxlength="255" placeholder="Describe el motivo del ajuste"></textarea></div>`;
        $('adjustmentLayerFooter').innerHTML=modalFooter('<button class="btn btn-primary" id="previewAdjustmentBtn"><i data-lucide="eye"></i><span>Previsualizar</span></button>'); setLayer('adjustment'); syncMode();
    }
    function syncMode(){ const mode=$('adjustmentMode'); const amount=$('adjustmentAmount'); if(!mode||!amount)return; if(mode.value==='full'){const d=state.currentDocument; amount.value=Number(d.document_type_id)===46?Number(d.foreign_balance_amount||d.total_amount||0).toFixed(2):Math.round(Number(d.balance_amount||d.total_amount||0));amount.disabled=true;}else{amount.disabled=false;} }

    async function previewAdjustment(){
        const btn=$('previewAdjustmentBtn'); btn.disabled=true; const err=$('adjustmentError'); err.classList.remove('show');
        const form=new URLSearchParams({source_id:String(state.currentId),environment:state.env,operation_type:state.operationType,mode:$('adjustmentMode').value,amount:$('adjustmentAmount').value,reason:$('adjustmentReason').value.trim(),issue_date:$('adjustmentIssueDate').value});
        try{ const p=await jsonFetch('/modules/billing/complementary_preview_ajax.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded;charset=UTF-8'},body:form}); state.previewData=p.data; state.operationId=Number(p.data.operation_id); renderPreview(p.data); }
        catch(e){err.textContent=e.message;err.classList.add('show');}
        finally{btn.disabled=false;}
    }
    function renderPreview(data){
        const label=operationLabel(data.operation_type); $('previewLayerTitle').textContent=`Preview FACTO ${state.env}`; $('previewLayerSubtitle').textContent=`${label} · origen ${data.source.document_number}`;
        $('previewLayerBody').innerHTML=`${steps('preview')}<div class="documents-success"><strong>Preview verificable.</strong> FACTO devolvió document_id y PDF.</div><div class="documents-summary crm-ui-summary-grid"><div class="crm-ui-summary-card"><span>Neto</span><strong>${data.source.currency_code&&data.source.currency_code!=='CLP'?new Intl.NumberFormat('es-CL',{style:'currency',currency:data.source.currency_code}).format(Number(data.amounts.net_amount||0)):money(data.amounts.net_amount)}</strong></div><div class="crm-ui-summary-card"><span>IVA</span><strong>${data.source.currency_code&&data.source.currency_code!=='CLP'?new Intl.NumberFormat('es-CL',{style:'currency',currency:data.source.currency_code}).format(Number(data.amounts.tax_amount||0)):money(data.amounts.tax_amount)}</strong></div><div class="crm-ui-summary-card"><span>Total ajuste</span><strong>${data.source.currency_code&&data.source.currency_code!=='CLP'?new Intl.NumberFormat('es-CL',{style:'currency',currency:data.source.currency_code}).format(Number(data.amounts.total_amount||0)):money(data.amounts.total_amount)}</strong></div></div><div class="documents-grid crm-ui-form-grid"><div class="documents-section crm-ui-section"><h3>Referencia</h3><p><strong>Factura:</strong> ${esc(data.source.document_number)}</p><p><strong>FACTO document_id:</strong> ${esc(data.reference.source_document_id)}</p><p><strong>Fecha referencia:</strong> ${dateText(data.reference.date)}</p><p><strong>Código:</strong> ${esc(data.reference.code)}</p></div><div class="documents-section crm-ui-section"><h3>Preview FACTO</h3><p><strong>document_id:</strong> ${esc(data.preview.document_id)}</p><p><strong>Folio preview:</strong> ${esc(data.preview.document_number||'-')}</p><p><strong>PDF:</strong> ${data.preview.pdf_available?'Disponible':'No disponible'}</p></div></div>${data.preview.pdf_available?`<h3>PDF preliminar</h3><iframe class="documents-preview-frame" src="/modules/billing/complementary_file.php?operation_id=${Number(data.operation_id)}&kind=pdf&stage=preview"></iframe>`:''}`;
        $('previewLayerFooter').innerHTML=modalFooter('<button class="btn btn-primary" id="continueConfirmBtn"><i data-lucide="arrow-right"></i><span>Continuar</span></button>'); setLayer('preview');
    }
    function renderConfirm(){
        const d=state.previewData; $('confirmLayerTitle').textContent=`Confirmar emisión ${state.env}`; $('confirmLayerSubtitle').textContent=`${operationLabel(d.operation_type)} · factura ${d.source.document_number}`;
        $('confirmLayerBody').innerHTML=`${steps('confirm')}<div id="confirmError" class="documents-layer-error"></div><div class="documents-warning"><strong>Operación tributaria irreversible.</strong> Sólo se aplicará el ajuste financiero después de recuperar y verificar el documento emitido mediante GET /documents/{document_id}.</div><div class="documents-summary crm-ui-summary-grid"><div class="crm-ui-summary-card"><span>Documento</span><strong>${esc(operationLabel(d.operation_type))}</strong></div><div class="crm-ui-summary-card"><span>Factura origen</span><strong>${esc(d.source.document_number)}</strong></div><div class="crm-ui-summary-card"><span>Total ajuste</span><strong>${d.source.currency_code&&d.source.currency_code!=='CLP'?currencyMoney(d.amounts.total_amount,d.source.currency_code):money(d.amounts.total_amount)}</strong>${d.source.currency_code&&d.source.currency_code!=='CLP'&&d.source.exchange_rate_value?`<small>≈ ${money(Number(d.amounts.total_amount||0)*Number(d.source.exchange_rate_value||0))} CLP</small>`:''}</div></div><div class="documents-field crm-ui-field"><label>Confirmación</label><input id="issueConfirmation" autocomplete="off" placeholder="Escribe ${state.env==='production'?'EMITIR PRODUCCION':'EMITIR'}"></div>`;
        $('confirmLayerFooter').innerHTML=modalFooter('<button class="btn btn-danger" id="issueAdjustmentBtn" disabled><i data-lucide="triangle-alert"></i><span>Confirmar emisión</span></button>'); setLayer('confirm');
    }
    async function issueAdjustment(){
        const btn=$('issueAdjustmentBtn'); btn.disabled=true; const err=$('confirmError'); err.classList.remove('show');
        const form=new URLSearchParams({operation_id:String(state.operationId),confirmation:$('issueConfirmation').value});
        try{ const p=await jsonFetch('/modules/billing/complementary_issue_ajax.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded;charset=UTF-8'},body:form}); renderResult(p.data); await loadDocuments(); }
        catch(e){err.textContent=e.message;err.classList.add('show');btn.disabled=false;}
    }
    function renderResult(data){
        $('resultLayerTitle').textContent=data.status==='issued'?'Emisión completada':'Resultado'; $('resultLayerSubtitle').textContent=`${operationLabel(data.operation_type)} · ${data.document_number||data.facto_document_id||''}`;
        $('resultLayerBody').innerHTML=`${steps('result')}<div class="${data.status==='issued'?'documents-success':'documents-warning'}"><strong>${data.status==='issued'?'Documento emitido y aplicado correctamente.':'Operación pendiente de revisión.'}</strong></div><div class="documents-summary crm-ui-summary-grid"><div class="crm-ui-summary-card"><span>Estado</span><strong>${esc(statusLabel(data.status))}</strong></div><div class="crm-ui-summary-card"><span>FACTO document_id</span><strong>${esc(data.facto_document_id||'-')}</strong></div><div class="crm-ui-summary-card"><span>Folio</span><strong>${esc(data.document_number||'-')}</strong></div></div><div class="documents-file-actions">${data.pdf_available?`<a target="_blank" class="btn btn-secondary" href="/modules/billing/complementary_file.php?operation_id=${Number(data.operation_id)}&kind=pdf&stage=issued">Ver PDF</a>`:''}${data.xml_available?`<a class="btn btn-secondary" href="/modules/billing/complementary_file.php?operation_id=${Number(data.operation_id)}&kind=xml&stage=issued">Descargar XML</a>`:''}</div>${data.error_message?`<div class="documents-layer-error show">${esc(data.error_message)}</div>`:''}`;
        $('resultLayerFooter').innerHTML=modalFooter('<button class="btn btn-primary" data-layer-back="detail-refresh"><i data-lucide="arrow-left"></i><span>Volver al documento</span></button>'); setLayer('result');
    }
    async function repairOperation(id){
        if(!confirm('¿Reintentar únicamente el cierre local de esta operación ya identificada en FACTO?')) return;
        const form=new URLSearchParams({operation_id:String(id)});
        try{await jsonFetch('/modules/billing/complementary_repair_ajax.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded;charset=UTF-8'},body:form}); await openDetail(state.currentId,state.currentOrigin); await loadDocuments();}
        catch(e){alert(e.message);}
    }

    on(document, 'click',(ev)=>{
        const pageButton=ev.target.closest('[data-billing-page]');
        if(pageButton&&pageButton.closest('#documentsGroups')){window.IcyBillingTable.movePage(state.paging,pageButton.dataset.billingPage,pageButton.dataset.direction,state.rows.filter(r=>groupKey(r)===pageButton.dataset.billingPage).length);renderRows();return;}
        const rowAdjustment=ev.target.closest('[data-document-adjustment-id]');
        if(rowAdjustment){openDetail(rowAdjustment.dataset.documentAdjustmentId,'issued').then(()=>openAdjustment(rowAdjustment.dataset.adjustmentType)).catch(error=>alert(error.message));return;}
        const open=ev.target.closest('.document-open-btn'); if(open){openDetail(open.dataset.id,open.dataset.origin||'issued');return;}
        const close=ev.target.closest('.documents-flow-close'); if(close){closeModal();return;}
        const adjust=ev.target.closest('[data-adjustment]'); if(adjust){openAdjustment(adjust.dataset.adjustment);return;}
        if(ev.target.closest('#previewAdjustmentBtn')){previewAdjustment();return;}
        if(ev.target.closest('#continueConfirmBtn')){renderConfirm();return;}
        if(ev.target.closest('#issueAdjustmentBtn')){issueAdjustment();return;}
        const back=ev.target.closest('[data-layer-back]'); if(back){const t=back.dataset.layerBack;if(t==='detail-refresh')openDetail(state.currentId,state.currentOrigin);else setLayer(t);return;}
        const repair=ev.target.closest('.repair-operation-btn'); if(repair){repairOperation(repair.dataset.operationId);return;}
    });
    on(document, 'change',(ev)=>{
        const pageSize=ev.target.closest('[data-billing-page-size]');
        if(pageSize&&pageSize.closest('#documentsGroups')){window.IcyBillingTable.setPageSize(state.paging,pageSize.dataset.billingPageSize,pageSize.value);renderRows();return;}
        if(ev.target.id==='adjustmentMode')syncMode();
    });
    on(document, 'billing-reference-sort',(ev)=>{
        if(!ev.target.closest('#documentsGroups'))return;
        window.IcyBillingTable.toggleSort(state.paging,ev.detail.group,ev.detail.column,ev.detail.type);
        renderRows();
    });
    on(document, 'input',(ev)=>{if(ev.target.id==='issueConfirmation'){const b=$('issueAdjustmentBtn');if(b)b.disabled=ev.target.value.trim().toUpperCase()!==(state.env==='production'?'EMITIR PRODUCCION':'EMITIR');}});
    on($('reloadDocumentsBtn'),'click',loadDocuments);
    ['documentsOrigin','documentsFamily','documentsFrom','documentsTo'].forEach(id=>on($(id),'change',loadDocuments));
    on($('documentsSearch'),'input',()=>{clearTimeout(state.searchTimer);state.searchTimer=setTimeout(loadDocuments,300);});
    on($('documentModal'),'click',e=>{if(e.target===$('documentModal'))closeModal();});
    on(document,'keydown',e=>{if(e.key==='Escape' && $('documentModal')?.classList.contains('show')) closeModal();});
    loadDocuments(); icons();
})();
