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

ConciliacionFisica._fmtMiles = function(val, dec) {
    dec = dec !== undefined ? dec : 2;
    var num = parseFloat(val) || 0;
    return num.toLocaleString('es-PE', { minimumFractionDigits: dec, maximumFractionDigits: dec });
};

ConciliacionFisica._fisicos = {};

ConciliacionFisica._cargarFisicos = function() {
    try {
        var raw = localStorage.getItem('conciliacion_fisica');
        if (raw) ConciliacionFisica._fisicos = JSON.parse(raw);
    } catch(e) {}
};

ConciliacionFisica._guardarFisicos = function() {
    try { localStorage.setItem('conciliacion_fisica', JSON.stringify(ConciliacionFisica._fisicos)); } catch(e) {}
};

var _cfMostrarVista = ConciliacionFisica.mostrarVista;
ConciliacionFisica.mostrarVista = function() {
    var self = this;
    ConciliacionFisica._cargarFisicos();

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

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

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

    var toolbar = document.querySelector('#' + self.elementId + ' .prov-toolbar');
    if (toolbar) {
        var bar = document.createElement('div');
        bar.id = 'cfExtraBar';
        bar.style.cssText = 'display:flex;align-items:center;gap:12px;padding:8px 20px;background:#f8fafc;border-bottom:1px solid #e2e8f0;font-size:0.82rem;flex-wrap:wrap';

        bar.innerHTML =
            '<label style="display:flex;align-items:center;gap:4px;font-weight:600;color:#475569;font-size:0.78rem">' +
            '<input type="checkbox" id="cfSoloDiferencias"> Solo con diferencias</label>' +
            '<button id="cfLimpiar" style="padding:4px 12px;background:#dc2626;color:#fff;border:none;border-radius:4px;font-size:0.78rem;cursor:pointer;font-weight:600">Limpiar Físicos</button>' +
            '<button id="cfCerrarAjustar" style="padding:4px 12px;background:#1A4480;color:#fff;border:none;border-radius:4px;font-size:0.78rem;cursor:pointer;font-weight:600">Cerrar y Ajustar</button>' +
            '<button id="cfExportarConciliacion" style="padding:4px 12px;background:#16a34a;color:#fff;border:none;border-radius:4px;font-size:0.78rem;cursor:pointer;font-weight:600">Exportar Conciliación</button>' +
            '<button id="cfVerAjustes" style="padding:4px 12px;background:#7c3aed;color:#fff;border:none;border-radius:4px;font-size:0.78rem;cursor:pointer;font-weight:600">Ver Ajustes</button>';
        toolbar.parentNode.insertBefore(bar, toolbar.nextSibling);

        document.getElementById('cfSoloDiferencias').addEventListener('change', function() {
            self.paginaActual = 1;
            self.cargarTabla();
        });
        document.getElementById('cfLimpiar').addEventListener('click', function() {
            Mensaje.confirmacion({
                titulo: 'Limpiar Físicos',
                texto: '¿Limpiar todos los conteos físicos?',
                onAceptar: function() {
                    ConciliacionFisica._fisicos = {};
                    ConciliacionFisica._guardarFisicos();
                    self.cargarTabla();
                }
            });
        });
        document.getElementById('cfCerrarAjustar').addEventListener('click', function() {
            self._cerrarYajustar();
        });
        document.getElementById('cfExportarConciliacion').addEventListener('click', function() {
            self.exportarConciliacion();
        });
        document.getElementById('cfVerAjustes').addEventListener('click', function() {
            self._verAjustes();
        });
    }

    self.cargarTabla();
};

ConciliacionFisica.obtenerParamsExtra = function() {
    var self = this;
    var soloEl = document.getElementById('cfSoloDiferencias');
    var s = '';
    if (self.sesion && self.sesion.id_sucursal) s += '&id_sucursal=' + self.sesion.id_sucursal;
    if (soloEl && soloEl.checked) s += '&solo_diferencias=true';
    return s;
};

ConciliacionFisica._lastTotales = { total_articulos: 0, stock_sistema_total: 0, valor_stock_total: 0 };

var _cfCargarTabla = ConciliacionFisica.cargarTabla;
ConciliacionFisica.cargarTabla = function() {
    var self = this;
    self._cargarTotales().then(function() {
        return _cfCargarTabla.call(self);
    }).then(function() {
        self._agregarTotales();
        self._pintarThead();
        try { self._agregarInputsFisicos(); } catch(e) { console.error('[CF] _agregarInputsFisicos:', e); }
    }).catch(function(e) {
        console.error('[CF] cargarTabla error:', e);
    });
};

ConciliacionFisica._cargarTotales = function() {
    var self = this;
    self.ensureSesion();
    if (!self.sesion || !self.sesion.id_empresa) return Promise.resolve();
    var url = self.API_URL + '/conciliacion-fisica/totales?id_empresa=' + self.sesion.id_empresa;
    if (typeof self.obtenerParamsExtra === 'function') url += self.obtenerParamsExtra();
    var filtrosStr = Object.keys(self.filtrosColumna).length > 0 ? '&filtros=' + encodeURIComponent(JSON.stringify(self.filtrosColumna)) : '';
    url += filtrosStr;
    return fetch(url).then(function(r) { return r.json(); }).then(function(res) {
        if (res.ok) {
            self._lastTotales = {
                total_articulos: res.total_articulos || 0,
                stock_sistema_total: res.stock_sistema_total || 0,
                valor_stock_total: res.valor_stock_total || 0
            };
        }
    }).catch(function(err) {
        console.error('[CF] Error cargar totales:', err);
    });
};

ConciliacionFisica._agregarTotales = function() {
    var self = this;
    var wrap = document.getElementById(self.elementId + 'TablaWrap');
    if (!wrap) return;

    var oldResumen = document.getElementById('cfResumen');
    if (oldResumen) oldResumen.remove();

    var pag = document.getElementById(self.elementId + 'Paginacion');
    if (pag) {
        var t = self._lastTotales;
        var resumen = document.createElement('div');
        resumen.id = 'cfResumen';
        resumen.className = 'cf-resumen';
        resumen.innerHTML =
            '<div class="sv-resumen-item"><span class="sv-resumen-label">Artículos:</span> <span class="sv-resumen-value">' + ConciliacionFisica._fmtMiles(t.total_articulos) + '</span></div>' +
            '<div class="sv-resumen-item"><span class="sv-resumen-label">Stock Sistema:</span> <span class="sv-resumen-value" style="color:#1A4480">' + ConciliacionFisica._fmtMiles(t.stock_sistema_total) + '</span></div>' +
            '<div class="sv-resumen-item"><span class="sv-resumen-label">Valor Stock:</span> <span class="sv-resumen-value" style="color:#1A4480">S/ ' + ConciliacionFisica._fmtMiles(t.valor_stock_total) + '</span></div>';
        pag.parentNode.insertBefore(resumen, pag);
    }
};

ConciliacionFisica._pintarThead = function() {
    var wrap = document.getElementById(this.elementId + 'TablaWrap');
    if (!wrap) return;
    var thead = wrap.querySelector('table thead');
    if (!thead) return;
    var tr = thead.querySelector('tr');
    if (!tr) return;

    tr.querySelectorAll('.cf-th-extra').forEach(function(el) { el.remove(); });

    var th1 = document.createElement('th');
    th1.className = 'cf-th-extra';
    th1.style.cssText = 'background:#1A4480;color:#fff;padding:8px 6px;font-size:0.7rem;vertical-align:middle;border-right:1px solid rgba(255,255,255,0.35);border-bottom:2px solid #102A50;text-align:center;width:12%';
    th1.textContent = 'Conteo Fís.';
    tr.appendChild(th1);

    var th2 = document.createElement('th');
    th2.className = 'cf-th-extra';
    th2.style.cssText = 'background:#1A4480;color:#fff;padding:8px 6px;font-size:0.7rem;vertical-align:middle;border-right:1px solid rgba(255,255,255,0.35);border-bottom:2px solid #102A50;text-align:right;width:12%';
    th2.textContent = 'Diferencia';
    tr.appendChild(th2);
};

ConciliacionFisica._agregarInputsFisicos = function() {
    var self = this;
    var wrap = document.getElementById(self.elementId + 'TablaWrap');
    if (!wrap) return;

    wrap.querySelectorAll('.cf-fisico-input').forEach(function(el) { el.remove(); });
    wrap.querySelectorAll('.cf-diff-cell').forEach(function(el) { el.remove(); });

    var tbody = wrap.querySelector('table tbody');
    if (!tbody) return;

    var trs = tbody.querySelectorAll('tr');
    trs.forEach(function(tr, idx) {
        tr.addEventListener('dblclick', function(e) {
            var rowData = self.currentData[idx];
            if (rowData) self._verDetalleArticulo(rowData);
        });
        var cells = tr.querySelectorAll('td');
        if (cells.length < 3) return;

        var codCell = cells[0];
        var cod = codCell ? codCell.textContent.trim() : '';
        if (!cod) return;

        var stockCell = cells[4];
        var stock = stockCell ? parseFloat(stockCell.textContent.replace(/[^0-9.\-]/g, '')) || 0 : 0;

        var inputTd = document.createElement('td');
        inputTd.className = 'cf-fisico-input';
        inputTd.style.cssText = 'padding:4px 8px;text-align:center';
        var input = document.createElement('input');
        input.type = 'number';
        input.style.cssText = 'width:60px;padding:4px;border:1px solid #cbd5e1;border-radius:4px;text-align:center;font-size:0.78rem';
        input.value = ConciliacionFisica._fisicos[cod] !== undefined ? ConciliacionFisica._fisicos[cod] : '';
        input.placeholder = '0';
        input.setAttribute('data-cod', cod);
        input.setAttribute('data-stock', stock);
        input.addEventListener('change', function() {
            var val = this.value.trim();
            if (val !== '') {
                ConciliacionFisica._fisicos[cod] = parseFloat(val) || 0;
            } else {
                delete ConciliacionFisica._fisicos[cod];
            }
            ConciliacionFisica._guardarFisicos();
            self._actualizarDiferencias();
        });
        inputTd.appendChild(input);
        tr.appendChild(inputTd);

        var diffTd = document.createElement('td');
        diffTd.className = 'cf-diff-cell';
        diffTd.style.cssText = 'padding:4px 8px;text-align:right;font-weight:700';
        var fisico = ConciliacionFisica._fisicos[cod] !== undefined ? ConciliacionFisica._fisicos[cod] : null;
        if (fisico !== null) {
            var diff = Math.round((fisico - stock) * 100) / 100;
            var color = diff === 0 ? '#22c55e' : diff > 0 ? '#d97706' : '#dc2626';
            diffTd.innerHTML = '<span style="color:' + color + '">' + ConciliacionFisica._fmtMiles(diff) + '</span>';
        }
        tr.appendChild(inputTd);
        tr.appendChild(diffTd);
    });
};

ConciliacionFisica._actualizarDiferencias = function() {
    var self = this;
    var wrap = document.getElementById(self.elementId + 'TablaWrap');
    if (!wrap) return;

    var tbody = wrap.querySelector('table tbody');
    if (!tbody) return;

    var trs = tbody.querySelectorAll('tr');
    trs.forEach(function(tr) {
        var inputs = tr.querySelectorAll('.cf-fisico-input input');
        var diffCells = tr.querySelectorAll('.cf-diff-cell');
        if (inputs.length === 0 || diffCells.length === 0) return;

        var input = inputs[0];
        var diffTd = diffCells[0];
        var cod = input.getAttribute('data-cod');
        var stock = parseFloat(input.getAttribute('data-stock')) || 0;

        var fisico = ConciliacionFisica._fisicos[cod] !== undefined ? ConciliacionFisica._fisicos[cod] : null;
        if (fisico !== null) {
            var diff = Math.round((fisico - stock) * 100) / 100;
            var color = diff === 0 ? '#22c55e' : diff > 0 ? '#d97706' : '#dc2626';
            diffTd.innerHTML = '<span style="color:' + color + '">' + ConciliacionFisica._fmtMiles(diff) + '</span>';
        } else {
            diffTd.innerHTML = '<span style="color:#94a3b8"></span>';
        }
    });
};

ConciliacionFisica._verDetalleArticulo = function(row) {
    var self = this;
    self.ensureSesion();
    if (!row.id_articulo || !self.sesion) return;
    fetch(self.API_URL + '/articulos/' + row.id_articulo + '?id_empresa=' + self.sesion.id_empresa)
        .then(function(r) { return r.json(); })
        .then(function(res) {
            if (!res.ok) { Mensaje.error({ titulo: 'Error', texto: 'Artículo no encontrado' }); return; }
            var a = res.data;
            var html = '<div style="padding:4px 0"><div style="display:grid;grid-template-columns:auto 1fr;gap:4px 16px;font-size:0.82rem">';
            html += '<span style="font-weight:600;color:#475569">Código:</span><span>' + (a.cod_articulo || '-') + '</span>';
            html += '<span style="font-weight:600;color:#475569">Cód. Venta:</span><span>' + (a.cod_vta || '-') + '</span>';
            html += '<span style="font-weight:600;color:#475569">Nombre:</span><span>' + (a.nombre || '-') + '</span>';
            html += '<span style="font-weight:600;color:#475569">Familia:</span><span>' + (a.familia_nombre || '-') + '</span>';
            html += '<span style="font-weight:600;color:#475569">Subfamilia:</span><span>' + (a.subfamilia_nombre || '-') + '</span>';
            html += '<span style="font-weight:600;color:#475569">Unidad:</span><span>' + (a.unidad_nombre || '-') + ' (' + (a.unidad_codigo || '') + ')</span>';
            html += '<span style="font-weight:600;color:#475569">Proveedor:</span><span>' + (a.proveedor_razon_social || '-') + '</span>';
            html += '<span style="font-weight:600;color:#475569">Stock Actual:</span><span style="font-weight:700">' + ConciliacionFisica._fmtMiles(a.stock_actual) + '</span>';
            html += '<span style="font-weight:600;color:#475569">Stock Mínimo:</span><span>' + ConciliacionFisica._fmtMiles(a.stock_minimo) + '</span>';
            html += '<span style="font-weight:600;color:#475569">Stock Máximo:</span><span>' + ConciliacionFisica._fmtMiles(a.stock_maximo) + '</span>';
            html += '<span style="font-weight:600;color:#475569">Precio Venta:</span><span>S/ ' + ConciliacionFisica._fmtMiles(a.precio_venta) + '</span>';
            html += '<span style="font-weight:600;color:#475569">Precio Compra:</span><span>S/ ' + ConciliacionFisica._fmtMiles(a.precio_compra) + '</span>';
            html += '</div></div>';
            Modal.abrir({ titulo: 'Detalle de Artículo — ' + (a.cod_articulo || ''), ancho: '600px', contenido: html, botones: [{ texto: 'Cerrar', tipo: 'primario', accion: function() { Modal.cerrar(); } }] });
        }).catch(function() { Mensaje.error({ titulo: 'Error', texto: 'Error al cargar artículo' }); });
};

ConciliacionFisica.imprimir = async function() {
    var self = this;
    var di = await TablaGenerica._obtenerDatosImpresion();
    var ahora = new Date();
    var fechaStr = ahora.toLocaleDateString('es-PE', { day: '2-digit', month: '2-digit', year: 'numeric' }) + ' ' + ahora.toLocaleTimeString('es-PE', { hour: '2-digit', minute: '2-digit' });

    var datos = await self.obtenerTodosDatos();
        if (!datos || datos.length === 0) { Mensaje.error({ titulo: 'Imprimir', texto: 'No hay datos' }); return; }

        var html = '<!DOCTYPE html><html><head><meta charset="UTF-8"><style>';
        html += '*{margin:0;padding:0;outline:none}';
        html += 'body{font-family:Arial,sans-serif;font-size:11px;margin:20px;color:#1E293B}';
        html += 'table{width:100%;border-collapse:collapse;font-size:10px}';
        html += 'th{background:#1A4480;color:#fff;padding:8px 10px;text-align:left;font-weight:700;text-transform:uppercase;font-size:9px;border:1px solid rgba(255,255,255,0.4);white-space:nowrap}';
        html += 'td{padding:6px 10px;border:0;border-bottom:1px solid #E2E8F0;color:#334155}';
        html += '.right{text-align:right}.bold{font-weight:700}';
        html += 'thead{display:table-header-group}';
        html += '@page{margin:10mm;@bottom-center{content:counter(page);font-family:Arial,sans-serif;font-size:9px;color:#64748B}}';
        html += '</style></head><body>';
        html += '<table>';
        html += '<thead>';
        html += '<tr><th colspan="8" style="text-align:left;padding:0 0 10px 0;border:0;background:none;color:#1E293B;font-size:14px;text-transform:uppercase"><div style="display:flex;justify-content:space-between;align-items:flex-start;width:100%"><div>' + di.logoHtml + '<span style="display:inline-block;vertical-align:middle"><span style="font-weight:800;color:#1A4480">Conciliación Física vs Sistema</span>' + (di.empresa ? '<br><span style="font-size:0.8rem;color:#1A4480;font-weight:600">' + di.empresa + '</span>' : '') + (di.sucursal ? '<br><span style="font-size:0.7rem;color:#64748B;font-weight:400">' + di.sucursal + '</span>' : '') + '</span></div><span style="font-size:0.65rem;color:#64748B;text-transform:none">' + fechaStr + '</span></div></th></tr>';
        html += '<tr><th style="width:8%;border-radius:6px 0 0 0">Código</th><th style="width:10%">Cod Venta</th><th style="width:22%">Artículo</th><th style="width:14%">Familia</th><th class="right" style="width:10%">Stock Sist.</th><th class="right" style="width:10%">Costo</th><th class="right" style="width:12%">Conteo Fís.</th><th class="right" style="width:12%;border-radius:0 6px 0 0">Diferencia</th></tr>';
        html += '</thead><tbody>';

        datos.forEach(function(a) {
            var stock = parseFloat(a.stock_sistema) || 0;
            var fisico = ConciliacionFisica._fisicos[a.cod_articulo] !== undefined ? ConciliacionFisica._fisicos[a.cod_articulo] : null;
            var diff = fisico !== null ? Math.round((fisico - stock) * 100) / 100 : null;
            var diffStr = diff !== null ? ConciliacionFisica._fmtMiles(diff) : '';
            var diffColor = diff !== null ? (diff === 0 ? '#22c55e' : diff > 0 ? '#d97706' : '#dc2626') : '#94a3b8';
            html += '<tr><td>' + (a.cod_articulo || '') + '</td><td>' + (a.cod_vta || '') + '</td><td>' + (a.nom_art || '') + '</td><td>' + (a.nom_fam || '') + '</td><td class="right bold">' + ConciliacionFisica._fmtMiles(stock) + '</td><td class="right">' + ConciliacionFisica._fmtMiles(a.costo_promedio) + '</td><td class="right bold">' + (fisico !== null ? ConciliacionFisica._fmtMiles(fisico) : '') + '</td><td class="right bold" style="color:' + diffColor + '">' + diffStr + '</td></tr>';
        });

        html += '</tbody></table>';

        var totalStock = 0, totalValor = 0;
        datos.forEach(function(a) { totalStock += parseFloat(a.stock_sistema) || 0; totalValor += parseFloat(a.valor_stock) || 0; });
        html += '<div style="display:flex;gap:16px;margin-top:14px;padding:8px 12px;background:#F8FAFC;border-radius:6px;font-size:9px;flex-wrap:wrap;border:1px solid #E2E8F0">';
        html += '<span style="font-weight:700;color:#334155">Artículos: <span style="color:#1A4480">' + ConciliacionFisica._fmtMiles(datos.length) + '</span></span>';
        html += '<span style="font-weight:700;color:#334155">Stock Sistema: <span style="color:#1A4480">' + ConciliacionFisica._fmtMiles(totalStock) + '</span></span>';
        html += '<span style="font-weight:700;color:#334155">Valor Stock: <span style="color:#1A4480">S/ ' + ConciliacionFisica._fmtMiles(totalValor) + '</span></span>';
        html += '</div>';
        html += '</body></html>';

        var iframe = document.createElement('iframe');
        iframe.style.cssText = 'position:fixed;top:-9999px;width:1px;height:1px';
        document.body.appendChild(iframe);
        var win = iframe.contentWindow;
        win.document.open();
        win.document.write(html);
        win.document.close();
        setTimeout(function() { win.print(); }, 300);
        setTimeout(function() { document.body.removeChild(iframe); }, 1500);
};

ConciliacionFisica.exportarExcel = function() {
    var self = this;
    self.cerrarExportDD();
    self.obtenerTodosDatos().then(function(datos) {
        if (!datos || datos.length === 0) { Mensaje.error({ titulo: 'Excel', texto: 'No hay datos para exportar' }); return; }
        function go() {
            var wb = new ExcelJS.Workbook();
            var ws = wb.addWorksheet('Conciliación Física');
            ws.columns = [
                { header: 'Código', key: 'cod', width: 10 }, { header: 'Cod. Venta', key: 'codvta', width: 12 },
                { header: 'Artículo', key: 'nombre', width: 35 }, { header: 'Familia', key: 'familia', width: 16 },
                { header: 'Stock Sist.', key: 'stock_sist', width: 12 }, { header: 'Costo', key: 'costo', width: 12 },
                { header: 'Conteo Fís.', key: 'fisico', width: 12 }, { header: 'Diferencia', key: 'diff', width: 12 }
            ];
            ws.getRow(1).font = { bold: true, color: { argb: 'FFFFFFFF' } };
            ws.getRow(1).fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF1A4480' } };
            ws.getRow(1).alignment = { horizontal: 'center' };
            datos.forEach(function(a) {
                var stock = parseFloat(a.stock_sistema) || 0;
                var fisico = ConciliacionFisica._fisicos[a.cod_articulo] !== undefined ? ConciliacionFisica._fisicos[a.cod_articulo] : null;
                ws.addRow({ cod: a.cod_articulo || '', codvta: a.cod_vta || '', nombre: a.nom_art || '', familia: a.nom_fam || '', stock_sist: stock, costo: parseFloat(a.costo_promedio) || 0, fisico: fisico !== null ? fisico : '', diff: fisico !== null ? fisico - stock : '' });
            });
            ws.getColumn('stock_sist').numFmt = '#,##0.00';
            ws.getColumn('costo').numFmt = '#,##0.0000';
            ws.getColumn('fisico').numFmt = '#,##0.00';
            ws.getColumn('diff').numFmt = '#,##0.00';
            wb.xlsx.writeBuffer().then(function(buf) {
                var a = document.createElement('a');
                a.href = URL.createObjectURL(new Blob([buf], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }));
                a.download = 'conciliacion_fisica_' + new Date().toISOString().slice(0, 10) + '.xlsx';
                a.click();
            });
        }
        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 = go; document.head.appendChild(s); } else { go(); }
    });
};

ConciliacionFisica.exportarCSV = function() {
    var self = this;
    self.cerrarExportDD();
    self.obtenerTodosDatos().then(function(datos) {
        if (!datos || datos.length === 0) { Mensaje.error({ titulo: 'CSV', texto: 'No hay datos para exportar' }); return; }
        var bom = '\uFEFF', rows = [];
        rows.push(['Codigo', 'Cod.Venta', 'Articulo', 'Familia', 'Stock Sist.', 'Costo', 'Conteo Fis.', 'Diferencia'].join(';'));
        datos.forEach(function(a) {
            var stock = parseFloat(a.stock_sistema) || 0;
            var fisico = ConciliacionFisica._fisicos[a.cod_articulo] !== undefined ? ConciliacionFisica._fisicos[a.cod_articulo] : '';
            var diff = fisico !== '' ? fisico - stock : '';
            rows.push(['"'+(a.cod_articulo||'')+'"','"'+(a.cod_vta||'')+'"','"'+(a.nom_art||'').replace(/"/g,'""')+'"','"'+(a.nom_fam||'').replace(/"/g,'""')+'"',stock.toFixed(2).replace('.',','),(parseFloat(a.costo_promedio)||0).toFixed(4).replace('.',','),fisico !== '' ? fisico.toFixed(2).replace('.',',') : '',diff !== '' ? diff.toFixed(2).replace('.',',') : ''].join(';'));
        });
        var a = document.createElement('a');
        a.href = URL.createObjectURL(new Blob([bom + rows.join('\n')], { type: 'text/csv;charset=utf-8' }));
        a.download = 'conciliacion_fisica_' + new Date().toISOString().slice(0, 10) + '.csv';
        a.click();
    });
};

ConciliacionFisica.exportarPDF = function() { this.cerrarExportDD(); this.imprimir(); };

ConciliacionFisica.exportarTXT = function() {
    var self = this;
    self.cerrarExportDD();
    self.obtenerTodosDatos().then(function(datos) {
        if (!datos || datos.length === 0) { Mensaje.error({ titulo: 'TXT', texto: 'No hay datos para exportar' }); return; }
        var rows = [];
        rows.push(['Codigo', 'Cod.Venta', 'Articulo', 'Familia', 'Stock Sist.', 'Costo', 'Conteo Fis.', 'Diferencia'].join('\t'));
        datos.forEach(function(a) {
            var stock = parseFloat(a.stock_sistema) || 0;
            var fisico = ConciliacionFisica._fisicos[a.cod_articulo] !== undefined ? ConciliacionFisica._fisicos[a.cod_articulo] : '';
            var diff = fisico !== '' ? fisico - stock : '';
            rows.push([a.cod_articulo||'',a.cod_vta||'',a.nom_art||'',a.nom_fam||'',stock.toFixed(2),(parseFloat(a.costo_promedio)||0).toFixed(4),fisico !== '' ? fisico.toFixed(2) : '',diff !== '' ? diff.toFixed(2) : ''].join('\t'));
        });
        var a = document.createElement('a');
        a.href = URL.createObjectURL(new Blob([rows.join('\n')], { type: 'text/plain;charset=utf-8' }));
        a.download = 'conciliacion_fisica_' + new Date().toISOString().slice(0, 10) + '.txt';
        a.click();
    });
};

ConciliacionFisica.exportarConciliacion = function() {
    var self = this;
    self.obtenerTodosDatos().then(function(datos) {
        if (!datos || datos.length === 0) { Mensaje.error({ titulo: 'Exportar', texto: 'No hay datos' }); return; }
        function go() {
            var wb = new ExcelJS.Workbook();
            var ws = wb.addWorksheet('Conciliación');
            ws.columns = [
                { header: 'Código', key: 'cod', width: 10 }, { header: 'Artículo', key: 'nombre', width: 30 },
                { header: 'Stock Sist.', key: 'stock', width: 12 }, { header: 'Conteo Fís.', key: 'fisico', width: 12 },
                { header: 'Diferencia', key: 'diff', width: 12 }, { header: 'Valor Dif.', key: 'vdiff', width: 14 }
            ];
            ws.getRow(1).font = { bold: true, color: { argb: 'FFFFFFFF' } };
            ws.getRow(1).fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF1A4480' } };
            datos.forEach(function(a) {
                var stock = parseFloat(a.stock_sistema) || 0;
                var fisico = ConciliacionFisica._fisicos[a.cod_articulo] !== undefined ? ConciliacionFisica._fisicos[a.cod_articulo] : stock;
                var diff = fisico - stock;
                ws.addRow({ cod: a.cod_articulo || '', nombre: a.nom_art || '', stock: stock, fisico: fisico, diff: diff, vdiff: diff * (parseFloat(a.costo_promedio) || 0) });
            });
            wb.xlsx.writeBuffer().then(function(buf) {
                var a = document.createElement('a');
                a.href = URL.createObjectURL(new Blob([buf], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }));
                a.download = 'conciliacion_' + new Date().toISOString().slice(0, 10) + '.xlsx';
                a.click();
            });
        }
        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 = go; document.head.appendChild(s); } else { go(); }
    });
};

ConciliacionFisica._cerrarYajustar = function() {
    var self = this;
    self.ensureSesion();
    if (!self.sesion) return;

    var fisicos = ConciliacionFisica._fisicos;
    var keys = Object.keys(fisicos);
    if (keys.length === 0) {
        Mensaje.error({ titulo: 'Cerrar', texto: 'No hay conteos físicos registrados' });
        return;
    }

    Mensaje.confirmacion({
        titulo: 'Cerrar Inventario y Generar Ajustes',
        texto: '¿Está seguro de cerrar el inventario? Se generarán movimientos de ajuste para todas las diferencias encontradas y se actualizará el stock. Esta operación no se puede deshacer.',
        onAceptar: function() {
            self.obtenerTodosDatos().then(function(datos) {
                if (!datos || datos.length === 0) {
                    Mensaje.error({ titulo: 'Cerrar', texto: 'No hay datos de artículos' });
                    return;
                }

                var items = [];
                datos.forEach(function(a) {
                    var fisico = fisicos[a.cod_articulo];
                    if (fisico !== undefined) {
                        items.push({
                            id_articulo: a.id_articulo,
                            cod_articulo: a.cod_articulo,
                            stock_sistema: parseFloat(a.stock_sistema) || 0,
                            conteo_fisico: parseFloat(fisico) || 0,
                            costo_promedio: parseFloat(a.costo_promedio) || 0
                        });
                    }
                });

                if (items.length === 0) {
                    Mensaje.error({ titulo: 'Cerrar', texto: 'No hay artículos con conteo físico registrado' });
                    return;
                }

                fetch(self.API_URL + '/conciliacion-fisica/cerrar', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        id_empresa: self.sesion.id_empresa,
                        id_sucursal: self.sesion.id_sucursal || null,
                        items: items,
                        usuario: self.sesion.usuario_id || null
                    })
                }).then(function(r) { return r.json(); }).then(function(res) {
                    if (res.ok) {
                        Mensaje.exito({ titulo: 'Ajustes Generados', texto: res.message || 'Ajustes generados correctamente' });
                        ConciliacionFisica._fisicos = {};
                        ConciliacionFisica._guardarFisicos();
                        self.cargarTabla();
                    } else {
                        Mensaje.error({ titulo: 'Error', texto: res.error || 'Error al generar ajustes' });
                    }
                }).catch(function(err) {
                    console.error('[CF] Error al cerrar:', err);
                    Mensaje.error({ titulo: 'Error', texto: 'Error de conexión al generar ajustes' });
                });
            }).catch(function(err) {
                console.error('[CF] Error obtenerTodosDatos:', err);
                Mensaje.error({ titulo: 'Error', texto: 'Error al cargar datos completos' });
            });
        }
    });
};

ConciliacionFisica._verAjustes = function() {
    var self = this;
    self.ensureSesion();
    if (!self.sesion) return;

    var urlAjustes = self.API_URL + '/conciliacion-fisica/ajustes?id_empresa=' + self.sesion.id_empresa;
    if (self.sesion && self.sesion.id_sucursal) urlAjustes += '&id_sucursal=' + self.sesion.id_sucursal;
    fetch(urlAjustes)
        .then(function(r) { return r.json(); })
        .then(function(res) {
            if (!res.ok || !res.data) {
                Mensaje.error({ titulo: 'Ajustes', texto: 'Error al cargar historial' });
                return;
            }

            var data = res.data;
            if (data.length === 0) {
                Mensaje.informacion({ titulo: 'Ajustes', texto: 'No hay ajustes de inventario registrados' });
                return;
            }

            function fmtFecha(d) {
                if (!d) return '-';
                return new Date(d).toLocaleDateString('es-PE', { day: '2-digit', month: '2-digit', year: 'numeric' });
            }

            var html = '<div style="max-height:450px;overflow-y:auto">';
            html += '<table style="width:100%;border-collapse:collapse;font-size:0.78rem">';
            html += '<thead><tr style="background:#1A4480;color:#fff">';
            html += '<th style="padding:8px;text-align:left;border-radius:6px 0 0 0">Documento</th>';
            html += '<th style="padding:8px;text-align:left">Fecha</th>';
            html += '<th style="padding:8px;text-align:right">Artículos</th>';
            html += '<th style="padding:8px;text-align:right">Entradas</th>';
            html += '<th style="padding:8px;text-align:right">Salidas</th>';
            html += '<th style="padding:8px;text-align:center;border-radius:0 6px 0 0">Detalle</th>';
            html += '</tr></thead><tbody>';

            data.forEach(function(d) {
                html += '<tr style="border-bottom:1px solid #E2E8F0">';
                html += '<td style="padding:6px 8px;font-weight:600">' + (d.documento || '') + '</td>';
                html += '<td style="padding:6px 8px">' + fmtFecha(d.fecha) + '</td>';
                html += '<td style="padding:6px 8px;text-align:right">' + (d.items || 0) + '</td>';
                html += '<td style="padding:6px 8px;text-align:right;color:#16a34a;font-weight:600">' + ConciliacionFisica._fmtMiles(d.total_entradas) + '</td>';
                html += '<td style="padding:6px 8px;text-align:right;color:#dc2626;font-weight:600">' + ConciliacionFisica._fmtMiles(d.total_salidas) + '</td>';
                html += '<td style="padding:6px 8px;text-align:center"><button class="cf-ver-detalle-btn" data-doc="' + d.documento + '" style="padding:4px 10px;background:#7c3aed;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:0.72rem;font-weight:600">Ver</button></td>';
                html += '</tr>';
            });

            html += '</tbody></table></div>';

            Modal.abrir({
                titulo: 'Historial de Ajustes de Inventario',
                ancho: '700px',
                contenido: html,
                botones: [{ texto: 'Cerrar', tipo: 'primario', accion: function() { Modal.cerrar(); } }],
                onAbierto: function() {
                    document.querySelectorAll('.cf-ver-detalle-btn').forEach(function(btn) {
                        btn.addEventListener('click', function() {
                            Modal.cerrar();
                            self._verDetalleAjuste(this.getAttribute('data-doc'));
                        });
                    });
                }
            });
        }).catch(function(err) {
            console.error('[CF] Error cargar ajustes:', err);
            Mensaje.error({ titulo: 'Error', texto: 'Error de conexión' });
        });
};

ConciliacionFisica._verDetalleAjuste = function(documento) {
    var self = this;
    self.ensureSesion();
    if (!self.sesion || !documento) return;

    var urlDet = self.API_URL + '/conciliacion-fisica/ajustes/' + encodeURIComponent(documento) + '?id_empresa=' + self.sesion.id_empresa;
    if (self.sesion && self.sesion.id_sucursal) urlDet += '&id_sucursal=' + self.sesion.id_sucursal;
    fetch(urlDet)
        .then(function(r) { return r.json(); })
        .then(function(res) {
            if (!res.ok || !res.data) {
                Mensaje.error({ titulo: 'Detalle', texto: 'Error al cargar detalle' });
                return;
            }

            var items = res.data;
            if (items.length === 0) {
                Mensaje.informacion({ titulo: 'Detalle', texto: 'No hay movimientos para este documento' });
                return;
            }

            var html = '<div style="max-height:450px;overflow-y:auto">';
            html += '<p style="font-weight:700;color:#1A4480;font-size:0.85rem;margin:0 0 8px 0">Documento: ' + documento + '</p>';
            html += '<table style="width:100%;border-collapse:collapse;font-size:0.75rem">';
            html += '<thead><tr style="background:#1A4480;color:#fff">';
            html += '<th style="padding:6px;text-align:left;border-radius:6px 0 0 0">Código</th>';
            html += '<th style="padding:6px;text-align:left">Artículo</th>';
            html += '<th style="padding:6px;text-align:center">Tipo</th>';
            html += '<th style="padding:6px;text-align:right">Cantidad</th>';
            html += '<th style="padding:6px;text-align:right">Costo Unit.</th>';
            html += '<th style="padding:6px;text-align:right;border-radius:0 6px 0 0">Costo Total</th>';
            html += '</tr></thead><tbody>';

            items.forEach(function(it) {
                var tipoLabel = it.tipo === 'E' ? '<span style="color:#16a34a;font-weight:700">ENTRADA</span>' : '<span style="color:#dc2626;font-weight:700">SALIDA</span>';
                html += '<tr style="border-bottom:1px solid #E2E8F0">';
                html += '<td style="padding:5px 6px">' + (it.cod_articulo || '') + '</td>';
                html += '<td style="padding:5px 6px">' + (it.nom_art || '') + '</td>';
                html += '<td style="padding:5px 6px;text-align:center">' + tipoLabel + '</td>';
                html += '<td style="padding:5px 6px;text-align:right;font-weight:600">' + ConciliacionFisica._fmtMiles(it.cantidad) + '</td>';
                html += '<td style="padding:5px 6px;text-align:right">' + ConciliacionFisica._fmtMiles(it.costo_unitario, 4) + '</td>';
                html += '<td style="padding:5px 6px;text-align:right;font-weight:600">S/ ' + ConciliacionFisica._fmtMiles(it.costo_total) + '</td>';
                html += '</tr>';
            });

            html += '</tbody></table></div>';

            Modal.abrir({
                titulo: 'Detalle de Ajuste',
                ancho: '700px',
                contenido: html,
                botones: [{ texto: 'Cerrar', tipo: 'primario', accion: function() { Modal.cerrar(); } }]
            });
        }).catch(function(err) {
            console.error('[CF] Error detalle ajuste:', err);
            Mensaje.error({ titulo: 'Error', texto: 'Error de conexión' });
        });
};

ConciliacionFisica.init({
    title: 'Conciliación Física vs Sistema',
    icon: 'fa-scale-balanced',
    idSingular: 'Artículo',
    idField: 'id_articulo',
    endpoint: '/conciliacion-fisica',
    sortDefault: 'cod_articulo',
    limite: 50,
    searchPlaceholder: 'Buscar por codigo, nombre...',
    filtroEstado: false,
    showEstado: false,
    showAcciones: false,
    showCrear: false,
    exportFileName: 'ConciliacionFisica',
    elementId: 'pageConciliacionFisica',
    menuPage: 'ConciliacionFisica',
    columnFilters: {},
    columns: [
        { field: 'cod_articulo', label: 'Código', sortable: true, filterable: true, width: '8%' },
        { field: 'cod_vta', label: 'Cod Venta', sortable: true, filterable: true, width: '10%',
            render: function(row) { return row.cod_vta || ''; }
        },
        { field: 'nom_art', label: 'Artículo', sortable: true, filterable: true, width: '22%' },
        { field: 'nom_fam', label: 'Familia', sortable: true, filterable: true, width: '14%',
            render: function(row) { return '<span style="color:#64748b">' + (row.nom_fam || '') + '</span>'; }
        },
        { field: 'stock_sistema', label: 'Stock Sist.', sortable: true, filterable: false, width: '10%',
            render: function(row) {
                return '<span style="display:block;text-align:right;font-weight:700">' + ConciliacionFisica._fmtMiles(row.stock_sistema) + '</span>';
            }
        },
        { field: 'costo_promedio', label: 'Costo', sortable: true, filterable: false, width: '10%',
            render: function(row) {
                return '<span style="display:block;text-align:right">' + ConciliacionFisica._fmtMiles(row.costo_promedio, 4) + '</span>';
            }
        },
        { field: 'valor_stock', label: 'Valor Stock', sortable: true, filterable: false, width: '12%',
            render: function(row) {
                return '<span style="display:block;text-align:right;font-weight:700">S/ ' + ConciliacionFisica._fmtMiles(row.valor_stock) + '</span>';
            }
        }
    ],
    onEliminar: null
});
