/**
 * SQLTools.js
 * Librería Cliente para conectar con el Backend PHP mediante AJAX.
 * Requiere: jQuery y Bootstrap 5 (para las alertas).
 */
class SQLTools {

    /**
     * @param {string} defaultDB - Nombre de la base de datos por defecto
     * @param {string} alertContainerId - (OPCIONAL) ID del div para alertas
     */
    constructor(defaultDB = "MS_Usuario", alertContainerId = null) {
        this.defaultDB = defaultDB;
        this.alertContainerId = alertContainerId;
        
        // RUTAS A TUS ARCHIVOS PHP (Ajusta si tus carpetas son diferentes)
        this.pathSelect = "../librerias/AJAX/Select.php";
        this.pathExecute = "../librerias/AJAX/Execute.php";
    }

    // =========================================================================
    // 1. SISTEMA DE NOTIFICACIONES
    // =========================================================================
    _notify(mensaje, tipo) {
        if (!this.alertContainerId) return;

        const $container = $("#" + this.alertContainerId);
        
        if ($container.length === 0) {
            console.warn("SQLTools: No existe el contenedor #" + this.alertContainerId);
            return;
        }

        const icon = tipo === 'success' ? '✅' : '⚠️';
        
        // Template de Alerta Bootstrap 5
        const alertHTML = `
            <div class="alert alert-${tipo} alert-dismissible fade show shadow-sm mb-0" role="alert">
                <strong>${icon} Sistema:</strong> ${mensaje}
                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close" 
                        onclick="$(this).parent().remove()"></button>
            </div>
        `;

        // .html() reemplaza la alerta anterior (Barra única)
        // Usa .append() si prefieres que se acumulen
        $container.html(alertHTML);

        // Auto-cierre solo para mensajes de éxito
        if (tipo === 'success') {
            setTimeout(() => {
                $container.find('.alert').fadeOut(500, function() { $(this).remove(); });
            }, 4000);
        }
    }

    // =========================================================================
    // 2. MÉTODO SELECT (LEER DATOS)
    // =========================================================================
    async select(sql, db = null) {
        const database = db || this.defaultDB;
        try {
            const response = await $.ajax({
                url: this.pathSelect,
                type: 'POST',
                dataType: 'json',
                data: { sql: sql, db: database }
            });
            
            if (response.status === 'error') {
                this._notify("Error SQL: " + response.message, 'danger');
                throw new Error(response.message);
            }
            return response; // Retorna {status, data, columns}
        } catch (error) {
            let msg = error.responseText || error.message || "Error de conexión";
            this._notify("Error: " + msg, 'danger');
            throw error;
        }
    }

    // =========================================================================
    // 3. MÉTODO QUERY (INSERT, UPDATE, DELETE)
    // =========================================================================
    async query(sql, db = null, silent = false) {
        const database = db || this.defaultDB;
        try {
            const response = await $.ajax({
                url: this.pathExecute,
                type: 'POST',
                dataType: 'json',
                data: { sql: sql, db: database }
            });

            if (response.status === 'success') {
                if (!silent) {
                    this._notify("Operación exitosa. Afectados: " + response.rows_affected, 'success');
                }
            } else {
                this._notify("Error SQL: " + response.message, 'danger');
                throw new Error(response.message);
            }
            return response; // Retorna {status, rows_affected, last_id}

        } catch (error) {
            let msg = error.responseText || error.message || "Error desconocido";
            this._notify("Fallo crítico: " + msg, 'danger');
            throw error;
        }
    }

    // =========================================================================
    // 4. UTILIDAD: LLENAR TABLA HTML AUTOMÁTICAMENTE
    // =========================================================================
    async llenarTabla(idTabla, sql) {
        const $tabla = $(`#${idTabla}`);
        
        // Loading state
        $tabla.html('<thead><tr><th>Cargando...</th></tr></thead><tbody><tr><td>Espere un momento...</td></tr></tbody>');

        try {
            const res = await this.select(sql);
            
            if (!res.data || res.data.length === 0) {
                $tabla.html('<tbody><tr><td class="text-center p-3 text-muted">No se encontraron registros</td></tr></tbody>');
                return;
            }

            // 1. Dibujar Encabezados (thead) dinámicamente
            let thead = '<thead class="table-light"><tr>';
            res.columns.forEach(col => {
                thead += `<th>${col.toUpperCase()}</th>`;
            });
            thead += '</tr></thead>';

            // 2. Dibujar Cuerpo (tbody)
            let tbody = '<tbody>';
            res.data.forEach(fila => {
                tbody += '<tr>';
                // Recorremos las columnas en orden para pintar las celdas
                res.columns.forEach(col => {
                    let valor = fila[col] !== null ? fila[col] : ''; // Evitar nulls
                    tbody += `<td>${valor}</td>`;
                });
                tbody += '</tr>';
            });
            tbody += '</tbody>';

            $tabla.html(thead + tbody);

        } catch (e) {
            $tabla.html(`<tbody><tr><td class="text-danger p-3">No se pudo cargar la tabla.</td></tr></tbody>`);
        }
    }

    // =========================================================================
    // 5. UTILIDAD: LLENAR SELECT (DROPDOWN)
    // =========================================================================
    /**
     * @param {string} idSelect - ID del <select> HTML
     * @param {string} sql - Consulta SQL
     * @param {string} campoValor - Columna para el value="" (ej: 'id')
     * @param {string} campoTexto - Columna para el texto visible (ej: 'nombre')
     */
    async llenarSelect(idSelect, sql, campoValor, campoTexto) {
        const $select = $(`#${idSelect}`);
        $select.html('<option>Cargando...</option>');

        try {
            const res = await this.select(sql);
            let opciones = '<option value="">-- Seleccione --</option>';
            
            res.data.forEach(item => {
                opciones += `<option value="${item[campoValor]}">${item[campoTexto]}</option>`;
            });
            
            $select.html(opciones);
        } catch (e) {
            $select.html('<option value="">Error de carga</option>');
            console.error("Error llenando select", e);
        }
    }
}