<?php
session_start();
$host = "localhost"; $user = "root"; $pass = "33comRxXMysql"; 
$conn = new mysqli($host, $user, $pass); $conn->set_charset("utf8mb4");

// --- API AJAX ---
if (isset($_GET['get_tables'])) {
    $db = $conn->real_escape_string($_GET['get_tables']);
    $res = $conn->query("SHOW TABLES FROM `$db`");
    $out = []; if ($res) while ($r = $res->fetch_array()) $out[] = $r[0];
    echo json_encode($out); exit;
}

if (isset($_GET['get_data'])) {
    $db = $conn->real_escape_string($_GET['db']);
    $table = $conn->real_escape_string($_GET['table']);
    $conn->select_db($db);
    
    // Obtener PK
    $cols = []; $pk = null;
    $resC = $conn->query("SHOW COLUMNS FROM `$table`");
    while ($r = $resC->fetch_assoc()) {
        $cols[] = $r;
        if ($r['Key'] === 'PRI') $pk = $r['Field'];
    }

    $resD = $conn->query("SELECT * FROM `$table` LIMIT 50");
    $rows = []; if ($resD) while ($r = $resD->fetch_assoc()) $rows[] = $r;

    echo json_encode(["pk" => $pk, "structure" => $cols, "rows" => $rows]); exit;
}

if (isset($_POST['save_json'])) {
    $db = $conn->real_escape_string($_POST['db']);
    $table = $conn->real_escape_string($_POST['table']);
    $pkName = $conn->real_escape_string($_POST['pk_name']);
    $pkVal = $conn->real_escape_string($_POST['pk_val']);
    $col = $conn->real_escape_string($_POST['col']);
    $json = $_POST['json']; // JSON String crudo

    $conn->select_db($db);
    $safeJson = $conn->real_escape_string($json);
    
    $sql = "UPDATE `$table` SET `$col` = '$safeJson' WHERE `$pkName` = '$pkVal'";
    if($conn->query($sql)){
        echo json_encode(["ok"=>true]);
    } else {
        echo json_encode(["ok"=>false, "error"=>$conn->error]);
    }
    exit;
}
?>
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="utf-8">
    <title>Generador de Formularios JSON</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.15.0/Sortable.min.js"></script>

    <style>
        body { background: #eef2f6; font-family: 'Segoe UI', sans-serif; }
        
        /* Layout */
        #mainTable tbody tr { cursor: pointer; transition: 0.1s; }
        #mainTable tbody tr:hover { background-color: #e0e7ff; }
        .cell-json { background: #dbeafe; color: #1e40af; padding: 2px 6px; border-radius: 4px; font-size: 0.8em; font-weight: bold; }
        
        /* Offcanvas más ancho para el constructor */
        .offcanvas-end { width: 70% !important; min-width: 800px; }

        /* BUILDER STYLES */
        .builder-container { background: #fff; border: 1px solid #dee2e6; border-radius: 6px; min-height: 200px; padding: 10px; background-color: #f8f9fa; }
        
        /* Tarjeta de Elemento de Formulario */
        .form-element-card {
            background: white;
            border: 1px solid #e2e8f0;
            border-left: 4px solid #3b82f6; /* Color acento */
            border-radius: 6px;
            margin-bottom: 10px;
            padding: 10px;
            transition: all 0.2s;
            position: relative;
        }
        .form-element-card:hover { box-shadow: 0 4px 6px rgba(0,0,0,0.05); transform: translateX(2px); }
        .form-element-card.header-type { border-left-color: #10b981; background: #f0fdf4; } /* Estilo diferente para títulos */
        
        .handle { cursor: grab; color: #cbd5e1; }
        .handle:hover { color: #64748b; }

        /* Preview Area */
        .preview-box { border: 2px dashed #cbd5e1; padding: 20px; border-radius: 8px; background: white; margin-top: 20px; }
        .preview-label { text-transform: uppercase; font-size: 0.75rem; color: #94a3b8; font-weight: bold; margin-bottom: 10px; }
    </style>
</head>
<body class="p-3">

<div class="container-fluid">
    <div class="card p-2 mb-3 border-0 shadow-sm d-flex flex-row gap-2 align-items-center">
        <div class="fw-bold px-2 text-primary"><i class="bi bi-ui-checks"></i> Form Builder DB</div>
        <select id="dbSelect" class="form-select w-auto form-select-sm"><option value="">Base de Datos...</option>
            <?php $r=$conn->query("SHOW DATABASES"); while($d=$r->fetch_row()) if(!in_array($d[0],['information_schema','mysql','performance_schema'])) echo "<option>{$d[0]}</option>"; ?>
        </select>
        <select id="tableSelect" class="form-select w-auto form-select-sm" disabled><option>Tabla...</option></select>
        <span class="ms-auto text-muted small">Haz clic en una celda JSON para abrir el Constructor.</span>
    </div>

    <div class="bg-white rounded shadow-sm overflow-hidden">
        <table id="mainTable" class="table table-hover mb-0">
            <thead class="table-light"></thead>
            <tbody></tbody>
        </table>
        <div id="loading" class="text-center p-5 text-muted">Selecciona una tabla.</div>
    </div>
</div>

<div class="offcanvas offcanvas-end" tabindex="-1" id="builderCanvas">
    <div class="offcanvas-header bg-primary text-white">
        <div>
            <h5 class="offcanvas-title"><i class="bi bi-pencil-square"></i> Constructor de Formularios</h5>
            <small class="text-white-50" id="editorSubtitle">...</small>
        </div>
        <button type="button" class="btn-close btn-close-white" data-bs-dismiss="offcanvas"></button>
    </div>
    
    <div class="offcanvas-body bg-light">
        
        <div class="row h-100">
            <div class="col-md-7 d-flex flex-column h-100 overflow-auto">
                
                <div class="mb-3 d-flex gap-2 flex-wrap">
                    <button class="btn btn-sm btn-outline-primary" onclick="addFormElement('text')"><i class="bi bi-input-cursor"></i> Texto</button>
                    <button class="btn btn-sm btn-outline-primary" onclick="addFormElement('number')"><i class="bi bi-123"></i> Num</button>
                    <button class="btn btn-sm btn-outline-primary" onclick="addFormElement('select')"><i class="bi bi-list-ul"></i> Select</button>
                    <button class="btn btn-sm btn-outline-primary" onclick="addFormElement('date')"><i class="bi bi-calendar"></i> Fecha</button>
                    <button class="btn btn-sm btn-outline-primary" onclick="addFormElement('textarea')"><i class="bi bi-textarea-t"></i> Area</button>
                    <button class="btn btn-sm btn-outline-success" onclick="addFormElement('header')"><i class="bi bi-type-h1"></i> Título</button>
                </div>

                <div id="elementsContainer" class="builder-container flex-grow-1">
                    </div>
            </div>

            <div class="col-md-5 d-flex flex-column h-100 overflow-auto">
                <div class="preview-label"><i class="bi bi-eye"></i> Vista Previa del Formulario</div>
                <div id="visualPreview" class="preview-box shadow-sm">
                    <p class="text-muted text-center my-5">Agrega elementos para ver el formulario.</p>
                </div>
                
                <div class="mt-3">
                    <div class="preview-label">JSON Resultante</div>
                    <textarea id="jsonOutput" class="form-control font-monospace small bg-dark text-warning border-0" rows="6" readonly></textarea>
                </div>
            </div>
        </div>

    </div>
    
    <div class="offcanvas-footer p-3 bg-white border-top">
        <button id="btnSave" class="btn btn-success w-100 fw-bold py-2">
            <i class="bi bi-save"></i> GUARDAR ESTRUCTURA DEL FORMULARIO
        </button>
    </div>
</div>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>

<script>
// --- ESTADO ---
let currentDB="", currentTable="", pkName="";
let activeCell = { pkVal: null, col: null };
let formSchema = []; // Aquí vive el Array del formulario
const canvas = new bootstrap.Offcanvas(document.getElementById('builderCanvas'));

// --- INICIO ---
$('#dbSelect').change(function(){
    currentDB = $(this).val();
    $('#tableSelect').html('<option>...</option>').prop('disabled', true);
    $.get('?get_tables='+currentDB, function(r){
        let d=JSON.parse(r), h='<option value="">Tabla...</option>';
        d.forEach(t => h+=`<option>${t}</option>`);
        $('#tableSelect').html(h).prop('disabled', false);
    });
});

$('#tableSelect').change(function(){
    currentTable = $(this).val();
    loadTable();
});

function loadTable(){
    if(!currentTable) return;
    $('#loading').show(); $('#mainTable thead, #mainTable tbody').empty();
    $.get(`?get_data&db=${currentDB}&table=${currentTable}`, function(r){
        let d = JSON.parse(r);
        pkName = d.pk;
        
        let th = "<tr>"; d.structure.forEach(c => th += `<th>${c.Field}</th>`); th += "</tr>";
        $('#mainTable thead').html(th);

        let tb = "";
        d.rows.forEach(row => {
            tb += `<tr>`;
            d.structure.forEach(c => {
                let val = row[c.Field];
                let isJson = detectJson(val, c.Type);
                let display = val === null ? 'NULL' : (val.length>30?val.substring(0,30)+'...':val);
                
                if(isJson){
                    display = `<span class="cell-json"><i class="bi bi-ui-radios"></i> FORM SCHEMA</span> <small class="text-muted ms-1">Clic para editar</small>`;
                    let safeVal = encodeURIComponent(val);
                    tb += `<td onclick="openBuilder('${row[pkName]}', '${c.Field}', '${safeVal}')">${display}</td>`;
                } else {
                    tb += `<td class="text-muted">${display}</td>`;
                }
            });
            tb += `</tr>`;
        });
        $('#mainTable tbody').html(tb);
        $('#loading').hide();
    });
}

function detectJson(val, type){
    if(type.includes('json')) return true;
    if(typeof val === 'string' && val.trim().startsWith('[') && val.trim().endsWith(']')) return true; // Detectar Arrays
    return false;
}

// --- CONSTRUCTOR (LOGICA CORE) ---

function openBuilder(pkVal, col, encodedJson){
    activeCell = { pkVal, col };
    let jsonStr = decodeURIComponent(encodedJson);
    
    // Parsear o Inicializar Array Vacío
    try { 
        formSchema = JSON.parse(jsonStr); 
        if(!Array.isArray(formSchema)) formSchema = []; // Forzar Array
    } catch(e) { 
        formSchema = []; 
    }

    $('#editorSubtitle').text(`Editando Formulario: ID ${pkVal} -> ${col}`);
    renderBuilder();
    canvas.show();
}

// Renderiza la lista de tarjetas (Izquierda)
function renderBuilder(){
    let container = $('#elementsContainer').empty();
    
    formSchema.forEach((item, index) => {
        let isHeader = item.type === 'header';
        let cardClass = isHeader ? 'header-type' : '';
        
        // Inputs condicionales según el tipo
        let extraInputs = '';
        
        if(item.type === 'select'){
            extraInputs = `
            <div class="col-12 mt-2">
                <input class="form-control form-control-sm" placeholder="Opciones (sep. por coma): A,B,C" value="${item.options || ''}" oninput="updateItem(${index}, 'options', this.value)">
            </div>`;
        }

        let commonInputs = '';
        if(!isHeader){
            commonInputs = `
            <div class="col-6">
                <input class="form-control form-control-sm" placeholder="Name (variable)" value="${item.name || ''}" oninput="updateItem(${index}, 'name', this.value)">
            </div>
            <div class="col-3">
                <select class="form-select form-select-sm" onchange="updateItem(${index}, 'col', this.value)">
                    <option value="12" ${item.col=='12'?'selected':''}>100%</option>
                    <option value="6" ${item.col=='6'?'selected':''}>50%</option>
                    <option value="4" ${item.col=='4'?'selected':''}>33%</option>
                </select>
            </div>
            <div class="col-3 d-flex align-items-center">
                <div class="form-check">
                    <input class="form-check-input" type="checkbox" ${item.required?'checked':''} onchange="updateItem(${index}, 'required', this.checked)">
                    <label class="form-check-label small">Req</label>
                </div>
            </div>`;
        }

        let html = `
        <div class="form-element-card ${cardClass}" data-index="${index}">
            <div class="d-flex justify-content-between align-items-start mb-2">
                <span class="badge bg-secondary text-uppercase" style="font-size:0.65rem">${item.type}</span>
                <div class="d-flex gap-2">
                    <i class="bi bi-arrows-move handle"></i>
                    <i class="bi bi-trash text-danger" style="cursor:pointer" onclick="removeItem(${index})"></i>
                </div>
            </div>
            <div class="row g-2">
                <div class="col-${isHeader?12:12}">
                    <input class="form-control form-control-sm fw-bold" placeholder="Etiqueta / Label visible" value="${item.label || ''}" oninput="updateItem(${index}, 'label', this.value)">
                </div>
                ${commonInputs}
                ${extraInputs}
            </div>
        </div>`;
        container.append(html);
    });

    updatePreview();
    
    // Activar Drag & Drop
    new Sortable(document.getElementById('elementsContainer'), {
        handle: '.handle',
        animation: 150,
        onEnd: function (evt) {
            // Reordenar array basado en el DOM
            let newSchema = [];
            $('#elementsContainer .form-element-card').each(function(){
                let oldIndex = $(this).data('index');
                newSchema.push(formSchema[oldIndex]);
            });
            formSchema = newSchema;
            renderBuilder(); // Re-renderizar para ajustar indices
        }
    });
}

// Agregar nuevo elemento al Array
function addFormElement(type){
    let newItem = { type: type, label: 'Nuevo Campo', col: '12' };
    
    if(type === 'header') newItem.label = "SECCIÓN NUEVA";
    else newItem.name = "campo_" + Math.floor(Math.random() * 1000);

    formSchema.push(newItem);
    renderBuilder();
    // Scroll al final
    let el = document.getElementById('elementsContainer');
    el.scrollTop = el.scrollHeight;
}

// Actualizar propiedad de un item
function updateItem(index, key, val){
    formSchema[index][key] = val;
    updatePreview(); // Actualizar preview en tiempo real sin re-renderizar todo
}

// Eliminar item
function removeItem(index){
    formSchema.splice(index, 1);
    renderBuilder();
}

// --- PREVIEW VISUAL (Derecha) ---
function updatePreview(){
    let html = '<div class="row g-3">';
    
    formSchema.forEach(item => {
        let colClass = item.col ? `col-md-${item.col}` : 'col-12';
        let req = item.required ? '<span class="text-danger">*</span>' : '';
        let input = '';

        if(item.type === 'header'){
            input = `<h5 class="border-bottom pb-2 mt-3">${item.label}</h5>`;
        } else if(item.type === 'select'){
            let opts = (item.options || "").split(',').map(o => `<option>${o.trim()}</option>`).join('');
            input = `
                <label class="form-label small fw-bold">${item.label} ${req}</label>
                <select class="form-select">${opts}</select>
            `;
        } else if(item.type === 'textarea'){
            input = `
                <label class="form-label small fw-bold">${item.label} ${req}</label>
                <textarea class="form-control" rows="2"></textarea>
            `;
        } else {
            // Text, Number, Date, etc.
            input = `
                <label class="form-label small fw-bold">${item.label} ${req}</label>
                <input type="${item.type}" class="form-control" placeholder="${item.name}">
            `;
        }

        html += `<div class="${colClass}">${input}</div>`;
    });
    
    html += '</div>';
    
    // Si está vacío
    if(formSchema.length === 0) html = '<p class="text-center text-muted my-5">Formulario vacío</p>';

    $('#visualPreview').html(html);
    $('#jsonOutput').val(JSON.stringify(formSchema, null, 2));
}

// --- GUARDAR ---
$('#btnSave').click(function(){
    let jsonStr = JSON.stringify(formSchema);
    
    $.post('', {
        save_json: 1,
        db: currentDB,
        table: currentTable,
        pk_name: pkName,
        pk_val: activeCell.pkVal,
        col: activeCell.col,
        json: jsonStr
    }, function(r){
        let resp = JSON.parse(r);
        if(resp.ok){
            canvas.hide();
            loadTable();
            // alert("Formulario guardado");
        } else {
            alert("Error: " + resp.error);
        }
    });
});
</script>
</body>
</html>