<?php
include 'TablaConfiguracion.php'; 

$solicitudGlobales = $config['acciones']['globales'] ?? [];
$solicitudFila     = $config['acciones']['fila'] ?? [];
$accionesFilaJS    = construirConfigRenglon($solicitudFila);

$configJS = [
    "sql"          => $config['consulta_select'] ?? '',
    "tableName"    => $config['tabla_sql'] ?? '',
    "primaryKey"   => $config['primary_key'] ?? 'id', 
    "editableCols" => array_column(array_filter($config['columnas'], function($c) { return $c['editable'] ?? false; }), 'key'),
    "columns"      => array_column($config['columnas'], 'key'),
    "headers"      => array_column($config['columnas'], 'label'),
    "actionsRow"   => $accionesFilaJS
];
?>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">

<style>
    /* =========================================
       ESTILOS DE ALTO CONTRASTE (NEGRO PURO)
       ========================================= */
    body { 
        color: #000000 !important; 
    }

    /* Forzar negro en tablas, inputs, etiquetas y modales */
    .table, .form-control, .form-select, label, h1, h2, h3, h4, h5, .modal-title, .modal-body {
        color: #000000 !important;
    }

    /* Placeholder un poco más claro pero visible */
    ::placeholder {
        color: #666 !important;
        opacity: 1;
    }

    /* Cabecera limpia */
    .thead-premium th {
        background-color: #f8f9fa;
        color: #000000 !important;
        font-weight: 800; /* Extra bold */
        font-size: 0.75rem;
        text-transform: uppercase;
        border-bottom: 2px solid #000000;
        padding: 1rem;
    }
    
    /* Filas y celdas */
    .tr-hover:hover td {
        background-color: #e9ecef; /* Hover un poco más oscuro para contraste */
    }
    
    /* Input Search */
    .search-pill {
        border-radius: 50px;
        background-color: #fff;
        border: 1px solid #ced4da;
        color: #000000 !important;
    }
    
    /* Input Edición Inline */
    .input-inline-edit {
        color: #000000 !important;
        font-weight: bold;
        background-color: #fff;
    }

    /* Asegurar que los inputs dentro de SweetAlert también sean negros */
    div:where(.swal2-container) input:where(.swal2-input), 
    div:where(.swal2-container) input:where(.swal2-file), 
    div:where(.swal2-container) textarea:where(.swal2-textarea), 
    div:where(.swal2-container) select:where(.swal2-select), 
    div:where(.swal2-container) div:where(.swal2-html-container) {
        color: #000000 !important;
    }
</style>

<div class="container-fluid p-0 mt-4">
    <div class="card border-0 shadow-sm rounded-3">
        
        <div class="card-header bg-white py-3 px-4 border-bottom-0">
            <div class="row align-items-center gy-2">
                <div class="col-12 col-md-6">
                    <h5 class="mb-0 fw-bold text-black"><?php echo $config['titulo']; ?></h5>
                    <small class="text-dark"><?php echo $config['subtitulo']; ?></small>
                </div>
                
                <div class="col-12 col-md-6">
                    <div class="d-flex justify-content-md-end align-items-center gap-3">
                        <div class="position-relative" style="width: 220px;">
                            <input type="text" id="globalSearch" class="form-control search-pill ps-4" placeholder="Buscar..." style="height: 38px;">
                            <i class="fas fa-search text-dark position-absolute" style="right: 15px; top: 11px; font-size: 0.8rem;"></i>
                        </div>
                        <div class="vr h-50 mx-1 text-dark opacity-25 d-none d-md-block"></div>
                        <?php echo construirHTMLGlobales($solicitudGlobales); ?>
                    </div>
                </div>
            </div>
        </div>

        <div class="table-responsive">
            <table class="table align-middle mb-0" id="tbl_maestra">
                <thead class="thead-premium">
                    <tr><td class="text-center p-5">Cargando...</td></tr>
                </thead>
                <tbody class="border-top-0"></tbody>
            </table>
        </div>
        
        <div class="card-footer bg-white py-3 px-4 border-top">
            <div class="d-flex justify-content-between align-items-center">
                <span class="badge bg-dark text-white fw-normal px-3" id="info_filas">...</span>
                <small class="text-dark fw-bold">Resultados</small>
            </div>
        </div>
    </div>
</div>

<div class="modal fade" id="modalCrear" tabindex="-1" data-bs-backdrop="static">
    <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content border-0 shadow">
            <div class="modal-header bg-white border-bottom-0 pb-0">
                <h5 class="modal-title fw-bold text-black">Nuevo Registro</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body pt-4">
                <form id="formDinamico" class="row g-3">
                    <?php foreach(($config['campos_formulario'] ?? []) as $campo): ?>
                        <div class="col-12">
                            <label class="form-label small fw-bold text-black text-uppercase"><?php echo $campo['label']; ?></label>
                            <input type="<?php echo $campo['type']; ?>" class="form-control border-secondary text-black" id="new_<?php echo $campo['name']; ?>" <?php echo ($campo['required']??false) ? 'required' : ''; ?>>
                        </div>
                    <?php endforeach; ?>
                </form>
            </div>
            <div class="modal-footer border-top-0">
                <button type="button" class="btn btn-light text-black border" data-bs-dismiss="modal">Cancelar</button>
                <button type="button" class="btn btn-dark px-4" onclick="tsManager.guardarNuevo()">Guardar</button>
            </div>
        </div>
    </div>
</div>

<script>

	class SQLClient {
    constructor(dbName) { this.db = dbName; }
    
    async request(endpoint, sql) {
        try {
            // 1. Hacemos la petición
            const r = await fetch(`../librerias/AJAX/${endpoint}`, { 
                method: 'POST', 
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: new URLSearchParams({ db: this.db, sql: sql })
            });

            // 2. Obtenemos el texto crudo ANTES de intentar convertir a JSON
            const rawText = await r.text();

            // 3. Verificamos si hubo error HTTP (404, 500, etc)
            if(!r.ok) throw new Error(`HTTP Error ${r.status}: ${rawText}`);

            // 4. Intentamos parsear el JSON
            try {
                const json = JSON.parse(rawText);
                return json;
            } catch (jsonError) {
                // AQUÍ ESTÁ LA CLAVE: Si falla el JSON, es porque PHP escupió un error de texto
                console.error("🔥 ERROR CRÍTICO DEL SERVIDOR (PHP/SQL):", rawText);
                throw new Error("El servidor devolvió datos inválidos. Revisa la consola (F12) para ver el error rojo.");
            }

        } catch(e) { 
            // Mostramos el error en pantalla
            Swal.fire({
                title: 'Error de Sistema',
                text: e.message,
                icon: 'error',
                footer: 'Ver consola (F12) para detalles técnicos'
            });
            return {status:'error', error: e.message}; 
        }
    }

    select(sql) { return this.request('Select.php', sql); }
    query(sql) { return this.request('Execute.php', sql); }
}

class TableManager {
    constructor(config, dbName) {
        this.cfg = config;
        this.db = new SQLClient(dbName);
        this.data = [];
        this.init();
    }
    init() {
        this.refresh();
        document.getElementById('globalSearch')?.addEventListener('keyup', (e) => this.filter(e.target.value));
        document.querySelector('#tbl_maestra tbody')?.addEventListener('click', (e) => {
            const cell = e.target.closest('td');
            if(cell && cell.dataset.editable === "true" && !cell.classList.contains('p-0')) {
                this.enableInlineEdit(cell);
            }
        });
    }
    async refresh() {
        const tbody = document.querySelector('#tbl_maestra tbody');
        tbody.innerHTML = '<tr><td colspan="100" class="text-center p-5"><div class="spinner-border text-dark" role="status"></div></td></tr>';
        const res = await this.db.select(this.cfg.sql);
        if(res.status==='success') { this.data=res.data; this.render(this.data); }
        else tbody.innerHTML = `<tr><td colspan="100" class="text-center p-5 text-danger fw-bold">${res.error}</td></tr>`;
    }
    render(rows) {
        const thead = document.querySelector('#tbl_maestra thead');
        const tbody = document.querySelector('#tbl_maestra tbody');
        
        let hh = '<tr>';
        this.cfg.headers.forEach(h => hh += `<th>${h}</th>`);
        if(this.cfg.actionsRow.length > 0) hh += '<th class="text-end pe-4" width="150px">ACCIONES</th>';
        hh += '</tr>';
        thead.innerHTML = hh;

        if(!rows || !rows.length) { 
            tbody.innerHTML='<tr><td colspan="100" class="text-center p-5 text-black">Sin datos encontrados</td></tr>'; 
            document.getElementById('info_filas').innerText = '0';
            return; 
        }

        let bh = '';
        rows.forEach(row => {
            const id = row[this.cfg.primaryKey]; 
            bh += `<tr class="tr-hover">`;
            this.cfg.columns.forEach(colKey => {
                const val = row[colKey] !== null ? row[colKey] : '';
                const isEditable = this.cfg.editableCols.includes(colKey);
                // Texto negro forzado
                bh += `<td class="px-3 py-3 text-black" 
                           ${isEditable ? 'data-editable="true" style="cursor:pointer;" title="Clic para editar"' : ''} 
                           data-id="${id}" data-col="${colKey}">${val}</td>`;
            });
            
            if(this.cfg.actionsRow.length > 0) {
                bh += '<td class="text-end pe-4">';
                this.cfg.actionsRow.forEach(act => {
                    let onclick = act.onclick.replace(/{ID}/g, id).replace(/{IDU}/g, id);
                    Object.keys(row).forEach(key => { onclick = onclick.replace(new RegExp(`{${key}}`,'g'), row[key]); });
                    
                    bh += `<button class="btn btn-sm btn-light text-black border-0 rounded-circle mx-1" 
                           style="width:32px; height:32px; padding:0; background-color: #f1f1f1;"
                           onclick="${onclick}" title="${act.titulo}" data-bs-toggle="tooltip">
                           <i class="${act.icono}"></i></button>`;
                });
                bh += '</td>';
            }
            bh += `</tr>`;
        });
        tbody.innerHTML = bh;
        document.getElementById('info_filas').innerText = rows.length;
        
        var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
        tooltipTriggerList.map(function (tooltipTriggerEl) { return new bootstrap.Tooltip(tooltipTriggerEl) });
    }
    filter(term) {
        const lower = term.toLowerCase();
        this.render(this.data.filter(r => Object.values(r).some(v => String(v).toLowerCase().includes(lower))));
    }
    enableInlineEdit(cell) { 
        const originalVal = cell.innerText; const id=cell.dataset.id; const col=cell.dataset.col;
        cell.classList.add('p-0'); 
        cell.innerHTML=`<input type="text" class="form-control input-inline-edit border-0 shadow-none text-center h-100 py-3" value="${originalVal}">`;
        const input=cell.querySelector('input'); input.focus(); 
        
        const save=()=>{
            if(input.value!==originalVal){
                this.db.query(`UPDATE ${this.cfg.tableName} SET ${col}='${input.value}' WHERE ${this.cfg.primaryKey}='${id}'`)
                .then(r=>{ 
                    if(r.status!=='success') { 
                        cell.innerText=originalVal; 
                        Swal.fire('Error', 'No se pudo actualizar', 'error'); 
                    } else { 
                        cell.innerText=input.value; 
                        Swal.fire({
                            icon: 'success',
                            title: 'Modificado',
                            text: 'El dato ha sido actualizado',
                            timer: 1500,
                            showConfirmButton: false
                        });
                    }
                    cell.classList.remove('p-0');
                });
            } else { cell.innerText=originalVal; cell.classList.remove('p-0'); }
        };
        input.addEventListener('blur', save); 
        input.addEventListener('keydown', e=>{if(e.key==='Enter') input.blur();});
    }
    
    abrirModalCrear() { document.getElementById('formDinamico').reset(); new bootstrap.Modal(document.getElementById('modalCrear')).show(); }
    activarEdicionFila(btn) { const cell=btn.closest('tr').querySelector('[data-editable="true"]'); if(cell) this.enableInlineEdit(cell); }
    exportarExcel() { alert("Función de exportar pendiente"); } 
    
    guardarNuevo() {
        let cols=[], vals=[], err=false;
        document.querySelectorAll('#formDinamico input').forEach(i=>{
            if(i.required && !i.value) err=true;
            cols.push(i.id.replace('new_','')); vals.push(`'${i.value}'`);
        });
        if(err) return Swal.fire('Atención','Faltan campos','warning');
        
        this.db.query(`INSERT INTO ${this.cfg.tableName} (${cols.join(',')}) VALUES (${vals.join(',')})`).then(r=>{
            if(r.status==='success') { 
                bootstrap.Modal.getInstance(document.getElementById('modalCrear')).hide(); 
                this.refresh(); 
                
                Swal.fire({
                    icon: 'success',
                    title: 'Agregado',
                    text: 'El registro se creó correctamente',
                    timer: 1500,
                    showConfirmButton: false
                });

            } else Swal.fire('Error', r.error, 'error');
        });
    }
}

const CONFIG = <?php echo json_encode($configJS); ?>;
const DB_NAME = "<?php echo $config['db_name'] ?? ''; ?>";
document.addEventListener('DOMContentLoaded', () => { window.tsManager = new TableManager(CONFIG, DB_NAME); });

<?php echo construirScriptsAcciones($solicitudGlobales, $solicitudFila); ?>
</script>