<?php
require_once '../../core/config.php';
require_once '../../core/session.php';
require_once '../../core/database.php';
require_once '../../core/auth.php';
require_once '../../core/permissions.php';
require_once '../../core/format.php';

require_login();

if (!user_can('billing.inbox') && !user_can('billing.payables') && !user_can('module.billing') && current_user_role() !== 'admin') {
    http_response_code(403);
    die('No tienes permisos para acceder a Cuentas por pagar.');
}

$page_title = 'Cuentas por pagar';

require_once '../../layouts/header.php';
require_once '../../layouts/sidebar.php';
?>

<main class="app-main billing-integrated-main" id="billingPayablesMain">
    <?php require_once '../../layouts/topbar.php'; ?>
    <section class="content billing-phase-content billing-payables-content">

<div id="payablesMain" class="payables-main">
    <div class="payables-header">
        <div>
            <h1>Cuentas por pagar</h1>
            <p>Pago individual, parcial o masivo de documentos recibidos.</p>
        </div>
        <div class="payables-header-actions">
            <select id="payablesEnv" class="payables-input">
                <option value="sandbox">Sandbox</option>
                <option value="production">Produccion</option>
            </select>
            <button type="button" class="btn btn-primary" id="reloadPayablesBtn">Actualizar</button>
        </div>
    </div>

    <div class="payables-kpis" id="payablesKpis">
        <div class="payables-kpi"><span>Documentos</span><strong>-</strong></div>
        <div class="payables-kpi"><span>Total recibido</span><strong>-</strong></div>
        <div class="payables-kpi"><span>Saldo abierto</span><strong>-</strong></div>
        <div class="payables-kpi"><span>Vencido</span><strong>-</strong></div>
        <div class="payables-kpi"><span>Sin proveedor</span><strong>-</strong></div>
        <div class="payables-kpi"><span>Sin centro</span><strong>-</strong></div>
    </div>

    <div class="payables-card">
        <div class="payables-toolbar">
            <input type="search" id="payablesSearch" class="payables-input" placeholder="Buscar proveedor, RUT o folio">
            <select id="payablesStatus" class="payables-input">
                <option value="open" selected>Impagos / parciales</option>
                <option value="all">Todos los estados</option>
                <option value="por_pagar">Por pagar</option>
                <option value="vencido">Vencido</option>
                <option value="parcial">Parcial</option>
                <option value="pagado">Pagado</option>
                <option value="rechazado">Rechazado</option>
                <option value="anulado">Anulado</option>
            </select>
            <input type="date" id="payablesFrom" class="payables-input">
            <input type="date" id="payablesTo" class="payables-input">
        </div>
        <div class="payables-bulkbar">
            <div>
                <strong id="payablesSelectedCount">0 seleccionados</strong>
                <span id="payablesSelectedTotal" class="payables-muted">Saldo seleccionado: $0</span>
            </div>
            <div class="payables-actions">
                <button type="button" class="btn btn-success" id="bulkPaymentBtn" disabled>Pagar seleccionados</button>
                <button type="button" class="btn btn-ghost" id="clearSelectionBtn" disabled>Limpiar seleccion</button>
            </div>
        </div>
        <div class="payables-table-wrap">
            <table class="payables-table">
                <thead>
                    <tr>
                        <th><input type="checkbox" id="payablesSelectAll"></th>
                        <th>Fecha</th>
                        <th>Proveedor</th>
                        <th>RUT</th>
                        <th>Tipo</th>
                        <th>Folio</th>
                        <th>Total</th>
                        <th>Pagado</th>
                        <th>Saldo</th>
                        <th>Vence</th>
                        <th>Estado</th>
                        <th>Centro</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody id="payablesRows">
                    <tr><td colspan="13">Cargando...</td></tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

<div id="payableModal" class="product-modal-backdrop" style="display:none;">
    <div class="product-modal-box payables-modal-box">
        <div class="product-modal-header">
            <div>
                <h2 id="payableModalTitle">Documento recibido</h2>
                <p id="payableModalSubtitle" class="payables-muted"></p>
            </div>
            <button type="button" class="product-modal-close" id="closePayableModalBtn">×</button>
        </div>
        <div class="product-modal-body" id="payableModalBody"></div>
        <div class="product-modal-footer" id="payableModalFooter"></div>
    </div>
</div>

<div id="payableBulkModal" class="product-modal-backdrop" style="display:none;">
    <div class="product-modal-box payables-modal-box payables-bulk-modal-box">
        <div class="product-modal-header">
            <div>
                <h2>Pago masivo proveedores</h2>
                <p id="payableBulkSubtitle" class="payables-muted"></p>
            </div>
            <button type="button" class="product-modal-close" id="closeBulkPaymentBtn">×</button>
        </div>
        <div class="product-modal-body" id="payableBulkBody"></div>
        <div class="product-modal-footer" id="payableBulkFooter"></div>
    </div>
</div>

<style>
.payables-main{padding:18px;display:flex;flex-direction:column;gap:16px;min-height:100%;}
.payables-header{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;}
.payables-header h1{margin:0;font-size:1.45rem;font-weight:800;color:#111827;}
.payables-header p{margin:4px 0 0;color:#6b7280;font-size:.9rem;}
.payables-header-actions{display:flex;gap:8px;align-items:center;}
.payables-kpis{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:10px;}
.payables-kpi{background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:12px;box-shadow:0 1px 3px rgba(15,23,42,.05);}
.payables-kpi span{display:block;font-size:.72rem;text-transform:uppercase;letter-spacing:.04em;color:#6b7280;font-weight:700;}
.payables-kpi strong{display:block;margin-top:5px;font-size:1.05rem;color:#111827;}
.payables-card{background:#fff;border:1px solid #e5e7eb;border-radius:16px;box-shadow:0 2px 8px rgba(15,23,42,.05);min-height:0;display:flex;flex-direction:column;}
.payables-toolbar{display:grid;grid-template-columns:1fr 180px 150px 150px;gap:8px;padding:12px;border-bottom:1px solid #e5e7eb;}
.payables-bulkbar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;border-bottom:1px solid #e5e7eb;background:#f9fafb;}
.payables-bulkbar>div:first-child{display:flex;gap:12px;align-items:center;flex-wrap:wrap;}
.payables-input{height:38px;border:1px solid #d1d5db;border-radius:10px;padding:0 10px;font-size:.88rem;background:#fff;color:#111827;}
.payables-table-wrap{overflow:auto;max-height:calc(100vh - 340px);}
.payables-table{width:100%;border-collapse:separate;border-spacing:0;font-size:.84rem;}
.payables-table th{position:sticky;top:0;background:#f9fafb;z-index:1;text-align:left;color:#374151;font-size:.72rem;text-transform:uppercase;letter-spacing:.04em;border-bottom:1px solid #e5e7eb;padding:10px;}
.payables-table td{border-bottom:1px solid #f1f5f9;padding:10px;vertical-align:middle;color:#111827;}
.payables-table tr:hover td{background:#f9fafb;}
.payables-table input[type="checkbox"]{width:16px;height:16px;}
.payables-number{text-align:right;white-space:nowrap;}
.payables-status{display:inline-flex;align-items:center;border-radius:999px;padding:4px 8px;font-size:.75rem;font-weight:800;background:#eef2ff;color:#3730a3;}
.payables-status.vencido{background:#fee2e2;color:#991b1b;}
.payables-status.pagado{background:#dcfce7;color:#166534;}
.payables-status.parcial{background:#fef3c7;color:#92400e;}
.payables-status.rechazado,.payables-status.anulado{background:#f3f4f6;color:#374151;}
.payables-resolution{display:inline-flex;align-items:center;border-radius:999px;padding:4px 8px;font-size:.72rem;font-weight:800;background:#ecfdf5;color:#166534;}
.payables-resolution.pending,.payables-resolution.missing_rut,.payables-resolution.error{background:#f3f4f6;color:#374151;}
.payables-resolution.created_from_dte{background:#dbeafe;color:#1d4ed8;}
.payables-readonly-status{display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
.payables-readonly-status small{color:#6b7280;}
.payables-muted{color:#6b7280;font-size:.86rem;margin:0;}
.payables-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;}
.payables-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;}
.payables-section{border:1px solid #e5e7eb;border-radius:14px;padding:12px;background:#fff;}
.payables-section h3{font-size:.9rem;margin:0 0 10px;color:#111827;}
.payables-field{display:flex;flex-direction:column;gap:5px;margin-bottom:10px;}
.payables-field label{font-size:.75rem;font-weight:800;color:#374151;text-transform:uppercase;letter-spacing:.04em;}
.payables-field input,.payables-field select,.payables-field textarea{border:1px solid #d1d5db;border-radius:10px;padding:9px 10px;font-size:.88rem;}
.payables-field textarea{min-height:74px;resize:vertical;}
.payables-summary{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-bottom:12px;}
.payables-summary-card{border:1px solid #e5e7eb;border-radius:12px;padding:10px;background:#f9fafb;}
.payables-summary-card span{display:block;color:#6b7280;font-size:.72rem;font-weight:800;text-transform:uppercase;letter-spacing:.04em;}
.payables-summary-card strong{display:block;margin-top:4px;font-size:1.1rem;}
.payables-payment-history{width:100%;border-collapse:separate;border-spacing:0;font-size:.82rem;}
.payables-payment-history th{background:#f9fafb;text-align:left;color:#374151;font-size:.7rem;text-transform:uppercase;letter-spacing:.04em;border-bottom:1px solid #e5e7eb;padding:8px;}
.payables-payment-history td{border-bottom:1px solid #f1f5f9;padding:8px;}
.payables-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center;}
.payables-bulk-result{border:1px solid #e5e7eb;border-radius:12px;overflow:hidden;}
.payables-bulk-result table{width:100%;border-collapse:collapse;font-size:.82rem;}
.payables-bulk-result th,.payables-bulk-result td{padding:8px;border-bottom:1px solid #f1f5f9;text-align:left;}
.payables-bulk-result th{background:#f9fafb;text-transform:uppercase;font-size:.7rem;color:#374151;}
#payablesMain .btn, #payableModal .btn, #payableBulkModal .btn{border:0;border-radius:10px;padding:9px 13px;font-weight:800;cursor:pointer;text-decoration:none;display:inline-flex;align-items:center;justify-content:center;gap:6px;font-size:.86rem;}
#payablesMain .btn-primary, #payableModal .btn-primary, #payableBulkModal .btn-primary{background:#2563eb;color:#fff;}
#payablesMain .btn-success, #payableModal .btn-success, #payableBulkModal .btn-success{background:#16a34a;color:#fff;}
#payablesMain .btn-warning, #payableModal .btn-warning, #payableBulkModal .btn-warning{background:#f59e0b;color:#111827;}
#payablesMain .btn-danger, #payableModal .btn-danger, #payableBulkModal .btn-danger{background:#dc2626;color:#fff;}
#payablesMain .btn-ghost, #payableModal .btn-ghost, #payableBulkModal .btn-ghost{background:#f3f4f6;color:#111827;}
#payablesMain .btn-outline, #payableModal .btn-outline, #payableBulkModal .btn-outline{background:#fff;border:1px solid #d1d5db;color:#111827;}
#payablesMain .btn:disabled, #payableModal .btn:disabled, #payableBulkModal .btn:disabled{opacity:.45;cursor:not-allowed;}
@media(max-width:900px){.payables-header{flex-direction:column}.payables-header-actions{width:100%}.payables-header-actions>*{flex:1}.payables-kpis{grid-template-columns:repeat(2,minmax(0,1fr))}.payables-toolbar{grid-template-columns:1fr}.payables-bulkbar{align-items:flex-start;flex-direction:column}.payables-table{min-width:1180px}.payables-grid,.payables-grid-3,.payables-summary{grid-template-columns:1fr}.payables-modal-box{width:96vw;max-width:96vw}}
</style>

<script>
(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();
})();
</script>

    </section>
</main>
<?php require_once '../../layouts/footer.php'; ?>
