<?php
// =================================================================
// 1. CONFIGURACIÓN DEL CATÁLOGO (AGREGA AQUÍ TUS BOTONES)
// =================================================================
// Modificando este arreglo, los botones aparecen automáticamente.

$catalog = [
    'Estructura' => [
        [
            'type'  => 'row',
            'label' => 'Fila (Row)',
            'icon'  => 'bi-layout-three-columns',
            'desc'  => 'Contenedor horizontal'
        ],
        [
            'type'  => 'col',
            'label' => 'Columna',
            'icon'  => 'bi-layout-column',
            'desc'  => 'Espacio vertical dentro de fila'
        ]
    ],
    'Texto y Contenido' => [
        [
            'type'  => 'h1',
            'label' => 'Título H1',
            'icon'  => 'bi-type-h1',
            'desc'  => 'Encabezado grande'
        ],
        [
            'type'  => 'p',
            'label' => 'Párrafo',
            'icon'  => 'bi-paragraph',
            'desc'  => 'Bloque de texto'
        ],
        [
            'type'  => 'button',
            'label' => 'Botón',
            'icon'  => 'bi-hand-index-thumb',
            'desc'  => 'Botón de acción'
        ]
    ],
    'Componentes UI' => [
        [
            'type'  => 'card',
            'label' => 'Tarjeta (Card)',
            'icon'  => 'bi-card-heading',
            'desc'  => 'Contenedor con borde'
        ],
        [
            'type'  => 'alert',
            'label' => 'Alerta',
            'icon'  => 'bi-exclamation-triangle',
            'desc'  => 'Mensaje de aviso'
        ],
        [
            'type'  => 'input',
            'label' => 'Input Texto',
            'icon'  => 'bi-input-cursor-text',
            'desc'  => 'Campo de formulario'
        ],
        [
            'type'  => 'badge',
            'label' => 'Etiqueta',
            'icon'  => 'bi-tag-fill',
            'desc'  => 'Pequeño indicador'
        ]
    ]
];
?>

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>App Builder PHP</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css">

    <style>
        body { background-color: #f4f6f9; height: 100vh; overflow: hidden; }
        
        /* Área de Trabajo */
        #editor-area {
            height: calc(100vh - 60px);
            overflow-y: auto;
            background-color: #ffffff;
            background-image: radial-gradient(#dee2e6 1px, transparent 1px);
            background-size: 20px 20px;
            padding: 40px;
            box-shadow: inset 0 0 20px rgba(0,0,0,0.05);
        }

        /* Componente Editable */
        .editable-component {
            position: relative;
            border: 1px dashed transparent;
            min-height: 40px;
            cursor: pointer;
            transition: all 0.2s;
        }
        .editable-component:hover { border: 1px dashed #0d6efd; }
        
        /* Selección Activa */
        .editable-component.active-selection {
            outline: 2px solid #0d6efd;
            background-color: rgba(13, 110, 253, 0.05);
            z-index: 10;
        }

        /* Etiquetas flotantes */
        .comp-label {
            display: none; position: absolute; top: -18px; left: 0;
            background: #0d6efd; color: white; font-size: 10px; padding: 2px 5px;
            border-radius: 3px 3px 0 0; z-index: 15;
            font-weight: bold;
        }
        .active-selection > .comp-label { display: block; }

        /* Botón Eliminar flotante */
        .delete-btn {
            display: none; position: absolute; top: -15px; right: 0;
            z-index: 20; border-radius: 50%; box-shadow: 0 2px 5px rgba(0,0,0,0.2);
        }
        .active-selection > .delete-btn { display: block; }

        /* Estilo Botones Menú */
        .tool-btn { 
            text-align: left; 
            transition: transform 0.1s; 
            border: 1px solid #e9ecef;
            background: white;
        }
        .tool-btn:active { transform: scale(0.98); }
        .tool-btn:hover { background-color: #f8f9fa; border-color: #0d6efd; color: #0d6efd; }
        .tool-btn i { font-size: 1.1rem; }

        /* Placeholder vacío */
        .empty-placeholder {
            border: 2px dotted #dee2e6; color: #adb5bd; padding: 20px; 
            text-align: center; border-radius: 8px; font-size: 0.85rem;
            background: #fdfdfd;
        }
    </style>
</head>
<body>

<nav class="navbar navbar-dark bg-dark px-3" style="height: 60px;">
    <span class="navbar-brand mb-0 h1"><i class="bi bi-window-stack"></i> Editor PHP</span>
    <div>
        <button class="btn btn-outline-light btn-sm me-2" onclick="exportJSON()"><i class="bi bi-code-slash"></i> JSON</button>
        <button class="btn btn-outline-danger btn-sm" onclick="resetWorkspace()"><i class="bi bi-trash"></i> Reset</button>
    </div>
</nav>

<div class="container-fluid h-100">
    <div class="row h-100">
        
        <div class="col-md-2 p-0 border-end bg-white d-flex flex-column" style="height: calc(100vh - 60px);">
            <div class="p-3 border-bottom bg-light">
                <h6 class="m-0 fw-bold text-dark"><i class="bi bi-tools"></i> Herramientas</h6>
            </div>
            
            <div class="flex-grow-1 overflow-auto p-3">
                <?php if (isset($catalog) && is_array($catalog)): ?>
                    <?php foreach ($catalog as $category => $items): ?>
                        
                        <h6 class="text-secondary text-uppercase small fw-bold mb-2 mt-2" style="font-size: 0.75rem;">
                            <?= $category ?>
                        </h6>
                        
                        <div class="d-grid gap-2 mb-4">
                            <?php foreach ($items as $item): ?>
                                <button class="btn btn-sm tool-btn shadow-sm py-2" 
                                        onclick="addComponent('<?= $item['type'] ?>')">
                                    <div class="d-flex align-items-center">
                                        <i class="bi <?= $item['icon'] ?> me-2"></i> 
                                        <span><?= $item['label'] ?></span>
                                    </div>
                                </button>
                            <?php endforeach; ?>
                        </div>

                    <?php endforeach; ?>
                <?php else: ?>
                    <div class="alert alert-danger">Error: No se pudo cargar el catálogo PHP.</div>
                <?php endif; ?>
            </div>
        </div>

        <div class="col-md-10 p-0">
            <div id="editor-area">
                <div id="workspace" class="container"></div>
            </div>
        </div>

    </div>
</div>

<div class="offcanvas offcanvas-end shadow" data-bs-scroll="true" data-bs-backdrop="false" tabindex="-1" id="propPanel">
    <div class="offcanvas-header bg-primary text-white">
        <h5 class="offcanvas-title"><i class="bi bi-sliders"></i> Propiedades</h5>
        <button type="button" class="btn-close btn-close-white" data-bs-dismiss="offcanvas"></button>
    </div>
    <div class="offcanvas-body bg-light">
        <div class="mb-3">
            <label class="small fw-bold text-muted">TIPO DE COMPONENTE</label>
            <input type="text" id="prop-type" class="form-control" disabled readonly>
        </div>
        <hr>
        
        <div class="mb-3">
            <label class="small fw-bold">Contenido / Texto</label>
            <textarea id="prop-text" class="form-control" rows="3" oninput="updateProp('text', this.value)"></textarea>
        </div>

        <div class="mb-3">
            <label class="small fw-bold">Clases CSS (Bootstrap)</label>
            <input type="text" id="prop-class" class="form-control" placeholder="Ej: text-center mt-3 shadow" oninput="updateProp('className', this.value)">
        </div>

        <div id="col-settings" class="card p-3 mb-3 border-warning" style="display:none;">
            <label class="d-flex justify-content-between small fw-bold mb-2">
                <span>Ancho Columna (1-12)</span>
                <span class="badge bg-warning text-dark" id="col-display">12</span>
            </label>
            <input type="range" class="form-range" min="1" max="12" id="prop-col-size" oninput="updateProp('colSize', this.value)">
        </div>

        <div id="variant-settings" class="mb-3" style="display:none;">
            <label class="small fw-bold">Color / Variante</label>
            <select id="prop-variant" class="form-select" onchange="updateProp('variant', this.value)">
                <option value="primary">Primary (Azul)</option>
                <option value="secondary">Secondary (Gris)</option>
                <option value="success">Success (Verde)</option>
                <option value="danger">Danger (Rojo)</option>
                <option value="warning">Warning (Amarillo)</option>
                <option value="info">Info (Cyan)</option>
                <option value="light">Light (Claro)</option>
                <option value="dark">Dark (Oscuro)</option>
            </select>
        </div>

        <button class="btn btn-outline-danger w-100 mt-5" onclick="deleteCurrent()">
            <i class="bi bi-trash"></i> Eliminar Componente
        </button>
    </div>
</div>

<div class="modal fade" id="jsonModal" tabindex="-1">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Código JSON</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body p-0">
                <textarea id="json-output" class="form-control bg-dark text-white font-monospace border-0" style="height: 500px;"></textarea>
            </div>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
    // Estado Inicial con una fila y columna por defecto
    let layout = [
        { id: 'root', type: 'row', className: 'mb-4', children: [
            { id: 'c1', type: 'col', colSize: '12', children: [
                { id: 'w1', type: 'h1', text: '¡Bienvenido!', className: 'text-center text-primary' }
            ]}
        ]}
    ];
    
    let selectedId = null;
    let offcanvas = null;

    document.addEventListener('DOMContentLoaded', () => {
        offcanvas = new bootstrap.Offcanvas(document.getElementById('propPanel'));
        render();
    });

    // --- MOTOR DE RENDERIZADO ---
    function render() {
        const ws = document.getElementById('workspace');
        ws.innerHTML = '';
        layout.forEach(node => ws.appendChild(createEl(node)));
    }

    function createEl(node) {
        // Wrapper Editable
        let el = document.createElement('div');
        el.dataset.id = node.id;
        el.className = `editable-component ${node.id === selectedId ? 'active-selection' : ''}`;
        el.onclick = (e) => { e.stopPropagation(); select(node.id); };

        // UI Auxiliar (Etiqueta y Botón X)
        el.innerHTML = `
            <div class="comp-label">${node.type.toUpperCase()}</div>
            <button class="btn btn-danger btn-sm delete-btn" onclick="event.stopPropagation(); del('${node.id}')"><i class="bi bi-x-lg"></i></button>
        `;

        // Generación del HTML según tipo
        let content = null;
        switch(node.type) {
            case 'row':
                el.classList.add('row');
                if(node.className) el.classList.add(...node.className.split(' '));
                el.style.border = "1px dashed #ced4da";
                el.style.padding = "15px";
                break;
            case 'col':
                el.classList.add(`col-md-${node.colSize || 12}`);
                if(node.className) el.classList.add(...node.className.split(' '));
                if(!node.children?.length) el.innerHTML += `<div class="empty-placeholder">Columna Vacía</div>`;
                break;
            case 'button':
                content = document.createElement('button');
                content.className = `btn btn-${node.variant||'primary'} ${node.className||''}`;
                content.textContent = node.text || 'Botón';
                el.appendChild(content);
                el.classList.add('d-inline-block', 'me-2', 'mb-2');
                break;
            case 'h1':
                content = document.createElement('h1');
                content.textContent = node.text || 'Título';
                content.className = node.className || '';
                el.appendChild(content);
                break;
            case 'p':
                content = document.createElement('p');
                content.textContent = node.text || 'Texto...';
                content.className = node.className || '';
                el.appendChild(content);
                break;
            case 'card':
                content = document.createElement('div');
                content.className = `card ${node.className||''}`;
                content.innerHTML = `<div class="card-body"><h5 class="card-title">Card</h5><p class="card-text">${node.text||'Contenido de la tarjeta.'}</p></div>`;
                el.appendChild(content);
                break;
            case 'alert':
                content = document.createElement('div');
                content.className = `alert alert-${node.variant||'info'} ${node.className||''}`;
                content.textContent = node.text || 'Mensaje de alerta';
                el.appendChild(content);
                break;
            case 'input':
                content = document.createElement('input');
                content.className = `form-control ${node.className||''}`;
                content.placeholder = node.text || 'Escribe aquí...';
                content.disabled = true;
                el.appendChild(content);
                break;
            case 'badge':
                content = document.createElement('span');
                content.className = `badge bg-${node.variant||'primary'} ${node.className||''}`;
                content.textContent = node.text || 'Etiqueta';
                el.appendChild(content);
                el.classList.add('d-inline-block', 'me-2');
                break;
        }

        // Renderizado Recursivo de Hijos
        if (node.children) node.children.forEach(child => el.appendChild(createEl(child)));
        return el;
    }

    // --- LÓGICA DE GESTIÓN ---
    function find(id, list=layout) {
        for(let n of list) {
            if(n.id === id) return n;
            if(n.children) { let f = find(id, n.children); if(f) return f; }
        }
        return null;
    }

    function addComponent(type) {
        let node = { id: `n-${Date.now()}`, type, text: '', children: [] };
        
        // Defaults
        if(type === 'h1') node.text = "Nuevo Título";
        if(type === 'button') node.text = "Click";
        if(type === 'badge') node.text = "New";
        if(type === 'card') node.text = "Contenido de la tarjeta";

        if(!selectedId) {
            if(type !== 'row') return alert("En el área principal solo puedes agregar 'Filas' (Rows).");
            layout.push(node);
        } else {
            let p = find(selectedId);
            // Reglas de Anidación Bootstrap
            if(p.type === 'row' && type !== 'col') return alert("Dentro de una Fila solo puedes poner Columnas.");
            if(p.type !== 'row' && type === 'col') return alert("Una Columna solo puede ir dentro de una Fila.");
            if(['button','h1','p','card','alert','input','badge'].includes(p.type)) return alert("Este elemento no puede contener otros elementos. Selecciona una Columna primero.");
            
            if(!p.children) p.children = [];
            p.children.push(node);
        }
        render();
    }

    function select(id) {
        selectedId = id;
        render();
        let n = find(id);
        
        // Cargar datos en el panel
        document.getElementById('prop-type').value = n.type.toUpperCase();
        document.getElementById('prop-text').value = n.text || '';
        document.getElementById('prop-class').value = n.className || '';
        
        // Mostrar/Ocultar controles según tipo
        document.getElementById('col-settings').style.display = (n.type === 'col') ? 'block' : 'none';
        if(n.type === 'col') {
            document.getElementById('prop-col-size').value = n.colSize || 12;
            document.getElementById('col-display').innerText = n.colSize || 12;
        }

        let hasVariant = ['button','alert','badge'].includes(n.type);
        document.getElementById('variant-settings').style.display = hasVariant ? 'block' : 'none';
        if(hasVariant) document.getElementById('prop-variant').value = n.variant || 'primary';

        offcanvas.show();
    }

    function updateProp(key, val) {
        if(!selectedId) return;
        let n = find(selectedId);
        n[key] = val;
        if(key === 'colSize') document.getElementById('col-display').innerText = val;
        render();
    }

    function del(id) {
        if(!confirm('¿Estás seguro de eliminar este elemento?')) return;
        const remove = (list) => {
            let idx = list.findIndex(x => x.id === id);
            if(idx > -1) { list.splice(idx, 1); return true; }
            for(let x of list) if(x.children && remove(x.children)) return true;
        };
        remove(layout);
        if(selectedId === id) { selectedId = null; offcanvas.hide(); }
        render();
    }
    
    function deleteCurrent() { if(selectedId) del(selectedId); }

    function exportJSON() {
        document.getElementById('json-output').value = JSON.stringify(layout, null, 2);
        new bootstrap.Modal(document.getElementById('jsonModal')).show();
    }
    
    function resetWorkspace() {
        if(confirm('¿Borrar todo el trabajo?')) { layout = []; selectedId = null; offcanvas.hide(); render(); }
    }
</script>

</body>
</html>