
(function(){
    const state = { env: 'sandbox', rows: [], options: null, current: null, currentPayments: [], selected: new Set() };
    const $ = (id) => document.getElementById(id);
    const today = () => new Date().toISOString().slice(0,10);
    const fmtMoney = (v) => '$' + Math.round(Number(v || 0)).toLocaleString('es-CL');
    const esc = (s) => String(s == null ? '' : s).replace(/[&<>'"]/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;',"'":'&#39;','"':'&quot;'}[c]));
    const statusLabel = (s) => ({por_pagar:'Por pagar',vencido:'Vencido',parcial:'Parcial',pagado:'Pagado',rechazado:'Rechazado',anulado:'Anulado'}[s] || s || 'Por pagar');
    const balanceOf = (r) => Number(r.balance_amount != null ? r.balance_amount : r.total_amount || 0);

    async function jsonFetch(url, options){
        const res = await fetch(url, options || {});
        const text = await res.text();
        let data;
        try { data = JSON.parse(text); } catch(e) { throw new Error(text || 'Respuesta no valida.'); }
        if (!res.ok || data.success === false) throw new Error(data.message || 'Error de solicitud.');
        return data;
    }

    function formData(obj){ const fd = new FormData(); Object.keys(obj).forEach(k => fd.append(k, obj[k] == null ? '' : obj[k])); return fd; }

    async function loadPayables(){
        const env = $('payablesEnv').value;
        state.env = env;
        state.selected.clear();
        updateSelectionUi();
        $('payablesRows').innerHTML = '<tr><td colspan="13">Cargando...</td></tr>';
        const q = new URLSearchParams({
            env: env,
            status: $('payablesStatus').value,
            search: $('payablesSearch').value,
            date_from: $('payablesFrom').value,
            date_to: $('payablesTo').value,
            limit: '120'
        });
        try {
            const data = await jsonFetch('payables_list_ajax.php?' + q.toString());
            state.rows = data.data.rows || [];
            state.options = data.data.options || null;
            renderKpis(data.data.kpis || {});
            renderRows();
        } catch(e) {
            $('payablesRows').innerHTML = '<tr><td colspan="13">' + esc(e.message) + '</td></tr>';
        }
    }

    function renderKpis(k){
        const values = [
            k.documents_count || 0,
            fmtMoney(k.total_received),
            fmtMoney(k.open_balance),
            fmtMoney(k.overdue_balance),
            k.unlinked_suppliers || 0,
            k.without_center || 0
        ];
        $('payablesKpis').querySelectorAll('strong').forEach((el, i) => el.textContent = values[i]);
    }

    function renderRows(){
        if (!state.rows.length) {
            $('payablesRows').innerHTML = '<tr><td colspan="13">Sin documentos recibidos para los filtros seleccionados.</td></tr>';
            $('payablesSelectAll').checked = false;
            return;
        }
        $('payablesRows').innerHTML = state.rows.map(r => {
            const status = r.collection_status || r.payment_status || 'por_pagar';
            const balance = balanceOf(r);
            const canPay = balance > 0.5 && !['pagado','rechazado','anulado'].includes(status);
            const checked = state.selected.has(String(r.id)) ? 'checked' : '';
            return `<tr>
                <td><input type="checkbox" class="payable-select" data-payable-id="${esc(r.id)}" ${checked} ${canPay ? '' : 'disabled'}></td>
                <td>${esc(r.document_date || '-')}</td>
                <td><strong>${esc(r.supplier_name || r.issuer_name || 'Sin proveedor')}</strong></td>
                <td>${esc(r.issuer_tax_id_code || '-')}</td>
                <td>${esc(r.document_type_taxbureau || r.document_type_id || '-')}</td>
                <td>${esc(r.document_number || '-')}</td>
                <td class="payables-number"><strong>${fmtMoney(r.total_amount)}</strong></td>
                <td class="payables-number">${fmtMoney(r.paid_amount)}</td>
                <td class="payables-number"><strong>${fmtMoney(balance)}</strong></td>
                <td>${esc(r.due_date || r.payment_due_date || '-')}</td>
                <td><span class="payables-status ${esc(status)}">${esc(statusLabel(status))}</span></td>
                <td>${esc(r.finance_center_name || 'Sin centro')}</td>
                <td><button type="button" class="btn btn-outline" data-payable-detail="${esc(r.id)}">Ver / pagar</button></td>
            </tr>`;
        }).join('');
        updateSelectionUi();
    }

    async function openDetail(id){
        const q = new URLSearchParams({id: id, env: state.env});
        const data = await jsonFetch('payable_detail_ajax.php?' + q.toString());
        state.current = data.document;
        state.currentPayments = data.payments || [];
        state.options = data.options || state.options;
        renderDetail(data.document, state.currentPayments);
        $('payableModal').style.display = 'flex';
        $('payableModal').classList.add('show');
    }

    function optionHtml(items, idKey, labelKey, selected){
        return (items || []).map(i => `<option value="${esc(i[idKey])}" ${String(i[idKey]) === String(selected || '') ? 'selected' : ''}>${esc(i[labelKey])}</option>`).join('');
    }

    function renderPayments(payments){
        if (!payments || !payments.length) {
            return '<p class="payables-muted">No hay pagos registrados para este documento.</p>';
        }
        return `<table class="payables-payment-history">
            <thead><tr><th>Fecha</th><th>Monto</th><th>Metodo</th><th>Caja/cuenta</th><th>Referencia</th><th>Nota</th></tr></thead>
            <tbody>${payments.map(p => `<tr>
                <td>${esc(p.payment_date || '-')}</td>
                <td><strong>${fmtMoney(p.amount)}</strong></td>
                <td>${esc(p.method_name || p.payment_method || '-')}</td>
                <td>${esc(p.account_name || '-')}</td>
                <td>${esc(p.external_reference || p.batch_reference || '-')}</td>
                <td>${esc(p.notes || '-')}</td>
            </tr>`).join('')}</tbody>
        </table>`;
    }

    function renderDetail(d, payments){
        const status = d.collection_status || d.payment_status || 'por_pagar';
        const balance = balanceOf(d);
        const paid = Number(d.paid_amount || 0);
        const resolution = d.supplier_resolution_status || (d.supplier_customer_id ? 'matched_existing' : 'pending');
        const resolutionLabel = {matched_existing:'Proveedor vinculado',created_from_dte:'Proveedor creado desde DTE',missing_rut:'Sin RUT usable',pending:'Pendiente',error:'Error'}[resolution] || resolution;
        const paymentTermLabel = d.supplier_payment_term_label || 'Contado';
        const paymentTermDays = d.supplier_payment_term_days != null ? Number(d.supplier_payment_term_days) : 0;
        $('payableModalTitle').textContent = 'DTE recibido ' + (d.document_number || '');
        $('payableModalSubtitle').textContent = (d.issuer_name || 'Proveedor sin nombre') + ' · ' + (d.issuer_tax_id_code || 'Sin RUT') + ' · ' + state.env;
        const centers = state.options ? state.options.finance_centers : [];
        const methods = state.options ? state.options.payment_methods : [];
        const accounts = state.options ? state.options.cash_accounts : [];
        $('payableModalBody').innerHTML = `
            <div class="payables-summary">
                <div class="payables-summary-card"><span>Total documento</span><strong>${fmtMoney(d.total_amount)}</strong></div>
                <div class="payables-summary-card"><span>Total pagado</span><strong>${fmtMoney(paid)}</strong></div>
                <div class="payables-summary-card"><span>Saldo pendiente</span><strong>${fmtMoney(balance)}</strong></div>
            </div>
            <div class="payables-grid">
                <div class="payables-section">
                    <h3>Documento</h3>
                    <p><strong>Proveedor:</strong> ${esc(d.supplier_name || d.issuer_name || 'Sin homologar')}</p>
                    <p><strong>RUT:</strong> ${esc(d.issuer_tax_id_code || '-')}</p>
                    <p><strong>Tipo:</strong> ${esc(d.document_type_taxbureau || d.document_type_id || '-')}</p>
                    <p><strong>Folio:</strong> ${esc(d.document_number || '-')}</p>
                    <p><strong>Fecha:</strong> ${esc(d.document_date || '-')}</p>
                    <p><strong>Neto:</strong> ${fmtMoney(d.net_amount)} · <strong>IVA:</strong> ${fmtMoney(d.taxes_amount)} · <strong>Total:</strong> ${fmtMoney(d.total_amount)}</p>
                    <p><strong>Estado:</strong> <span class="payables-status ${esc(status)}">${esc(statusLabel(status))}</span></p>
                    <p><strong>Proveedor:</strong> <span class="payables-resolution ${esc(resolution)}">${esc(resolutionLabel)}</span></p>
                    <p class="payables-muted">${esc(d.supplier_resolution_notes || '')}</p>
                    <div class="payables-actions">
                        ${d.pdf_file_path ? `<a class="btn btn-outline" target="_blank" href="payable_file.php?id=${esc(d.id)}&env=${esc(state.env)}&type=pdf">Ver PDF</a>` : ''}
                        ${d.xml_file_path ? `<a class="btn btn-outline" target="_blank" href="payable_file.php?id=${esc(d.id)}&env=${esc(state.env)}&type=xml">Descargar XML</a>` : ''}
                        ${d.supplier_customer_id ? '' : '<button type="button" class="btn btn-ghost" id="linkSupplierBtn">Resolver / crear proveedor por RUT</button>'}
                    </div>
                </div>
                <div class="payables-section">
                    <h3>Ajustes financieros del DTE</h3>
                    <form id="payableUpdateForm">
                        <div class="payables-field"><label>Centro de costo</label><select name="finance_center_id"><option value="">${d.supplier_default_cost_center_id ? 'Usar centro del proveedor' : 'Sin centro'}</option>${optionHtml(centers, 'id', 'center_name', d.effective_finance_center_id || d.finance_center_id || d.supplier_default_cost_center_id)}</select><small>${d.finance_center_source === 'supplier_default' ? 'Valor heredado desde la ficha del proveedor. Puedes cambiarlo sólo para este DTE.' : (d.finance_center_source === 'document_override' ? 'Centro definido específicamente para este DTE.' : 'Proveedor sin centro de costo definido.')}</small></div>
                        <div class="payables-field"><label>Condicion de pago proveedor</label><div class="payables-readonly-status"><span class="payables-resolution">${esc(paymentTermLabel)}</span><small>${paymentTermDays} dias. Se usa para calcular el vencimiento automaticamente.</small></div></div>
                        <div class="payables-field"><label>Fecha vencimiento</label><div class="payables-readonly-status"><span>${esc(d.due_date || d.payment_due_date || 'Vencida / sin fecha calculable')}</span><small>Calculada desde la condicion de pago del proveedor. Si no hay proveedor o condicion, se usa contado; si no hay fecha base valida, queda vencida.</small></div></div>
                        <div class="payables-field"><label>Estado financiero</label><div class="payables-readonly-status"><span class="payables-status ${esc(status)}">${esc(statusLabel(status))}</span><small>Calculado por saldo, pagos y vencimiento.</small></div></div>
                        <div class="payables-field"><label>Nota interna</label><textarea name="notes">${esc(d.collection_notes || '')}</textarea></div>
                    </form>
                    <button type="button" class="btn btn-primary" id="savePayableBtn">Guardar ajustes financieros</button>
                </div>
            </div>
            <div class="payables-section" style="margin-top:12px;">
                <h3>Registrar pago individual / parcial</h3>
                <form id="payablePaymentForm" class="payables-grid-3">
                    <div class="payables-field"><label>Fecha pago</label><input type="date" name="payment_date" value="${today()}"></div>
                    <div class="payables-field"><label>Monto a pagar</label><input type="number" name="amount" min="1" step="1" max="${Math.round(balance)}" value="${Math.round(balance)}" ${balance <= 0.5 ? 'disabled' : ''}></div>
                    <div class="payables-field"><label>Metodo de pago</label><select name="payment_method_id" ${balance <= 0.5 ? 'disabled' : ''}><option value="">Seleccionar</option>${optionHtml(methods, 'id', 'method_name', '')}</select></div>
                    <div class="payables-field"><label>Caja/cuenta origen</label><select name="cash_account_id" ${balance <= 0.5 ? 'disabled' : ''}><option value="">Seleccionar</option>${optionHtml(accounts, 'id', 'account_name', '')}</select></div>
                    <div class="payables-field"><label>Referencia</label><input type="text" name="external_reference" placeholder="Transferencia, voucher, folio" ${balance <= 0.5 ? 'disabled' : ''}></div>
                    <div class="payables-field"><label>Nota pago</label><input type="text" name="notes" placeholder="Observacion interna" ${balance <= 0.5 ? 'disabled' : ''}></div>
                </form>
                <button type="button" class="btn btn-success" id="registerPayablePaymentBtn" disabled>Registrar pago</button>
                <p class="payables-muted" style="margin-top:8px;">Puedes registrar pagos parciales. Si el saldo llega a $0, el documento queda como pagado.</p>
            </div>
            <div class="payables-section" style="margin-top:12px;">
                <h3>Historial de pagos</h3>
                ${renderPayments(payments)}
            </div>
`;
        $('payableModalFooter').innerHTML = '<button type="button" class="btn btn-ghost" id="closePayableFooterBtn">Cerrar</button>';
        bindPaymentValidation();
    }

    function bindPaymentValidation(){
        const form = $('payablePaymentForm');
        const btn = $('registerPayablePaymentBtn');
        if (!form || !btn) return;
        const validate = () => {
            const amount = Number(form.amount.value || 0);
            const max = Number(form.amount.getAttribute('max') || 0);
            btn.disabled = !(form.payment_date.value && amount > 0 && amount <= max && form.payment_method_id.value && form.cash_account_id.value);
        };
        form.querySelectorAll('input,select').forEach(el => el.addEventListener('input', validate));
        form.querySelectorAll('select,input[type="date"]').forEach(el => el.addEventListener('change', validate));
        validate();
    }

    async function savePayable(){
        const fd = new FormData($('payableUpdateForm'));
        fd.append('id', state.current.id);
        fd.append('environment', state.env);
        const data = await jsonFetch('payable_update_ajax.php', {method:'POST', body:fd});
        state.current = data.result.document;
        await loadPayables();
        await openDetail(state.current.id);
    }

    async function registerPayment(){
        const fd = new FormData($('payablePaymentForm'));
        fd.append('id', state.current.id);
        fd.append('environment', state.env);
        const data = await jsonFetch('payable_register_payment_ajax.php', {method:'POST', body:fd});
        state.current = data.document;
        state.currentPayments = data.payments || [];
        await loadPayables();
        renderDetail(state.current, state.currentPayments);
    }

    async function linkSupplier(){
        const fd = formData({id: state.current.id, environment: state.env});
        const data = await jsonFetch('payable_link_supplier_ajax.php', {method:'POST', body:fd});
        state.current = data.result.document;
        await loadPayables();
        await openDetail(state.current.id);
    }

    async function inboxAction(action){
        if (!confirm('Confirmar accion FACTO: ' + action + '?')) return;
        const fd = formData({id: state.current.id, environment: state.env, action: action});
        const data = await jsonFetch('payable_accept_reject_ajax.php', {method:'POST', body:fd});
        state.current = data.document;
        await loadPayables();
        renderDetail(state.current, state.currentPayments);
    }

    function selectedRows(){
        return state.rows.filter(r => state.selected.has(String(r.id)) && balanceOf(r) > 0.5);
    }

    function updateSelectionUi(){
        const rows = selectedRows();
        const total = rows.reduce((sum, r) => sum + balanceOf(r), 0);
        $('payablesSelectedCount').textContent = rows.length + ' seleccionados';
        $('payablesSelectedTotal').textContent = 'Saldo seleccionado: ' + fmtMoney(total);
        $('bulkPaymentBtn').disabled = rows.length === 0;
        $('clearSelectionBtn').disabled = rows.length === 0;
        const available = state.rows.filter(r => balanceOf(r) > 0.5 && !['pagado','rechazado','anulado'].includes(r.collection_status || r.payment_status || 'por_pagar'));
        $('payablesSelectAll').checked = available.length > 0 && available.every(r => state.selected.has(String(r.id)));
    }

    function openBulkPayment(){
        const rows = selectedRows();
        if (!rows.length) return;
        const total = rows.reduce((sum, r) => sum + balanceOf(r), 0);
        const methods = state.options ? state.options.payment_methods : [];
        const accounts = state.options ? state.options.cash_accounts : [];
        $('payableBulkSubtitle').textContent = rows.length + ' documentos · saldo seleccionado ' + fmtMoney(total);
        $('payableBulkBody').innerHTML = `
            <div class="payables-summary">
                <div class="payables-summary-card"><span>Documentos</span><strong>${rows.length}</strong></div>
                <div class="payables-summary-card"><span>Saldo seleccionado</span><strong>${fmtMoney(total)}</strong></div>
                <div class="payables-summary-card"><span>Modo</span><strong>Pago masivo</strong></div>
            </div>
            <div class="payables-section">
                <h3>Datos del pago</h3>
                <form id="bulkPaymentForm" class="payables-grid-3">
                    <div class="payables-field"><label>Fecha pago</label><input type="date" name="payment_date" value="${today()}"></div>
                    <div class="payables-field"><label>Monto total a aplicar</label><input type="number" name="amount" min="1" step="1" max="${Math.round(total)}" value="${Math.round(total)}"></div>
                    <div class="payables-field"><label>Metodo de pago</label><select name="payment_method_id"><option value="">Seleccionar</option>${optionHtml(methods, 'id', 'method_name', '')}</select></div>
                    <div class="payables-field"><label>Caja/cuenta origen</label><select name="cash_account_id"><option value="">Seleccionar</option>${optionHtml(accounts, 'id', 'account_name', '')}</select></div>
                    <div class="payables-field"><label>Referencia</label><input type="text" name="external_reference" placeholder="Transferencia, voucher, folio"></div>
                    <div class="payables-field"><label>Nota pago</label><input type="text" name="notes" placeholder="Observacion interna"></div>
                    <label style="display:flex;align-items:center;gap:8px;font-weight:700;"><input type="checkbox" name="full_payment" value="1" checked> Pagar saldo completo de seleccionados</label>
                </form>
                <p class="payables-muted">Si el monto es menor al saldo seleccionado, se imputara por orden de seleccion hasta agotar el monto.</p>
            </div>
            <div class="payables-section" style="margin-top:12px;">
                <h3>Documentos seleccionados</h3>
                <div class="payables-bulk-result"><table>
                    <thead><tr><th>Proveedor</th><th>Folio</th><th>Saldo</th></tr></thead>
                    <tbody>${rows.map(r => `<tr><td>${esc(r.supplier_name || r.issuer_name || 'Sin proveedor')}</td><td>${esc(r.document_number || '-')}</td><td><strong>${fmtMoney(balanceOf(r))}</strong></td></tr>`).join('')}</tbody>
                </table></div>
            </div>`;
        $('payableBulkFooter').innerHTML = '<button type="button" class="btn btn-ghost" id="cancelBulkPaymentBtn">Cancelar</button><button type="button" class="btn btn-success" id="confirmBulkPaymentBtn" disabled>Registrar pago masivo</button>';
        $('payableBulkModal').style.display = 'flex';
        $('payableBulkModal').classList.add('show');
        bindBulkValidation(total);
    }

    function bindBulkValidation(total){
        const form = $('bulkPaymentForm');
        const btn = $('confirmBulkPaymentBtn');
        const amount = form.amount;
        const full = form.full_payment;
        const sync = () => {
            if (full.checked) {
                amount.value = Math.round(total);
                amount.disabled = true;
            } else {
                amount.disabled = false;
            }
            const value = Number(amount.value || 0);
            btn.disabled = !(form.payment_date.value && value > 0 && value <= total + 0.5 && form.payment_method_id.value && form.cash_account_id.value);
        };
        form.querySelectorAll('input,select').forEach(el => el.addEventListener('input', sync));
        form.querySelectorAll('select,input[type="date"],input[type="checkbox"]').forEach(el => el.addEventListener('change', sync));
        sync();
    }

    async function submitBulkPayment(){
        const rows = selectedRows();
        if (!rows.length) return;
        const form = $('bulkPaymentForm');
        const fd = new FormData(form);
        fd.append('environment', state.env);
        fd.append('ids', JSON.stringify(rows.map(r => r.id)));
        if (!form.full_payment.checked) fd.set('full_payment', '0');
        const data = await jsonFetch('payable_bulk_payment_ajax.php', {method:'POST', body:fd});
        renderBulkResult(data.result);
        state.selected.clear();
        await loadPayables();
    }

    function renderBulkResult(result){
        $('payableBulkSubtitle').textContent = 'Batch #' + result.batch_id + ' · aplicado ' + fmtMoney(result.amount_allocated);
        $('payableBulkBody').innerHTML = `
            <div class="payables-summary">
                <div class="payables-summary-card"><span>Monto informado</span><strong>${fmtMoney(result.amount_total)}</strong></div>
                <div class="payables-summary-card"><span>Monto aplicado</span><strong>${fmtMoney(result.amount_allocated)}</strong></div>
                <div class="payables-summary-card"><span>No asignado</span><strong>${fmtMoney(result.unallocated)}</strong></div>
            </div>
            <div class="payables-section">
                <h3>Resultado por documento</h3>
                <div class="payables-bulk-result"><table>
                    <thead><tr><th>Proveedor</th><th>Folio</th><th>Aplicado</th><th>Saldo posterior</th><th>Estado</th></tr></thead>
                    <tbody>${(result.processed || []).map(r => `<tr><td>${esc(r.supplier || '-')}</td><td>${esc(r.folio || '-')}</td><td><strong>${fmtMoney(r.amount_applied)}</strong></td><td>${fmtMoney(r.balance_after)}</td><td>${esc(statusLabel(r.status_after))}</td></tr>`).join('')}</tbody>
                </table></div>
            </div>`;
        $('payableBulkFooter').innerHTML = '<button type="button" class="btn btn-primary" id="closeBulkPaymentResultBtn">Cerrar</button>';
    }

    function closeModal(){ $('payableModal').style.display = 'none'; $('payableModal').classList.remove('show'); }
    function closeBulk(){ $('payableBulkModal').style.display = 'none'; $('payableBulkModal').classList.remove('show'); }

    document.addEventListener('click', function(e){
        const detailBtn = e.target.closest('[data-payable-detail]');
        if (detailBtn) { openDetail(detailBtn.getAttribute('data-payable-detail')).catch(err => alert(err.message)); return; }
        if (e.target.id === 'reloadPayablesBtn') { loadPayables(); return; }
        if (e.target.id === 'closePayableModalBtn' || e.target.id === 'closePayableFooterBtn') { closeModal(); return; }
        if (e.target.id === 'closeBulkPaymentBtn' || e.target.id === 'cancelBulkPaymentBtn' || e.target.id === 'closeBulkPaymentResultBtn') { closeBulk(); return; }
        if (e.target.id === 'savePayableBtn') { savePayable().catch(err => alert(err.message)); return; }
        if (e.target.id === 'registerPayablePaymentBtn') { registerPayment().catch(err => alert(err.message)); return; }
        if (e.target.id === 'linkSupplierBtn') { linkSupplier().catch(err => alert(err.message)); return; }
        if (e.target.id === 'bulkPaymentBtn') { openBulkPayment(); return; }
        if (e.target.id === 'confirmBulkPaymentBtn') { submitBulkPayment().catch(err => alert(err.message)); return; }
        if (e.target.id === 'clearSelectionBtn') { state.selected.clear(); renderRows(); return; }
        const inboxBtn = e.target.closest('[data-inbox-action]');
        if (inboxBtn) { inboxAction(inboxBtn.getAttribute('data-inbox-action')).catch(err => alert(err.message)); return; }
    });

    document.addEventListener('change', function(e){
        if (e.target.classList.contains('payable-select')) {
            const id = String(e.target.getAttribute('data-payable-id'));
            if (e.target.checked) state.selected.add(id); else state.selected.delete(id);
            updateSelectionUi();
            return;
        }
        if (e.target.id === 'payablesSelectAll') {
            const checked = e.target.checked;
            state.rows.forEach(r => {
                const status = r.collection_status || r.payment_status || 'por_pagar';
                if (balanceOf(r) > 0.5 && !['pagado','rechazado','anulado'].includes(status)) {
                    if (checked) state.selected.add(String(r.id)); else state.selected.delete(String(r.id));
                }
            });
            renderRows();
            return;
        }
    });

    ['payablesEnv','payablesStatus','payablesFrom','payablesTo'].forEach(id => $(id).addEventListener('change', loadPayables));
    $('payablesSearch').addEventListener('keydown', function(e){ if (e.key === 'Enter') loadPayables(); });
    loadPayables();
})();
