   
        class SmartTable {
            constructor(tableId, dbInstance, config) {
                this.tableId = tableId; 
                this.db = dbInstance;
                this.config = config;
                this.rawData = []; this.currentData = []; this.columns = [];
                this.currentPage = 1; this.rowsPerPage = config.rowsPerPage || 10;
                this.sortCol = null; this.sortAsc = true;
                
                // Referencia global segura
                this.globalRef = 'st_' + tableId.replace(/[^a-zA-Z0-9_]/g, '_');
                window[this.globalRef] = this;

                if(config.searchId) $(`#${config.searchId}`).on('keyup', (e) => this._filter(e.target.value));
            }

            async refresh() {
                try {
                    const res = await this.db.select(this.config.sql);
                    if(res.status === 'error') throw new Error(res.message);
                    
                    this.columns = res.columns;
                    this.rawData = res.data || []; // Evitar error si data es null
                    this.currentData = [...this.rawData];
                    this.currentPage = 1;
                    this._render();
                } catch (e) {
                    $(`#${this.tableId} tbody`).html(`<tr><td colspan="100" class="text-danger p-4 text-center">Error: ${e.message || 'Conexión'}</td></tr>`);
                }
            }

            _render() {
                const $thead = $(`#${this.tableId} thead`);
                const $tbody = $(`#${this.tableId} tbody`);
                
                // Header
                let head = '<tr>';
                this.columns.forEach(col => {
                    let icon = this.sortCol === col ? (this.sortAsc ? ' ↑' : ' ↓') : '';
                    head += `<th onclick="${this.globalRef}._sort('${col}')">${col}${icon}</th>`;
                });
                if (this.config.actions) head += '<th class="text-center">ACCIONES</th>';
                head += '</tr>';
                $thead.html(head);

                // Body & Paginación
                const start = (this.currentPage - 1) * this.rowsPerPage;
                const pageData = this.currentData.slice(start, start + this.rowsPerPage);
                
                let body = '';
                if (pageData.length === 0) body = `<tr><td colspan="100" class="text-center py-5 text-muted">Sin datos</td></tr>`;
                else {
                    pageData.forEach(row => {
                        const pkVal = row[this.config.primaryKey];
                        body += '<tr>';
                        this.columns.forEach(col => {
                            let val = row[col] !== null ? row[col] : '';
                            if (this.config.editableCols.includes(col)) {
                                let safe = String(val).replace(/'/g, "&#39;");
                                body += `<td><input type="text" class="editable-input" value="${safe}" onchange="${this.globalRef}._update('${pkVal}', '${col}', this.value)"></td>`;
                            } else body += `<td>${val}</td>`;
                        });
                        if (this.config.actions) {
                            body += '<td class="text-center">';
                            this.config.actions.forEach(act => {
                                let onclick = act.onclick.replace('{id}', pkVal);
                                body += `<button class="btn btn-sm btn-light text-${act.color||'primary'} mx-1 border" onclick="${onclick}"><i class="${act.icon}"></i></button>`;
                            });
                            body += '</td>';
                        }
                        body += '</tr>';
                    });
                }
                $tbody.html(body);
                if(this.config.paginationId) this._renderPag();
            }

            _renderPag() {
                const total = Math.ceil(this.currentData.length / this.rowsPerPage);
                const $box = $(`#${this.config.paginationId} #botones_paginacion`);
                $(`#${this.config.paginationId} #info_filas`).text(`${this.currentData.length} registros | Pág ${this.currentPage}/${total||1}`);
                
                let html = `<button class="page-btn" onclick="${this.globalRef}._setPage(${this.currentPage-1})" ${this.currentPage===1?'disabled':''}>&lt;</button>`;
                for(let i=1; i<=total; i++) {
                    if(i===1 || i===total || (i>=this.currentPage-1 && i<=this.currentPage+1))
                        html += `<button class="page-btn ${i===this.currentPage?'active':''}" onclick="${this.globalRef}._setPage(${i})">${i}</button>`;
                    else if(html.slice(-5)!=='...</span>') html += `<span class="px-1 small">...</span>`;
                }
                html += `<button class="page-btn" onclick="${this.globalRef}._setPage(${this.currentPage+1})" ${this.currentPage>=total?'disabled':''}>&gt;</button>`;
                $box.html(html);
            }

            _setPage(n) { 
                const total = Math.ceil(this.currentData.length / this.rowsPerPage);
                if(n>0 && n<=total) { this.currentPage = n; this._render(); } 
            }
            _sort(col) {
                if(this.sortCol===col) this.sortAsc = !this.sortAsc; else { this.sortCol=col; this.sortAsc=true; }
                this.currentData.sort((a,b) => {
                    let vA=(a[col]||'').toString().toLowerCase(), vB=(b[col]||'').toString().toLowerCase();
                    return vA<vB ? (this.sortAsc?-1:1) : vA>vB ? (this.sortAsc?1:-1) : 0;
                });
                this.currentPage=1; this._render();
            }
            _filter(t) {
                t=t.toLowerCase();
                this.currentData = this.rawData.filter(r => Object.values(r).some(v => String(v).toLowerCase().includes(t)));
                this.currentPage=1; this._render();
            }
            async _update(id, col, val) {
                await this.db.query(`UPDATE ${this.config.tableName} SET ${col}='${val}' WHERE ${this.config.primaryKey}='${id}'`);
                const r = this.rawData.find(row => row[this.config.primaryKey] == id); if(r) r[col] = val;
            }
        }
   