<?php
/* ==============================================================================
   MÓDULO: TRANSFERENCIAS PRO (FINAL + VISUALIZADOR DE HISTORIAL)
   ============================================================================== */
session_start();
if (!isset($_SESSION['Acceso']) || $_SESSION['Acceso'] !== 'AccesoSiqueSi') { die("Acceso Denegado."); }

header('Content-Type: text/html; charset=utf-8');

// --- 1. CONTEXTO DB ---
$bd_datos  = "MS_Datos";
$bd_global = "MS_Usuario";

// --- 2. PREFIJOS ---
$prefijo = isset($_GET['IDU']) ? $_GET['IDU'] : ($_SESSION['IDU'] ?? '101'); 
$ID_Usuario_Actual = $_SESSION['IDU'] ?? '0';

// --- 3. VARIABLES PARA JS ---
$tb_suc   = $prefijo . "-Sucursales";
?>

<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ttskch/select2-bootstrap4-theme@x.x.x/dist/select2-bootstrap4.min.css">
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script> 
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">

<style>
    body { background-color: #f0f2f5; font-family: 'Inter', 'Segoe UI', sans-serif; }
    
    /* CARDS & UI */
    .card-pro { border: none; border-radius: 12px; box-shadow: 0 4px 15px rgba(0,0,0,0.05); background: white; }
    .card-header-pro { background: #fff; border-bottom: 1px solid #edf2f7; padding: 15px 20px; font-weight: 700; color: #2d3748; border-radius: 12px 12px 0 0; }
    
    /* STEPPER */
    .stepper { display: flex; align-items: center; justify-content: space-between; margin-bottom: 2rem; }
    .step { flex: 1; text-align: center; opacity: 0.5; transition: 0.3s; position: relative; }
    .step.active { opacity: 1; font-weight: bold; color: #3182ce; }
    .step-icon { width: 40px; height: 40px; background: #fff; border: 2px solid #cbd5e0; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10px; z-index: 2; position: relative; }
    .step.active .step-icon { border-color: #3182ce; background: #ebf8ff; color: #3182ce; }
    .step::after { content: ''; position: absolute; top: 20px; left: 50%; width: 100%; height: 2px; background: #e2e8f0; z-index: 0; }
    .step:last-child::after { display: none; }

    /* DUAL LIST BOX (SERIES) */
    .dual-list-container { display: flex; align-items: stretch; justify-content: space-between; height: 400px; }
    .dual-list-box { width: 45%; border: 1px solid #e2e8f0; border-radius: 8px; display: flex; flex-direction: column; overflow: hidden; }
    .dual-header { padding: 10px; background: #f7fafc; border-bottom: 1px solid #e2e8f0; font-weight: 600; font-size: 0.9em; text-transform: uppercase; }
    .dual-search { padding: 8px; border-bottom: 1px solid #e2e8f0; }
    .dual-items { flex: 1; overflow-y: auto; padding: 5px; background: #fff; }
    .serie-item { padding: 6px 10px; margin-bottom: 2px; cursor: pointer; border-radius: 4px; font-family: monospace; display: flex; justify-content: space-between; }
    .serie-item:hover { background-color: #ebf8ff; }
    .serie-item.selected { background-color: #3182ce; color: white; }
    .dual-controls { width: 10%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; }
    .btn-control { width: 40px; height: 40px; border-radius: 50%; border: 1px solid #e2e8f0; background: white; transition: 0.2s; }
    .btn-control:hover { background: #edf2f7; transform: scale(1.1); }
</style>

<div class="container-fluid p-4">
    <div class="d-flex justify-content-between align-items-center mb-4">
        <div><h3 class="font-weight-bold text-dark mb-0">Centro de Transferencias</h3><span class="text-muted">Movimientos entre almacenes</span></div>
        <div>
            <button class="btn btn-info shadow-sm mr-2 font-weight-bold" onclick="abrirHistorial()"><i class="fas fa-history mr-2"></i>Historial</button>
            <button class="btn btn-dark shadow-sm font-weight-bold" onclick="$('#modalRecepcion').modal('show')"><i class="fas fa-search-location mr-2"></i>Rastrear / Recibir</button>
        </div>
    </div>

    <div class="stepper">
        <div class="step active" id="step1"><div class="step-icon"><i class="fas fa-map-marker-alt"></i></div><small>Ruta</small></div>
        <div class="step" id="step2"><div class="step-icon"><i class="fas fa-box-open"></i></div><small>Productos</small></div>
        <div class="step" id="step3"><div class="step-icon"><i class="fas fa-check"></i></div><small>Confirmar</small></div>
    </div>

    <div class="row">
        <div class="col-lg-4 mb-4">
            <div class="card-pro h-100">
                <div class="card-header-pro">1. Ruta</div>
                <div class="card-body">
                    <div class="form-group">
                        <label class="font-weight-bold small text-muted">ORIGEN (SALIDA)</label>
                        <select id="sel_origen" class="form-control font-weight-bold" style="height: 50px;"><option value="">Cargando...</option></select>
                    </div>
                    <div class="text-center py-2"><i class="fas fa-arrow-down text-primary"></i></div>
                    <div class="form-group">
                        <label class="font-weight-bold small text-muted">DESTINO (ENTRADA)</label>
                        <select id="sel_destino" class="form-control font-weight-bold" style="height: 50px;"><option value="">Cargando...</option></select>
                    </div>
                </div>
            </div>
        </div>

        <div class="col-lg-8 mb-4">
            <div class="card-pro h-100" id="panel_productos" style="opacity: 0.6; pointer-events: none;">
                <div class="card-header-pro d-flex justify-content-between">
                    <span>2. Paquete</span>
                    <span class="badge badge-primary px-3 py-2" id="cart_counter">0 Ítems</span>
                </div>
                <div class="card-body bg-light">
                    <div class="input-group input-group-lg shadow-sm mb-4">
                        <select id="buscador_productos" class="form-control"></select>
                    </div>
                    <div class="bg-white rounded border shadow-sm table-responsive" style="height: 350px;">
                        <table class="table table-hover mb-0">
                            <thead class="bg-white small text-muted"><tr><th class="pl-4">Producto</th><th class="text-center">Tipo</th><th class="text-center">Cant</th><th class="text-right pr-4">Acción</th></tr></thead>
                            <tbody id="cart_body"><tr><td colspan="4" class="text-center py-5 text-muted">Selecciona ruta...</td></tr></tbody>
                        </table>
                    </div>
                </div>
                <div class="card-footer bg-white p-3">
                    <button class="btn btn-success btn-lg btn-block font-weight-bold shadow-sm" id="btn_enviar" disabled onclick="enviarTransferencia()">
                        <i class="fas fa-paper-plane mr-2"></i> PROCESAR ENVÍO
                    </button>
                </div>
            </div>
        </div>
    </div>
</div>

<div class="modal fade" id="modalSeriesManager" data-backdrop="static" tabindex="-1">
    <div class="modal-dialog modal-lg modal-dialog-centered">
        <div class="modal-content border-0 shadow-lg">
            <div class="modal-header bg-dark text-white">
                <div><h5 class="modal-title font-weight-bold" id="lbl_modal_prod">Series</h5><small class="text-white-50" id="lbl_modal_sku">SKU: ---</small></div>
                <button type="button" class="close text-white" data-dismiss="modal"><span>&times;</span></button>
            </div>
            <div class="modal-body bg-light">
                <div class="dual-list-container">
                    <div class="dual-list-box bg-white">
                        <div class="dual-header text-success">Disponibles (<span id="count_available">0</span>)</div>
                        <div class="dual-search"><input type="text" id="search_available" class="form-control form-control-sm border-0 bg-light" placeholder="Buscar..."></div>
                        <div class="dual-items" id="list_available"></div>
                    </div>
                    <div class="dual-controls">
                        <button class="btn-control" onclick="moveAll('right')"><i class="fas fa-angle-double-right"></i></button>
                        <button class="btn-control" onclick="moveSelected('right')"><i class="fas fa-angle-right"></i></button>
                        <button class="btn-control" onclick="moveSelected('left')"><i class="fas fa-angle-left"></i></button>
                        <button class="btn-control" onclick="moveAll('left')"><i class="fas fa-angle-double-left"></i></button>
                    </div>
                    <div class="dual-list-box bg-white border-primary">
                        <div class="dual-header text-primary">A Transferir (<span id="count_selected">0</span>)</div>
                        <div class="dual-search"><input type="text" id="search_selected" class="form-control form-control-sm border-0 bg-light" placeholder="Buscar..."></div>
                        <div class="dual-items" id="list_selected"></div>
                    </div>
                </div>
            </div>
            <div class="modal-footer bg-white">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancelar</button>
                <button type="button" class="btn btn-primary px-4 font-weight-bold" onclick="confirmarSeries()"><i class="fas fa-check mr-2"></i>Confirmar</button>
            </div>
        </div>
    </div>
</div>

<div class="modal fade" id="modalHistorial">
    <div class="modal-dialog modal-lg modal-dialog-scrollable">
        <div class="modal-content border-0">
            <div class="modal-header bg-info text-white">
                <h5 class="modal-title font-weight-bold"><i class="fas fa-history mr-2"></i>Historial de Envíos</h5>
                <button class="close text-white" data-dismiss="modal"><span>&times;</span></button>
            </div>
            <div class="modal-body bg-light">
                <div class="row mb-3">
                    <div class="col-md-8">
                        <label class="small font-weight-bold">Fecha</label>
                        <input type="date" id="fecha_hist" class="form-control" value="<?php echo date('Y-m-d'); ?>">
                    </div>
                    <div class="col-md-4 d-flex align-items-end">
                        <button class="btn btn-info btn-block font-weight-bold" onclick="cargarBitacora()"><i class="fas fa-search mr-2"></i>Filtrar</button>
                    </div>
                </div>
                <div class="bg-white rounded shadow-sm table-responsive" style="min-height: 200px;">
                    <table class="table table-hover mb-0 small">
                        <thead class="thead-light"><tr><th>Folio</th><th>Destino</th><th>Hora</th><th class="text-right">Acciones</th></tr></thead>
                        <tbody id="hist_tbody"><tr><td colspan="4" class="text-center p-4 text-muted">Selecciona una sucursal de origen para ver su historial.</td></tr></tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>

<div class="modal fade" id="modalVerDetalles">
    <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content border-0">
            <div class="modal-header bg-light">
                <h5 class="modal-title font-weight-bold" id="lbl_ver_folio">Folio: ---</h5>
                <button class="close" data-dismiss="modal"><span>&times;</span></button>
            </div>
            <div class="modal-body p-0 table-responsive" style="max-height: 400px;">
                <table class="table table-striped mb-0">
                    <thead class="bg-white sticky-top">
                        <tr><th class="pl-4">Producto / Serie</th><th class="text-right pr-4">Cant</th></tr>
                    </thead>
                    <tbody id="ver_tbody"></tbody>
                </table>
            </div>
            <div class="modal-footer">
                <button class="btn btn-secondary btn-sm" data-dismiss="modal">Cerrar</button>
            </div>
        </div>
    </div>
</div>

<div class="modal fade" id="modalRecepcion">
    <div class="modal-dialog modal-lg">
        <div class="modal-content border-0">
            <div class="modal-header bg-dark text-white">
                <h5 class="modal-title font-weight-bold"><i class="fas fa-search-location mr-2"></i>Rastreador de Paquetes</h5>
                <button class="close text-white" data-dismiss="modal"><span>&times;</span></button>
            </div>
            <div class="modal-body">
                <div class="input-group mb-4">
                    <input type="text" id="scan_uuid" class="form-control form-control-lg" placeholder="Escanear Folio (TR-...)">
                    <div class="input-group-append"><button class="btn btn-primary px-4" onclick="buscarEnNube()">BUSCAR</button></div>
                </div>
                
                <div id="ui_recepcion" class="d-none">
                    <div class="alert alert-info border-0 shadow-sm">
                        <div class="d-flex justify-content-between">
                            <span><strong>Folio:</strong> <span id="rec_uuid"></span></span>
                            <span><strong>Estado:</strong> <span id="rec_status" class="badge badge-warning">---</span></span>
                        </div>
                    </div>
                    <div class="table-responsive border rounded mb-3" style="max-height: 250px;">
                        <table class="table table-sm table-striped mb-0 small">
                            <thead class="bg-light sticky-top"><tr><th>SKU</th><th>Producto</th><th class="text-right">Cant</th></tr></thead>
                            <tbody id="rec_tbody"></tbody>
                        </table>
                    </div>
                    <a href="Recepcion.php" class="btn btn-outline-dark btn-block">Ir al Módulo de Recepción para procesar</a>
                </div>
            </div>
        </div>
    </div>
</div>

<div class="modal fade" id="modalExito"><div class="modal-dialog modal-dialog-centered"><div class="modal-content border-0"><div class="modal-body text-center p-5"><div class="mb-3 text-success"><i class="fas fa-check-circle fa-4x"></i></div><h2 class="font-weight-bold">¡Transferencia Exitosa!</h2><h4 class="text-muted mb-4" id="folio_final">---</h4><div id="qr_code" class="d-flex justify-content-center mb-4"></div><button class="btn btn-outline-dark" onclick="location.reload()">Nuevo Envío</button></div></div></div></div>

<script>
    // --- VARIABLES CONFIG ---
    const DB_DATOS  = "<?php echo $bd_datos; ?>";
    const DB_GLOBAL = "<?php echo $bd_global; ?>";
    const USER_ID   = "<?php echo $ID_Usuario_Actual; ?>";
    const T_SUC     = "<?php echo $tb_suc; ?>";

    let CART = [];
    let TEMP_PRODUCT = null;
    let TEMP_SERIES_POOL = [];
    let TEMP_SERIES_SELECTED = [];
    let SUCURSALES_CACHE = {}; 

    // --- INICIALIZACIÓN ---
    $(document).ready(() => {
        $('#buscador_productos').select2({ theme: 'bootstrap4', placeholder: 'Buscar producto...', width: '100%', allowClear: true });
        cargarSucursales();
        setupListeners();
    });

    function setupListeners() {
        $('#sel_origen').on('change', function() {
            if(CART.length > 0 && !confirm('Se vaciará el carrito. ¿Continuar?')) { $(this).val($(this).data('prev')); return; }
            CART = []; renderCart();
            $(this).data('prev', $(this).val());
            validarRuta();
            if($(this).val()) cargarCatalogo($(this).val());
        });
        $('#sel_destino').on('change', validarRuta);
        $('#buscador_productos').on('select2:select', function(e) { verificarProducto($(e.params.data.element).data()); });
        $('#search_available').on('keyup', function() { filterList('list_available', $(this).val()); });
        $('#search_selected').on('keyup', function() { filterList('list_selected', $(this).val()); });
        $('#scan_uuid').on('keypress', function(e) { if(e.which == 13) buscarEnNube(); });
    }

    // --- AJAX HELPERS ---
    async function apiSelect(sql, db) {
        try { const fd = new FormData(); fd.append('sql', sql); fd.append('db', db); return await (await fetch('../librerias/AJAX/Select.php', {method:'POST', body:fd})).json(); } 
        catch(e) { console.error(e); return {data:[]}; }
    }
    async function apiExecute(sql, db) {
        try { const fd = new FormData(); fd.append('sql', sql); fd.append('db', db); return await (await fetch('../librerias/AJAX/Execute.php', {method:'POST', body:fd})).json(); } 
        catch(e) { return {error:e.message}; }
    }

    // --- CARGA DE DATOS ---
    async function cargarSucursales() {
        const r = await apiSelect(`SELECT IDS, nombre FROM \`${DB_DATOS}\`.\`${T_SUC}\` WHERE activo=1`, DB_DATOS);
        let html = '<option value="">-- Seleccionar --</option>';
        (r.data || []).forEach(s => { 
            html += `<option value="${s.IDS}">${s.nombre}</option>`;
            SUCURSALES_CACHE[s.IDS] = s.nombre; 
        });
        $('#sel_origen').html(html); $('#sel_destino').html(html);
    }

    async function cargarCatalogo(idSuc) {
        $('#buscador_productos').empty().trigger('change');
        const tb_inv = `${idSuc}-Productos_Inventario`;
        const tb_cat = `${idSuc}-Productos_Catalogo`;
        const sql = `SELECT I.sku, C.nombre, I.existencia FROM \`${DB_DATOS}\`.\`${tb_inv}\` I JOIN \`${DB_DATOS}\`.\`${tb_cat}\` C ON I.sku = C.sku WHERE I.existencia > 0 ORDER BY C.nombre ASC`;
        const r = await apiSelect(sql, DB_DATOS);
        (r.data || []).forEach(p => {
            const opt = new Option(`${p.nombre} (Stock: ${p.existencia})`, p.sku, false, false);
            $(opt).data('obj', p); $('#buscador_productos').append(opt);
        });
    }

    function validarRuta() {
        const ok = ($('#sel_origen').val() && $('#sel_destino').val() && $('#sel_origen').val() !== $('#sel_destino').val());
        $('#panel_productos').css({ opacity: ok?1:0.6, pointerEvents: ok?'all':'none' });
        $('.step').removeClass('active');
        if(ok) $('#step2').addClass('active'); else $('#step1').addClass('active');
    }

    // --- SERIES ---
    async function verificarProducto(dataRaw) {
        const p = dataRaw.obj;
        const idSuc = $('#sel_origen').val();
        TEMP_PRODUCT = p;
        const skuLimpio = String(p.sku).trim();
        const tablaSeries = `${idSuc}-Productos_Series`; 

        const sql = `SELECT Serie FROM \`${DB_DATOS}\`.\`${tablaSeries}\` WHERE TRIM(SKU) = '${skuLimpio}' AND Estado = 'DISPONIBLE'`;
        const res = await apiSelect(sql, DB_DATOS);
        const series = res.data || [];

        if (series.length > 0) {
            TEMP_SERIES_POOL = series.map(s => s.Serie);
            TEMP_SERIES_SELECTED = [];
            abrirGestorSeries();
        } else {
            const { value: cant } = await Swal.fire({
                title: 'Cantidad', text: `${p.nombre}`, input: 'number', inputValue: 1,
                inputAttributes: { min: 1, max: parseFloat(p.existencia), step: 1 },
                showCancelButton: true
            });
            if (cant) agregarAlCarrito(cant, []); else $('#buscador_productos').val(null).trigger('change');
        }
    }

    function abrirGestorSeries() {
        $('#lbl_modal_prod').text(TEMP_PRODUCT.nombre);
        $('#lbl_modal_sku').text('SKU: ' + TEMP_PRODUCT.sku);
        renderDualList();
        $('#modalSeriesManager').modal('show');
    }

    function renderDualList() {
        const listAv = $('#list_available').empty();
        const listSel = $('#list_selected').empty();
        TEMP_SERIES_POOL.forEach(s => { if(!TEMP_SERIES_SELECTED.includes(s)) listAv.append(`<div class="serie-item" onclick="$(this).toggleClass('selected')">${s}</div>`); });
        TEMP_SERIES_SELECTED.forEach(s => listSel.append(`<div class="serie-item" onclick="$(this).toggleClass('selected')">${s}</div>`));
        $('#count_available').text(TEMP_SERIES_POOL.length - TEMP_SERIES_SELECTED.length);
        $('#count_selected').text(TEMP_SERIES_SELECTED.length);
    }

    window.moveSelected = (dir) => {
        if(dir==='right') $('#list_available .serie-item.selected').each(function(){ TEMP_SERIES_SELECTED.push($(this).text()); });
        else $('#list_selected .serie-item.selected').each(function(){ const s=$(this).text(); TEMP_SERIES_SELECTED=TEMP_SERIES_SELECTED.filter(i=>i!==s); });
        renderDualList();
    };
    window.moveAll = (dir) => { TEMP_SERIES_SELECTED = (dir==='right') ? [...TEMP_SERIES_POOL] : []; renderDualList(); };
    function filterList(id, txt) { $(`#${id} .serie-item`).toggle(function(){ return $(this).text().toLowerCase().indexOf(txt.toLowerCase())>-1 }); }
    window.confirmarSeries = () => { if(TEMP_SERIES_SELECTED.length===0){ Swal.fire('Error', 'Selecciona series', 'warning'); return; } agregarAlCarrito(TEMP_SERIES_SELECTED.length, TEMP_SERIES_SELECTED); $('#modalSeriesManager').modal('hide'); };

    // --- CARRITO ---
    function agregarAlCarrito(cant, series) {
        if(CART.find(i => i.sku === TEMP_PRODUCT.sku)) { Swal.fire('Error', 'Producto ya agregado', 'warning'); return; }
        CART.push({ sku: TEMP_PRODUCT.sku, nombre: TEMP_PRODUCT.nombre, cantidad: parseFloat(cant), series: series });
        renderCart(); $('#buscador_productos').val(null).trigger('change');
    }

    function renderCart() {
        const tb = $('#cart_body').empty();
        if(CART.length===0) { tb.html('<tr><td colspan="4" class="text-center py-5">Vacío</td></tr>'); $('#btn_enviar').prop('disabled',true); $('#cart_counter').text('0'); return; }
        CART.forEach((i, idx) => {
            let info = i.series.length>0 ? `<div class="mt-1 small text-muted"><i class="fas fa-barcode"></i> ${i.series.slice(0,3).join(', ')}...</div>` : '';
            let type = i.series.length>0 ? '<span class="badge badge-info">Serie</span>' : '<span class="badge badge-secondary">Normal</span>';
            tb.append(`<tr><td class="pl-4"><b>${i.nombre}</b><br><small>${i.sku}</small>${info}</td><td class="text-center">${type}</td><td class="text-center h5">${i.cantidad}</td><td class="text-right pr-4"><button class="btn btn-sm btn-outline-danger" onclick="CART.splice(${idx},1); renderCart();"><i class="fas fa-times"></i></button></td></tr>`);
        });
        $('#cart_counter').text(CART.length); $('#btn_enviar').prop('disabled',false); $('#step3').addClass('active');
    }

    window.enviarTransferencia = async () => {
        const idO = $('#sel_origen').val();
        const idD = $('#sel_destino').val();
        const folio = "TR-" + Date.now();
        const json = JSON.stringify(CART).replace(/\\/g, '\\\\').replace(/'/g, "\\'");
        
        if(!(await Swal.fire({title:'¿Confirmar?', text:`${CART.length} productos`, icon:'question', showCancelButton:true})).isConfirmed) return;
        Swal.showLoading();

        try {
            const T_TRANS_G = "Transferencias";
            const T_BIT_L   = `${idO}-Productos_Transferencias_Bitacora`;
            const T_INV_L   = `${idO}-Productos_Inventario`;
            const T_MOV_L   = `${idO}-Productos_Movimientos`;
            const T_SER_L   = `${idO}-Productos_Series`; 

            // 1. GLOBAL
            let res = await apiExecute(`INSERT INTO \`${DB_GLOBAL}\`.\`${T_TRANS_G}\` (UUID_Unico, IDS_Origen, IDS_Destino, IDU_Emisor, Contenido_Paquete, Estado) VALUES ('${folio}', ${idO}, ${idD}, '${USER_ID}', '${json}', 'EN_TRANSITO')`, DB_GLOBAL);
            if(res.error) throw new Error("Error Global: "+res.error);

            // 2. LOCAL BITACORA
            res = await apiExecute(`INSERT INTO \`${DB_DATOS}\`.\`${T_BIT_L}\` (Folio, IDS_Origen, IDS_Destino, IDU_Usuario, Items_JSON) VALUES ('${folio}', ${idO}, ${idD}, ${USER_ID}, '${json}')`, DB_DATOS);
            if(res.error) throw new Error("Error Local: "+res.error);

            // 3. MOVIMIENTOS
            for(const i of CART) {
                let batch = `UPDATE \`${DB_DATOS}\`.\`${T_INV_L}\` SET existencia = existencia - ${i.cantidad} WHERE sku='${i.sku}'; `;
                batch += `INSERT INTO \`${DB_DATOS}\`.\`${T_MOV_L}\` (sku, IDS_Origen, IDS_Destino, cantidad, tipo_movimiento, IDU_Usuario, notas) VALUES ('${i.sku}', ${idO}, ${idD}, ${i.cantidad}, 'SALIDA_TRANSFER', ${USER_ID}, 'Folio: ${folio}'); `;
                
                if(i.series.length > 0) {
                    const lista = i.series.map(s => `'${s}'`).join(',');
                    batch += `UPDATE \`${DB_DATOS}\`.\`${T_SER_L}\` SET Estado='EN_TRANSITO' WHERE SKU='${i.sku}' AND Serie IN (${lista}); `;
                }
                await apiExecute(batch, DB_DATOS);
            }

            $('#folio_final').text(folio); $('#qr_code').empty(); new QRCode(document.getElementById("qr_code"), {text:folio, width:128, height:128});
            
            // Boton impresion en modal exito
            if($('#btn_imprimir_exito').length === 0) $('#modalExito .modal-body').append('<button id="btn_imprimir_exito" class="btn btn-outline-primary mt-2" onclick="reimprimirDesdeHistorial(\''+folio+'\', \''+json+'\')"><i class="fas fa-print"></i> Imprimir Ticket</button>');
            else $('#btn_imprimir_exito').attr('onclick', `reimprimirDesdeHistorial('${folio}', '${json}')`);

            $('#modalExito').modal('show'); CART=[]; renderCart();

        } catch(e) { Swal.fire('Error', e.message, 'error'); }
    };

    // --- FUNCIONES HISTORIAL Y VISUALIZACION ---
    window.abrirHistorial = () => { 
        const idO = $('#sel_origen').val();
        if(!idO) Swal.fire('Info', 'Selecciona una sucursal de Origen primero para ver su historial.', 'info');
        $('#modalHistorial').modal('show'); 
        if(idO) cargarBitacora(); 
    }
    
    window.cargarBitacora = async () => {
        const idSuc = $('#sel_origen').val() || "<?php echo $prefijo; ?>";
        const fecha = $('#fecha_hist').val();
        const tb_bit = `${idSuc}-Productos_Transferencias_Bitacora`;
        
        const sql = `SELECT * FROM \`${DB_DATOS}\`.\`${tb_bit}\` WHERE DATE(fecha) = '${fecha}' ORDER BY fecha DESC`;
        const res = await apiSelect(sql, DB_DATOS);
        const tb = $('#hist_tbody').empty();
        
        if(res.data && res.data.length > 0) {
            res.data.forEach(d => {
                const itemsJson = d.Items_JSON.replace(/"/g, "&quot;"); // Escape simple para pasar por atributo
                const nomDest = SUCURSALES_CACHE[d.IDS_Destino] || d.IDS_Destino;
                const hora = new Date(d.fecha).toLocaleTimeString();
                
                tb.append(`
                    <tr>
                        <td class="font-weight-bold">${d.Folio}</td>
                        <td><i class="fas fa-arrow-right text-muted mr-1"></i> ${nomDest}</td>
                        <td>${hora}</td>
                        <td class="text-right">
                            <button class="btn btn-sm btn-info mr-1" title="Ver Detalles" onclick="verDetalles('${d.Folio}', '${itemsJson}')">
                                <i class="fas fa-eye"></i>
                            </button>
                            <button class="btn btn-sm btn-dark" title="Imprimir" onclick="reimprimirDesdeHistorial('${d.Folio}', '${itemsJson}')">
                                <i class="fas fa-print"></i>
                            </button>
                        </td>
                    </tr>`);
            });
        } else {
            tb.html('<tr><td colspan="4" class="text-center p-4 text-muted">Sin movimientos para esta fecha/sucursal</td></tr>');
        }
    }

    // --- NUEVA FUNCIÓN PARA VISUALIZAR ---
    window.verDetalles = (folio, jsonItems) => {
        const items = JSON.parse(jsonItems);
        const tbody = $('#ver_tbody').empty();
        $('#lbl_ver_folio').text('Folio: ' + folio);

        items.forEach(i => {
            let info = i.sku;
            if(i.series && i.series.length > 0) {
                info += `<div class="text-muted small mt-1"><i class="fas fa-barcode"></i> ${i.series.join(', ')}</div>`;
            }
            tbody.append(`<tr><td class="pl-4"><b>${i.nombre}</b><br><small>${info}</small></td><td class="text-right pr-4 font-weight-bold">${i.cantidad}</td></tr>`);
        });

        $('#modalVerDetalles').modal('show');
    }

    window.reimprimirDesdeHistorial = (folio, jsonItems) => {
        const items = JSON.parse(jsonItems);
        let h = ''; 
        items.forEach(i => h+=`<tr><td style="text-align:left">${i.nombre}</td><td style="text-align:right">${i.cantidad}</td></tr>`);
        const w = window.open('','_blank');
        w.document.write(`<html><body style="font-family:monospace; text-align:center; width: 80mm;"><h3>TRANSFERENCIA</h3><h2 style="margin:5px 0">${folio}</h2><hr><table width="100%" style="font-size:12px"><tr><th align="left">Producto</th><th align="right">Cant</th></tr>${h}</table><hr><div style="font-size:10px">Reimpresión: ${new Date().toLocaleString()}</div></body></html>`);
        w.document.close(); setTimeout(()=> { w.print(); w.close(); }, 500);
    }

    // --- RASTREO ---
    window.buscarEnNube = async () => {
        const uuid = $('#scan_uuid').val().trim();
        if(!uuid) return;
        const sql = `SELECT * FROM \`${DB_GLOBAL}\`.Transferencias WHERE UUID_Unico='${uuid}' LIMIT 1`;
        const res = await apiSelect(sql, DB_GLOBAL);
        
        if(res.data && res.data.length > 0) {
            const t = res.data[0];
            $('#rec_uuid').text(t.UUID_Unico);
            $('#rec_status').text(t.Estado).removeClass().addClass('badge badge-' + (t.Estado=='RECIBIDA'?'success':'warning'));
            $('#ui_recepcion').removeClass('d-none');
            const items = JSON.parse(t.Contenido_Paquete);
            const tb = $('#rec_tbody').empty();
            items.forEach(i => tb.append(`<tr><td>${i.sku}</td><td>${i.nombre}</td><td class="text-right">${i.cantidad}</td></tr>`));
        } else {
            Swal.fire('No encontrado', 'Folio no existe en la nube.', 'error');
            $('#ui_recepcion').addClass('d-none');
        }
    }
</script>