var ConsultaOC = Object.assign({}, TablaGenerica);

ConsultaOC._fechaHoraStr = function() {
    var a = new Date();
    return a.toLocaleDateString('es-PE', { day: '2-digit', month: '2-digit', year: 'numeric' }) + ' ' + a.toLocaleTimeString('es-PE', { hour: '2-digit', minute: '2-digit' });
};

ConsultaOC._imprimirSrcdoc = function(html, titulo) {
    var fullHtml = '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>' + (titulo || 'Reporte') + '</title>' +
        '<link rel="preconnect" href="https://fonts.googleapis.com"><link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">' +
        '<style>' +
        '*{margin:0;padding:0;box-sizing:border-box}' +
        'body{font-family:"Plus Jakarta Sans",sans-serif;padding:30px 40px;color:#1E293B}' +
        '.prov-print-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:16px;padding-bottom:12px;border-bottom:2px solid #1A4480}' +
        '.prov-print-titulo{font-size:1.2rem;font-weight:800;color:#1A4480;text-transform:uppercase;letter-spacing:0.5px}' +
        '.prov-print-info{text-align:right}' +
        '.prov-print-fecha{font-size:0.65rem;color:#64748B;margin-bottom:4px}' +
        '.prov-print-filtros{font-size:0.72rem;color:#475569;background:#F1F5F9;padding:5px 10px;border-radius:6px;margin-bottom:14px}' +
        'table{width:100%;border-collapse:collapse;font-size:0.72rem}' +
        'thead th{background:#1A4480;color:#FFF;padding:7px 8px;text-align:left;font-weight:700;text-transform:uppercase;font-size:0.6rem;letter-spacing:0.5px;border-bottom:2px solid #0F2847}' +
        '.oc-det-tbl td{padding:5px 8px;border-bottom:1px solid #E2E8F0;color:#334155}' +
        'tbody tr:nth-child(even){background:#F8FAFC}' +
        '.prov-print-total{font-size:0.75rem;color:#1A4480;font-weight:600;margin-top:12px}' +
        '.prov-print-footer{text-align:center;font-size:0.65rem;color:#94A3B8;margin-top:20px;border-top:1px solid #E2E8F0;padding-top:8px}' +
        '@page{margin:12mm;@bottom-center{content:counter(page);font-family:"Plus Jakarta Sans",sans-serif;font-size:0.65rem;color:#94A3B8}}' +
        '<' + 'script' + '>window.onload=function(){setTimeout(function(){window.print()},800)};<' + '/' + 'script' + '>' +
        '</style></head><body>' + html + '<div class="prov-print-footer">NexusERP</div></body></html>';

    var oldIframe = document.getElementById('cons-oc-print-frame');
    if (oldIframe) document.body.removeChild(oldIframe);
    var iframe = document.createElement('iframe');
    iframe.id = 'cons-oc-print-frame';
    iframe.style.cssText = 'position:absolute;width:1px;height:1px;opacity:0.01;top:-9999px;left:-9999px';
    iframe.srcdoc = fullHtml;
    document.body.appendChild(iframe);
    iframe.onload = function() {
        setTimeout(function() {
            try { iframe.contentWindow.print(); } catch(e) {}
        }, 1500);
    };
};

var _consOCMostrarVista = ConsultaOC.mostrarVista;
ConsultaOC.mostrarVista = function() {
    var self = this;

    var _origCargar = this.cargarTabla;
    var skipFirst = true;
    this.cargarTabla = function() {
        if (skipFirst) { skipFirst = false; return Promise.resolve(); }
        return _origCargar.apply(this, arguments);
    };
    _consOCMostrarVista.call(this);
    this.cargarTabla = _origCargar;

    var wrap = document.getElementById(this.elementId + 'TablaWrap');
    if (!wrap) return;

    var oldBar = document.getElementById('consOCFechaBar');
    if (oldBar) oldBar.remove();

    var hoy = new Date();
    var fmtHoy = hoy.toISOString().split('T')[0];
    var fmtMes = new Date(hoy.getFullYear(), hoy.getMonth(), 1).toISOString().split('T')[0];

    var bar = document.createElement('div');
    bar.id = 'consOCFechaBar';
    bar.style.cssText = 'display:flex;align-items:center;gap:10px;padding:10px 20px;background:#f8fafc;border-bottom:1px solid #e2e8f0;font-size:0.82rem';
    bar.innerHTML =
        '<i class="fas fa-calendar-alt" style="color:#1A4480;font-size:0.9rem"></i>' +
        '<span style="color:#475569;font-weight:600">Desde:</span>' +
        '<input type="date" id="consOCFechaDesde" class="prov-input" value="' + fmtMes + '" style="width:150px;padding:5px 8px;font-size:0.8rem">' +
        '<span style="color:#475569;font-weight:600">Hasta:</span>' +
        '<input type="date" id="consOCFechaHasta" class="prov-input" value="' + fmtHoy + '" style="width:150px;padding:5px 8px;font-size:0.8rem">' +
        '<button class="btn-prov btn-prov-primario" id="consOCBtnLimpiarFecha" style="padding:5px 14px;font-size:0.78rem">Limpiar</button>';

    wrap.parentNode.insertBefore(bar, wrap);

    function recargar() {
        self.paginaActual = 1;
        self.cargarTabla();
    }
    document.getElementById('consOCFechaDesde').addEventListener('change', recargar);
    document.getElementById('consOCFechaHasta').addEventListener('change', recargar);
    document.getElementById('consOCBtnLimpiarFecha').addEventListener('click', function() {
        document.getElementById('consOCFechaDesde').value = fmtMes;
        document.getElementById('consOCFechaHasta').value = fmtHoy;
        recargar();
    });

    self.cargarTabla();
};

ConsultaOC.obtenerParamsExtra = function() {
    var desde = document.getElementById('consOCFechaDesde');
    var hasta = document.getElementById('consOCFechaHasta');
    var s = '';
    if (desde && desde.value) s += '&fecha_desde=' + encodeURIComponent(desde.value);
    if (hasta && hasta.value) s += '&fecha_hasta=' + encodeURIComponent(hasta.value);
    return s;
};

var _consOCCargarTabla = ConsultaOC.cargarTabla;
ConsultaOC.cargarTabla = function() {
    var self = this;
    _consOCCargarTabla.call(this).then(function() {
        var wrap = document.getElementById(self.elementId + 'TablaWrap');
        if (!wrap || !self.currentData) return;
        var rows = wrap.querySelectorAll('table tbody tr');

        rows.forEach(function(tr, idx) {
            var rowData = self.currentData[idx];
            if (!rowData) return;

            var badges = { P: 'prov-badge-pendiente', A: 'prov-badge-activo', C: 'prov-badge-cerrado', N: 'prov-badge-anulado' };
            var tds = tr.querySelectorAll('td');
            var colIdx = self.columns.findIndex(function(c) { return c.field === 'estado'; });
            if (colIdx >= 0 && tds[colIdx] && badges[rowData.estado]) {
                tds[colIdx].innerHTML = '<span class="prov-badge ' + badges[rowData.estado] + '">' + tds[colIdx].textContent.trim() + '</span>';
            }

            tr.style.cursor = 'pointer';
            tr.addEventListener('dblclick', function() {
                self.verDetalle(rowData.num_oc, rowData.ejercicio);
            });
        });

        // Context menu for Pedido column
        var pedColIdx = self.columns.findIndex(function(c) { return c.field === 'num_ped'; });
        if (pedColIdx >= 0) {
            var ctxMenu = document.getElementById('consOCCtxMenu');
            if (!ctxMenu) {
                ctxMenu = document.createElement('div');
                ctxMenu.id = 'consOCCtxMenu';
                ctxMenu.style.cssText = 'position:fixed;z-index:99999;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 4px 16px rgba(0,0,0,0.12);padding:4px 0;display:none;min-width:180px';
                document.body.appendChild(ctxMenu);
                document.addEventListener('click', function(e) {
                    if (!ctxMenu.contains(e.target)) ctxMenu.style.display = 'none';
                });
                document.addEventListener('contextmenu', function(e) {
                    if (!ctxMenu.contains(e.target)) ctxMenu.style.display = 'none';
                });
            }
            rows.forEach(function(tr) {
                var td = tr.querySelectorAll('td')[pedColIdx];
                if (!td) return;
                td.style.cursor = 'context-menu';
                td.addEventListener('contextmenu', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    var numPed = (this.textContent || '').trim();
                    if (!numPed || numPed === '-') return;
                    ctxMenu.innerHTML =
                        '<div class="cons-oc-ctx-item" data-ped="' + numPed + '" data-action="ver" style="padding:8px 14px;cursor:pointer;font-size:0.78rem;color:#1e293b;display:flex;align-items:center;gap:8px"><i class="fas fa-eye" style="color:#1A4480;width:16px;text-align:center"></i> Ver Pedido ' + numPed + '</div>' +
                        '<div class="cons-oc-ctx-item" data-ped="' + numPed + '" data-action="imprimir" style="padding:8px 14px;cursor:pointer;font-size:0.78rem;color:#1e293b;display:flex;align-items:center;gap:8px"><i class="fas fa-print" style="color:#64748b;width:16px;text-align:center"></i> Imprimir Pedido ' + numPed + '</div>';
                    ctxMenu.style.left = e.clientX + 'px';
                    ctxMenu.style.top = e.clientY + 'px';
                    ctxMenu.style.display = 'block';
                    requestAnimationFrame(function() {
                        var r = ctxMenu.getBoundingClientRect();
                        if (r.right > window.innerWidth) ctxMenu.style.left = Math.max(0, e.clientX - r.width) + 'px';
                        if (r.bottom > window.innerHeight) ctxMenu.style.top = Math.max(0, e.clientY - r.height) + 'px';
                    });
                    ctxMenu.querySelectorAll('.cons-oc-ctx-item').forEach(function(item) {
                        item.addEventListener('click', function(ev) {
                            ev.stopPropagation();
                            ctxMenu.style.display = 'none';
                            var pedParts = this.dataset.ped.split('-');
                            var ejercicio = pedParts.length > 1 ? pedParts[0] : '';
                            var numPed = pedParts.length > 1 ? pedParts.slice(1).join('-') : this.dataset.ped;
                            if (this.dataset.action === 'ver') {
                                if (typeof ConsultaPedidos !== 'undefined') ConsultaPedidos.verDetalle(numPed, ejercicio);
                            } else if (this.dataset.action === 'imprimir') {
                                if (typeof ConsultaPedidos !== 'undefined') ConsultaPedidos.imprimirDetalleVer(numPed, ejercicio);
                            }
                        });
                        item.addEventListener('mouseenter', function() { this.style.background = '#f1f5f9'; });
                        item.addEventListener('mouseleave', function() { this.style.background = ''; });
                    });
                });
            });
        }
    });
};

ConsultaOC.verDetalle = async function(numOc, ejercicio) {
    var self = this;
    if (!self.sesion || !self.sesion.id_empresa) {
        self.cargarSesion();
    }
    if (!self.sesion || !self.sesion.id_empresa) {
        var _s = localStorage.getItem('erp_session') || sessionStorage.getItem('erp_session');
        if (_s) { try { self.sesion = JSON.parse(_s); } catch(e) {} }
    }
    if (!self.sesion || !self.sesion.id_empresa) {
        Mensaje.error({ titulo: 'Error', texto: 'Sesión no disponible. Inicie sesión.' });
        return;
    }
    try {
        var params = '?id_empresa=' + self.sesion.id_empresa;
        if (ejercicio) params += '&ejercicio=' + ejercicio;
        var res = await fetch(self.API_URL + self.endpoint + '/' + numOc + params);
        var data = await res.json();
        if (!data.ok) { Mensaje.error({ titulo: 'Error', texto: data.mensaje }); return; }
        var row = data.data;
        var estados = { P: 'Pendiente', A: 'Aprobado', C: 'Cerrado', N: 'Anulado' };
        var html = '<div class="ped-detalle-view">';

        html += '<div class="ped-section"><div class="ped-section-title"><i class="fas fa-file-invoice"></i> Orden de Compra<button class="ped-detalle-print-btn oc-excel-btn" id="consOCViewExcelBtn" title="Exportar Excel" style="color:#059669"><i class="fas fa-file-excel" style="color:#059669"></i></button><button class="ped-detalle-print-btn" id="consOCViewPrintBtn" title="Imprimir" style="color:#1A4480"><i class="fas fa-print" style="color:#1A4480"></i></button></div>';
        html += '<div class="ped-detalle-grid oc-detalle-grid">';
        html += '<div class="ped-detalle-row"><span class="ped-detalle-label">N° OC:</span><span class="ped-detalle-valor">' + (row.num_oc || '-') + '</span></div>';
        html += '<div class="ped-detalle-row"><span class="ped-detalle-label">Pedido Origen:</span><span class="ped-detalle-valor">' + ((row.ped_ejercicio ? row.ped_ejercicio + '-' : '') + (row.num_ped || '-')) + '</span></div>';
        html += '<div class="ped-detalle-row"><span class="ped-detalle-label">Fecha:</span><span class="ped-detalle-valor">' + (row.fecha_oc ? row.fecha_oc.split('T')[0].split('-').reverse().join('/') : '-') + '</span></div>';
        html += '<div class="ped-detalle-row"><span class="ped-detalle-label">Proveedor:</span><span class="ped-detalle-valor">' + (row.proveedor_razon_social || '-') + '</span></div>';
        html += '<div class="ped-detalle-row"><span class="ped-detalle-label">Cond. Pago:</span><span class="ped-detalle-valor">' + (row.condicion_nombre || '-') + '</span></div>';
        html += '<div class="ped-detalle-row"><span class="ped-detalle-label">Tipo:</span><span class="ped-detalle-valor">' + (row.tipo === 'M' ? 'Materiales' : 'Gastos') + '</span></div>';
        html += '<div class="ped-detalle-row"><span class="ped-detalle-label">Moneda:</span><span class="ped-detalle-valor">' + (row.moneda === 'ME' ? 'Dolares' : 'Soles') + '</span></div>';
        html += '<div class="ped-detalle-row"><span class="ped-detalle-label">T.Cambio:</span><span class="ped-detalle-valor">' + (row.tipo_cambio ? parseFloat(row.tipo_cambio).toFixed(3) : '-') + '</span></div>';
        html += '<div class="ped-detalle-row"><span class="ped-detalle-label">Contacto:</span><span class="ped-detalle-valor">' + ((row.contacto || '-').toUpperCase()) + '</span></div>';
        html += '<div class="ped-detalle-row"><span class="ped-detalle-label">Solicitado por:</span><span class="ped-detalle-valor">' + ((row.solicitado_por || '-').toUpperCase()) + '</span></div>';
        html += '<div class="ped-detalle-row"><span class="ped-detalle-label">Fecha Entrega:</span><span class="ped-detalle-valor">' + (row.fecha_entrega ? row.fecha_entrega.split('T')[0].split('-').reverse().join('/') : '-') + '</span></div>';
        html += '<div class="ped-detalle-row"><span class="ped-detalle-label">Estado:</span><span class="ped-detalle-valor">' + (estados[row.estado] || row.estado) + '</span></div>';
        html += '<div class="ped-detalle-row"><span class="ped-detalle-label">Observaciones:</span><span class="ped-detalle-valor">' + (row.observaciones || '-') + '</span></div>';
        html += '</div></div>';

        html += '<div class="ped-section"><div class="ped-section-title"><i class="fas fa-list"></i> Detalle</div>';
        html += '<table class="ped-detalle-table"><thead><tr><th style="width:80px">Codigo</th><th>Articulo</th><th style="width:50px">Und</th><th style="width:90px;text-align:right">Cantidad</th><th style="width:100px;text-align:right">Precio</th><th style="width:70px;text-align:right">Desc %</th><th style="width:100px;text-align:right">Total</th></tr></thead><tbody>';
        var descFromDetail = 0;
        if (row.detalle && row.detalle.length > 0) {
            row.detalle.forEach(function(d) {
                var dTotal = parseFloat(d.total) || 0;
                var dDesc = parseFloat(d.descuento) || 0;
                var dDescPct = dTotal > 0 && dDesc > 0 ? (dDesc * 100 / dTotal) : 0;
                descFromDetail += dDesc;
                html += '<tr><td>' + (d.cod_articulo || '') + '</td><td>' + (d.nombre || '') + '</td><td>' + (d.cod_unidad || '') + '</td><td style="text-align:right">' + (parseFloat(d.cantidad) || 0).toFixed(3) + '</td><td style="text-align:right">' + (parseFloat(d.precio) || 0).toFixed(3) + '</td><td style="text-align:right">' + (dDescPct > 0 ? dDescPct.toFixed(2) + '%' : '') + '</td><td style="text-align:right">' + dTotal.toFixed(2) + '</td></tr>';
            });
        } else {
            html += '<tr><td colspan="7" style="text-align:center;color:#94a3b8">Sin detalle</td></tr>';
        }
        html += '</tbody></table>';
        var descGlobalMonto = 0;
        var descGlobalTipo = row.descuento_tipo || '%';
        var descGlobalValor = parseFloat(row.descuento_valor) || 0;
        var igvRate = (parseFloat(row.porcentaje_igv) || 18) / 100;
        var netoBeforeIgv = (parseFloat(row.total) || 0) / (1 + igvRate);
        descGlobalMonto = (parseFloat(row.subtotal) || 0) - descFromDetail - netoBeforeIgv;
        if (descGlobalMonto < 0) descGlobalMonto = 0;
        html += '<div style="display:flex;justify-content:flex-end;padding:8px 0;margin-top:4px"><table style="border-collapse:collapse;font-size:0.75rem"><tbody>';
        html += '<tr><td style="padding:4px 12px;text-align:right;color:#475569;font-weight:500;border:none">Subtotal</td><td style="padding:4px 12px;text-align:right;font-weight:600;color:#334155;min-width:100px;border:none">' + (parseFloat(row.subtotal) || 0).toLocaleString('es-PE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + '</td></tr>';
        if (descFromDetail > 0) {
            html += '<tr><td style="padding:4px 12px;text-align:right;color:#c2410c;font-weight:500;border:none">Descuento por línea</td><td style="padding:4px 12px;text-align:right;font-weight:600;color:#c2410c;border:1px solid #d1d5db;border-radius:4px;background:#FFF7ED">-' + descFromDetail.toLocaleString('es-PE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + '</td></tr>';
        }
        if (descGlobalMonto > 0) {
            var dgLabel = descGlobalTipo === '%' ? 'Descuento global (' + descGlobalValor.toFixed(2) + '%)' : 'Descuento global';
            html += '<tr><td style="padding:4px 12px;text-align:right;color:#c2410c;font-weight:500;border:none">' + dgLabel + '</td><td style="padding:4px 12px;text-align:right;font-weight:600;color:#c2410c;border:1px solid #d1d5db;border-radius:4px;background:#FFF7ED">-' + descGlobalMonto.toLocaleString('es-PE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + '</td></tr>';
        }
        html += '<tr><td style="padding:4px 12px;text-align:right;color:#475569;font-weight:500;border:none">IGV</td><td style="padding:4px 12px;text-align:right;font-weight:600;color:#334155;border:none">' + (parseFloat(row.igv) || 0).toLocaleString('es-PE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + '</td></tr>';
        html += '<tr><td style="padding:6px 12px;text-align:right;color:#1A4480;font-weight:700;font-size:0.85rem;border:none">TOTAL</td><td style="padding:6px 12px;text-align:right;font-weight:700;color:#1A4480;font-size:0.85rem;border:none">' + (parseFloat(row.total) || 0).toLocaleString('es-PE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + '</td></tr>';
        html += '</tbody></table></div></div>';
        html += '</div>';

        Modal.abrir({
            titulo: 'Detalle de OC ' + numOc,
            ancho: '780px',
            contenido: html,
            botones: [
                { texto: 'Cerrar', tipo: 'primario', accion: function() { Modal.cerrar(); } }
            ],
            onAbierto: function() {
                var btn = document.getElementById('consOCViewPrintBtn');
                if (btn) {
                    btn.onclick = function() { self.imprimirDetalleVer(numOc); };
                }
                var btnExcel = document.getElementById('consOCViewExcelBtn');
                if (btnExcel) {
                    btnExcel.onclick = function() { self.exportarExcelVer(numOc, ejercicio); };
                }
            }
        });
    } catch (error) {
        Mensaje.error({ titulo: 'Error', texto: 'Error al cargar detalle de OC' });
    }
};

ConsultaOC.imprimirDetalleVer = function(numOc, ejercicio) {
    var self = this;
    if (!self.sesion || !self.sesion.id_empresa) {
        self.cargarSesion();
    }
    if (!self.sesion || !self.sesion.id_empresa) {
        var _s = localStorage.getItem('erp_session') || sessionStorage.getItem('erp_session');
        if (_s) { try { self.sesion = JSON.parse(_s); } catch(e) {} }
    }
    if (!self.sesion || !self.sesion.id_empresa) {
        Mensaje.error({ titulo: 'Error', texto: 'Sesión no disponible. Inicie sesión.' });
        return;
    }
    var empresa = this.sesion?.empresa_razon || '';
    var params = '?id_empresa=' + (self.sesion ? self.sesion.id_empresa : '');
    if (ejercicio) params += '&ejercicio=' + ejercicio;
    fetch(self.API_URL + self.endpoint + '/' + numOc + params)
        .then(function(r) { return r.json(); })
        .then(function(res) {
            if (!res.ok) return;
            var row = res.data;
            var ahora = new Date();
            var fechaHora = ahora.toLocaleDateString('es-PE', { day: '2-digit', month: '2-digit', year: 'numeric' }) + ' ' + ahora.toLocaleTimeString('es-PE', { hour: '2-digit', minute: '2-digit' });
            var filas = '';
            var descFromDetail = 0;
            if (row.detalle) {
                row.detalle.forEach(function(d) {
                    var dTotal = parseFloat(d.total) || 0;
                    var dDesc = parseFloat(d.descuento) || 0;
                    var dDescPct = dTotal > 0 && dDesc > 0 ? (dDesc * 100 / dTotal) : 0;
                    descFromDetail += dDesc;
                    filas += '<tr><td>' + (d.cod_articulo || '') + '</td><td>' + (d.nombre || '') + '</td><td>' + (d.cod_unidad || '') + '</td><td style="text-align:right">' + (parseFloat(d.cantidad) || 0).toFixed(3) + '</td><td style="text-align:right">' + (parseFloat(d.precio) || 0).toFixed(3) + '</td><td style="text-align:right">' + (dDescPct > 0 ? dDescPct.toFixed(2) + '%' : '') + '</td><td style="text-align:right">' + dTotal.toFixed(2) + '</td></tr>';
                });
            }
            var tituloHtml = '<div class="prov-print-header"><div><div class="prov-print-titulo">ORDEN DE COMPRA</div>' + (empresa ? '<div style="font-size:0.8rem;color:#1A4480;font-weight:600;margin-top:4px">' + empresa + '</div>' : '') + '</div><div class="prov-print-info"><div class="prov-print-fecha">' + fechaHora + '</div></div></div>';
            var pedDisplay = (row.ped_ejercicio ? row.ped_ejercicio + '-' : '') + (row.num_ped || '-');
            function _consFmtFecha(iso) { if (!iso) return ''; var p = iso.split('T')[0].split('-'); return p[2] + '/' + p[1] + '/' + p[0]; }
            var infoHtml = '<div style="margin:12px 0;font-size:0.72rem;display:grid;grid-template-columns:auto 1fr;gap:2px 12px;align-items:start"><strong style="color:#475569;white-space:nowrap">N\u00B0:</strong><span>' + (row.num_oc || '') + '</span><strong style="color:#475569;white-space:nowrap">Proveedor:</strong><span>' + (row.proveedor_razon_social || '') + '</span><strong style="color:#475569;white-space:nowrap">Pedido Origen:</strong><span>' + pedDisplay + '</span><strong style="color:#475569;white-space:nowrap">Fecha:</strong><span>' + _consFmtFecha(row.fecha_oc) + '</span><strong style="color:#475569;white-space:nowrap">C.Pago:</strong><span>' + (row.condicion_nombre || '-') + '</span><strong style="color:#475569;white-space:nowrap">Fecha Entrega:</strong><span>' + (_consFmtFecha(row.fecha_entrega) || '-') + '</span></div>';
            var tablaHtml = '<table class="oc-det-tbl"><thead><tr><th>Codigo</th><th>Articulo</th><th>Und</th><th style="text-align:right">Cantidad</th><th style="text-align:right">Precio</th><th style="text-align:right">Desc %</th><th style="text-align:right">Total</th></tr></thead><tbody>' + filas + '</tbody></table>';
            var totalsHtml = '<div style="display:flex;justify-content:flex-end;padding:8px 0;margin-top:6px"><table style="border-collapse:collapse;font-size:0.75rem"><tbody>' +
                '<tr><td style="padding:4px 12px;text-align:right;color:#475569;font-weight:500;border:none">Subtotal</td><td style="padding:4px 12px;text-align:right;font-weight:600;color:#334155;min-width:100px;border:none">' + (parseFloat(row.subtotal) || 0).toLocaleString('es-PE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + '</td></tr>';
            if (descFromDetail > 0) {
                totalsHtml += '<tr><td style="padding:4px 12px;text-align:right;color:#c2410c;font-weight:500;border:none">Descuento por línea</td><td style="padding:4px 12px;text-align:right;font-weight:600;color:#c2410c;border:1px solid #d1d5db;border-radius:4px;background:#FFF7ED">-' + descFromDetail.toLocaleString('es-PE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + '</td></tr>';
            }
            var igvRate4 = (parseFloat(row.porcentaje_igv) || 18) / 100;
            var netoBeforeIgv4 = (parseFloat(row.total) || 0) / (1 + igvRate4);
            var descGM = (parseFloat(row.subtotal) || 0) - descFromDetail - netoBeforeIgv4;
            if (descGM < 0) descGM = 0;
            if (descGM > 0.01) {
                var dgTipo = row.descuento_tipo || '%';
                var dgValor = parseFloat(row.descuento_valor) || 0;
                var dgLabel = dgTipo === '%' ? 'Descuento global (' + dgValor.toFixed(2) + '%)' : 'Descuento global';
                totalsHtml += '<tr><td style="padding:4px 12px;text-align:right;color:#c2410c;font-weight:500;border:none">' + dgLabel + '</td><td style="padding:4px 12px;text-align:right;font-weight:600;color:#c2410c;border:1px solid #d1d5db;border-radius:4px;background:#FFF7ED">-' + descGM.toLocaleString('es-PE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + '</td></tr>';
            }
            totalsHtml += '<tr><td style="padding:4px 12px;text-align:right;color:#475569;font-weight:500;border:none">IGV</td><td style="padding:4px 12px;text-align:right;font-weight:600;color:#334155;border:none">' + (parseFloat(row.igv) || 0).toLocaleString('es-PE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + '</td></tr>' +
                '<tr><td style="padding:6px 12px;text-align:right;color:#1A4480;font-weight:700;font-size:0.85rem;border:none">TOTAL</td><td style="padding:6px 12px;text-align:right;font-weight:700;color:#1A4480;font-size:0.85rem;border:none">' + (parseFloat(row.total) || 0).toLocaleString('es-PE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + '</td></tr>' +
                '</tbody></table></div>';
            self._imprimirSrcdoc(tituloHtml + infoHtml + tablaHtml + totalsHtml + '<div class="prov-print-total">Total items: ' + (row.detalle ? row.detalle.length : 0) + '</div>', 'OC ' + numOc);
        });
};

var _consOCImprimir = ConsultaOC.imprimir;
ConsultaOC.imprimir = async function() {
    var datos = await this.obtenerTodosDatos();
    if (!datos || datos.length === 0) { Mensaje.error({ titulo: 'Imprimir', texto: 'No hay datos para imprimir' }); return; }

    var filtros = [];
    if (Object.keys(this.filtrosColumna).length > 0) {
        for (var k in this.filtrosColumna) {
            if (k === 'estado') {
                var estMap = { P: 'Pendiente', A: 'Aprobado', C: 'Cerrado', N: 'Anulado' };
                filtros.push('Estado: ' + this.filtrosColumna[k].split(',').map(function(v) { return estMap[v.trim()] || v.trim(); }).join(', '));
            } else if (k === 'tipo') {
                filtros.push('Tipo: ' + this.filtrosColumna[k].split(',').map(function(v) { return v.trim() === 'M' ? 'Materiales' : 'Gastos'; }).join(', '));
            } else {
                filtros.push(k + ': ' + this.filtrosColumna[k]);
            }
        }
    }
    var buscarVal = document.getElementById(this.elementId + 'Buscar');
    if (buscarVal && buscarVal.value.trim()) filtros.push('Busqueda: ' + buscarVal.value.trim());

    function fmtFecha(iso) {
        if (!iso) return '';
        var p = iso.split('-');
        return p[2] + '/' + p[1] + '/' + p[0];
    }
    var desde = document.getElementById('consOCFechaDesde');
    var hasta = document.getElementById('consOCFechaHasta');
    if (desde && desde.value && hasta && hasta.value) {
        filtros.push('Desde: ' + fmtFecha(desde.value) + ' - Hasta: ' + fmtFecha(hasta.value));
    } else {
        if (desde && desde.value) filtros.push('Desde: ' + fmtFecha(desde.value));
        if (hasta && hasta.value) filtros.push('Hasta: ' + fmtFecha(hasta.value));
    }

    var ahora = new Date();
    var fechaHora = ahora.toLocaleDateString('es-PE', { day: '2-digit', month: '2-digit', year: 'numeric' }) + ' ' + ahora.toLocaleTimeString('es-PE', { hour: '2-digit', minute: '2-digit' });

    var filasHtml = '';
    datos.forEach(function(row) {
        filasHtml += '<tr>';
        this.columns.forEach(function(col, ci) {
            var val = row[col.field];
            if (col.render) val = col.render(row, val);
            else val = (val !== null && val !== undefined) ? String(val) : '-';
            var cls = ci === 6 ? ' class="numeric"' : '';
            filasHtml += '<td' + cls + '>' + val + '</td>';
        }, this);
        filasHtml += '</tr>';
    }, this);

    var cabecerasHtml = this.columns.map(function(c, ci) { var cls = ci === 6 ? ' class="numeric"' : ''; return '<th' + cls + '>' + c.label + '</th>'; }).join('');
    var tablaHtml = '<table><thead><tr>' + cabecerasHtml + '</tr></thead><tbody>' + filasHtml + '</tbody></table>';

    var di = await TablaGenerica._obtenerDatosImpresion();
    var empresaHtml = di.empresa ? '<div style="font-size:0.8rem;color:#1A4480;font-weight:600;margin-top:4px">' + di.empresa + '</div>' : '';
    var sucursalHtml = di.sucursal ? '<div style="font-size:0.7rem;color:#64748B;margin-top:1px">' + di.sucursal + '</div>' : '';
    var printHtml = '<div class="prov-print-header">' +
            '<div>' + di.logoHtml + '<div style="display:inline-block;vertical-align:middle"><div class="prov-print-titulo">' + this.title + '</div>' + empresaHtml + sucursalHtml + '</div></div>' +
            '<div class="prov-print-info"><div class="prov-print-fecha">' + fechaHora + '</div></div>' +
        '</div>';

    if (filtros.length > 0) {
        printHtml += '<div class="prov-print-filtros">' + filtros.join(' | ') + '</div>';
    }

    printHtml += tablaHtml +
        '<div class="prov-print-total">Total: ' + datos.length + ' registro(s)</div>';

    this._imprimirSrcdoc(printHtml, this.title);
};

ConsultaOC._ocFmtFecha = function(v) { if (!v) return ''; var p = v.split('-'); return p.length === 3 ? p[2] + '/' + p[1] + '/' + p[0] : v; };

ConsultaOC.exportarExcelVer = function(numOc, ejercicio) {
    var self = this;
    if (!self.sesion || !self.sesion.id_empresa) {
        var _s = localStorage.getItem('erp_session') || sessionStorage.getItem('erp_session');
        if (_s) { try { self.sesion = JSON.parse(_s); } catch(e) {} }
    }
    if (typeof ExcelJS === 'undefined') {
        var s = document.createElement('script');
        s.src = 'https://cdn.jsdelivr.net/npm/exceljs@4.4.0/dist/exceljs.min.js';
        s.onload = function() { self._ocExportExcel(numOc, ejercicio); };
        s.onerror = function() { Mensaje.error({ titulo: 'Excel', texto: 'Error al cargar la librería de Excel' }); };
        document.head.appendChild(s);
    } else {
        self._ocExportExcel(numOc, ejercicio);
    }
};

ConsultaOC._ocExportExcel = function(numOc, ejercicio) {
    var self = this;
    var params = '?id_empresa=' + self.sesion.id_empresa;
    if (ejercicio) params += '&ejercicio=' + ejercicio;
    fetch(self.API_URL + self.endpoint + '/' + numOc + params)
        .then(function(r) { return r.json(); })
        .then(function(data) {
            if (!data.ok) { Mensaje.error({ titulo: 'Excel', texto: data.mensaje }); return; }
            var row = data.data;
            var empresa = self.sesion.empresa_razon || '';
            var ocDisplay = row.ejercicio ? row.ejercicio + '-' + row.num_oc : row.num_oc;
            var pedDisplay = row.ped_ejercicio ? row.ped_ejercicio + '-' + (row.num_ped || '') : (row.num_ped || '');
            var fecha = self._ocFmtFecha(row.fecha_oc ? row.fecha_oc.split('T')[0] : '');
            var fechaEntrega = self._ocFmtFecha(row.fecha_entrega ? row.fecha_entrega.split('T')[0] : '');

            var totalBruto = 0, descuentoLineas = 0;
            var items = [];
            (row.detalle || []).forEach(function(d) {
                var itemTotal = parseFloat(d.total) || 0;
                var itemDesc = parseFloat(d.descuento) || 0;
                descuentoLineas += itemDesc;
                totalBruto += itemTotal;
                var descPct = itemTotal > 0 ? (itemDesc / itemTotal * 100) : 0;
                items.push({ cod: d.cod_articulo, nombre: d.nombre, unidad: d.cod_unidad, cantidad: parseFloat(d.cantidad) || 0, precio: parseFloat(d.precio) || 0, descPct: descPct, total: itemTotal });
            });

            var subtotalNeto = totalBruto - descuentoLineas;
            var descGlobalTipo = row.descuento_tipo || '%';
            var descGlobalValor = parseFloat(row.descuento_valor) || 0;
            var igvRate5 = (parseFloat(row.porcentaje_igv) || 18) / 100;
            var netoBeforeIgv5 = (parseFloat(row.total) || 0) / (1 + igvRate5);
            var descGlobalMonto = (parseFloat(row.subtotal) || 0) - descuentoLineas - netoBeforeIgv5;
            if (descGlobalMonto < 0) descGlobalMonto = 0;
            subtotalNeto -= descGlobalMonto;
            var igvCalc = subtotalNeto * (parseFloat(row.porcentaje_igv) || 18) / 100;
            var totalFinal = subtotalNeto + igvCalc;

            var wb = new ExcelJS.Workbook();
            OrdenesCompra._ocBuildExcel(wb, ocDisplay, empresa, row.proveedor_razon_social || '', pedDisplay, fecha, row.contacto || '', row.solicitado_por || '', fechaEntrega, items, totalBruto, descuentoLineas, descGlobalTipo, descGlobalValor, descGlobalMonto, igvCalc, totalFinal);
            wb.xlsx.writeBuffer().then(function(buf) {
                var blob = new Blob([buf], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
                var a = document.createElement('a');
                a.href = URL.createObjectURL(blob);
                a.download = 'OC_' + ocDisplay.replace(/[^a-zA-Z0-9-]/g, '_') + '.xlsx';
                a.click();
            });
        })
        .catch(function() { Mensaje.error({ titulo: 'Excel', texto: 'Error al obtener datos' }); });
};

ConsultaOC.init({
    title: 'Consultar O/C',
    icon: 'fa-shopping-cart',
    idSingular: 'OC',
    idField: 'num_oc',
    endpoint: '/ordenes-compra',
    sortDefault: 'fecha_oc',
    limite: 50,
    searchPlaceholder: 'Buscar por N° OC o proveedor...',
    filtroEstado: false,
    showEstado: false,
    showAcciones: false,
    showCrear: false,
    exportFileName: 'ConsultaOC',
    elementId: 'pageConsOC',
    menuPage: 'ConsOC',
    columnFilters: {},
    columns: [
        { field: 'ejercicio', label: 'Ejerc.', sortable: true, filterable: true, width: '5%' },
        { field: 'num_oc', label: 'N° OC', sortable: true, filterable: true, width: '7%' },
        { field: 'num_ped', label: 'Pedido', sortable: true, filterable: true, width: '7%',
            render: function(row) { return (row.ped_ejercicio ? row.ped_ejercicio + '-' : '') + (row.num_ped || '-'); }
        },
        { field: 'fecha_oc', label: 'Fecha', sortable: true, filterable: false, width: '8%',
            render: function(row) {
                if (!row.fecha_oc) return '';
                var d = new Date(row.fecha_oc);
                if (isNaN(d.getTime())) return row.fecha_oc;
                return ('0' + d.getDate()).slice(-2) + '/' + ('0' + (d.getMonth() + 1)).slice(-2) + '/' + d.getFullYear();
            }
        },
        { field: 'proveedor_razon_social', label: 'Proveedor', sortable: true, filterable: true, width: '24%' },
        { field: 'condicion_nombre', label: 'C.Pago', sortable: true, filterable: true, width: '6%',
            render: function(row) { return row.condicion_nombre || '-'; }
        },
        { field: 'fecha_entrega', label: 'Entreg.', sortable: true, filterable: false, width: '7%',
            render: function(row) {
                if (!row.fecha_entrega) return '-';
                var d = new Date(row.fecha_entrega);
                if (isNaN(d.getTime())) return row.fecha_entrega;
                return ('0' + d.getDate()).slice(-2) + '/' + ('0' + (d.getMonth() + 1)).slice(-2) + '/' + d.getFullYear();
            }
        },
        { field: 'tipo', label: 'Tipo', sortable: true, filterable: true, width: '8%',
            render: function(row) { return row.tipo === 'M' ? 'Materiales' : 'Gastos'; }
        },
        { field: 'total', label: 'Total', sortable: true, filterable: false, width: '7%',
            render: function(row) {
                var total = parseFloat(row.total) || 0;
                return '<span style="display:block;text-align:right;font-family:inherit;font-size:inherit">' + total.toLocaleString('es-PE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + '</span>';
            }
        },
        { field: 'estado', label: 'Estado', sortable: true, filterable: true, width: '8%',
            render: function(row) {
                var estados = { P: 'Pendiente', A: 'Aprobado', C: 'Cerrado', N: 'Anulado' };
                return estados[row.estado] || row.estado;
            }
        }
    ],
    onEliminar: null
});
