<?php
/* ==========================================================
   admin_secciones.php — Editor de Secciones (nuevo, independiente)
   Requiere: db.php (función pdo()), PHP 7.4+, carpeta /uploads/sections (775)
   Endpoints (JSON):
     POST action=list          {page}
     POST action=new_section   {page, h?, padding?, bg?, orden?}
     POST action=update_section{id, h?, padding?, bg?, orden?, enabled?}
     POST action=delete_section{id}
     POST action=new_item      {seccion_id, type, x?, y?, w?, h?, z?, content_json?}
     POST action=update_item   {id, x?, y?, w?, h?, z?, enabled?, content_json?}
     POST action=delete_item   {id}
     POST action=upload        (multipart/form-data) -> {url}
   ========================================================== */
@session_start();
ini_set('display_errors',1); error_reporting(E_ALL);

if (!file_exists(__DIR__.'/db.php')) { http_response_code(500); echo "Falta db.php"; exit; }
require __DIR__.'/db.php';
$pdo = pdo();
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

/* --- Helpers JSON / salida --- */
function json_input(){
  $raw = file_get_contents('php://input');
  if ($raw && stripos($_SERVER['CONTENT_TYPE'] ?? '', 'application/json')!==false) {
    $j = json_decode($raw, true);
    return is_array($j) ? $j : [];
  }
  return [];
}
function out($arr){ header('Content-Type: application/json; charset=utf-8'); echo json_encode($arr); exit; }
function ok($extra=[]){ out(['ok'=>true]+$extra); }
function bad($msg, $code=400){ http_response_code($code); out(['ok'=>false,'error'=>$msg]); }
function s($v){ return htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); }

/* --- API --- */
$action = $_GET['action'] ?? ($_POST['action'] ?? null);
if ($action) {
  if ($action==='upload') {
    if (empty($_FILES['file'])) bad('No file');
    $dir = __DIR__.'/uploads/sections';
    if (!is_dir($dir)) { @mkdir($dir, 0775, true); }
    $f = $_FILES['file'];
    if ($f['error']!==UPLOAD_ERR_OK) bad('Upload error '.$f['error']);
    $ext = strtolower(pathinfo($f['name'], PATHINFO_EXTENSION));
    if (!preg_match('/^(png|jpg|jpeg|webp|gif)$/',$ext)) bad('Extensión no permitida');
    $base = uniqid('sx_',true).'.'.$ext;
    $dest = $dir.'/'.$base;
    if (!move_uploaded_file($f['tmp_name'], $dest)) bad('No se pudo mover el archivo');
    $url = '/uploads/sections/'.$base;
    ok(['url'=>$url]);
  }

  $j = json_input();

  switch ($action) {
    case 'list': {
      $page = basename($j['page'] ?? 'index.php');
      $q1 = $pdo->prepare("SELECT * FROM secciones WHERE page=? ORDER BY orden ASC, id ASC");
      $q1->execute([$page]);
      $secciones = $q1->fetchAll(PDO::FETCH_ASSOC);

      $ids = array_column($secciones, 'id');
      $items = [];
      if ($ids) {
        $in = implode(',', array_fill(0, count($ids), '?'));
        $q2 = $pdo->prepare("SELECT * FROM seccion_items WHERE seccion_id IN ($in) ORDER BY z ASC, id ASC");
        $q2->execute($ids);
        while ($r = $q2->fetch(PDO::FETCH_ASSOC)) {
          $items[$r['seccion_id']][] = $r;
        }
      }
      ok(['secciones'=>$secciones,'items'=>$items]);
    }

    case 'new_section': {
      $page    = basename($j['page'] ?? 'index.php');
      $h       = (int)($j['h'] ?? 700);
      $padding = (int)($j['padding'] ?? 48);
      $bg      = $j['bg'] ?? '#ffffff';
      $orden   = (int)($j['orden'] ?? 999);
      $ins = $pdo->prepare("INSERT INTO secciones (page, orden, h, padding, bg, enabled) VALUES (?,?,?,?,?,1)");
      $ins->execute([$page,$orden,$h,$padding,$bg]);
      ok(['id'=>$pdo->lastInsertId()]);
    }

    case 'update_section': {
      $id = (int)($j['id'] ?? 0);
      if (!$id) bad('id?');
      $fields=[]; $args=[];
      foreach (['h','padding','bg','orden','enabled'] as $k){
        if (isset($j[$k])) { $fields[]="$k=?"; $args[]=$j[$k]; }
      }
      if (!$fields) ok();
      $args[]=$id;
      $sql="UPDATE secciones SET ".implode(',',$fields)." WHERE id=?";
      $st=$pdo->prepare($sql); $st->execute($args);
      ok();
    }

    case 'delete_section': {
      $id = (int)($j['id'] ?? 0);
      if (!$id) bad('id?');
      $pdo->prepare("DELETE FROM secciones WHERE id=?")->execute([$id]);
      ok();
    }

    case 'new_item': {
      $seccion_id = (int)($j['seccion_id'] ?? 0);
      $type       = $j['type'] ?? '';
      if (!$seccion_id || !$type) bad('seccion_id/type?');
      $x = (int)($j['x'] ?? 40);
      $y = (int)($j['y'] ?? 40);
      $w = isset($j['w']) ? (int)$j['w'] : 600;
      $h = isset($j['h']) ? (int)$j['h'] : null;
      $z = (int)($j['z'] ?? 1);
      $cj= isset($j['content_json']) ? json_encode($j['content_json'], JSON_UNESCAPED_UNICODE) : null;
      $ins = $pdo->prepare("INSERT INTO seccion_items (seccion_id, type, x, y, w, h, z, enabled, content_json) VALUES (?,?,?,?,?,?,?,?,?)");
      $ins->execute([$seccion_id, $type, $x, $y, $w, $h, $z, 1, $cj]);
      ok(['id'=>$pdo->lastInsertId()]);
    }

    case 'update_item': {
      $id = (int)($j['id'] ?? 0);
      if (!$id) bad('id?');
      $fields=[]; $args=[];
      foreach (['x','y','w','h','z','enabled'] as $k){
        if (isset($j[$k])) { $fields[]="$k=?"; $args[]=$j[$k]; }
      }
      if (isset($j['content_json'])) {
        $fields[]="content_json=?";
        $args[] = json_encode($j['content_json'], JSON_UNESCAPED_UNICODE);
      }
      if (!$fields) ok();
      $args[]=$id;
      $sql="UPDATE seccion_items SET ".implode(',',$fields)." WHERE id=?";
      $st=$pdo->prepare($sql); $st->execute($args);
      ok();
    }

    case 'delete_item': {
      $id = (int)($j['id'] ?? 0);
      if (!$id) bad('id?');
      $pdo->prepare("DELETE FROM seccion_items WHERE id=?")->execute([$id]);
      ok();
    }

    default: bad('Acción inválida', 404);
  }
}

/* --- UI (Editor) --- */
$page = basename($_GET['page'] ?? 'index.php');
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Admin Secciones — <?= s($page) ?></title>
<style>
  :root{ --ink:#0f1a24; --soft:#f3f6f8; --pri:#1769aa; --bd:#e4edf2; --mut:#6b7b88; }
  *{box-sizing:border-box}
  body{font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,'Helvetica Neue',Arial; margin:0; color:var(--ink); background:#fff;}
  header{position:sticky;top:0;z-index:10;background:#fff;border-bottom:1px solid var(--bd);padding:12px 16px;display:flex;gap:12px;align-items:center}
  header .right{margin-left:auto;display:flex;gap:8px;align-items:center}
  select,input,button{font:inherit}
  button{background:var(--pri);color:#fff;border:0;border-radius:8px;padding:8px 12px;cursor:pointer}
  button.secondary{background:#fff;color:var(--ink);border:1px solid var(--bd)}
  .wrap{display:grid;grid-template-columns:320px 1fr; min-height:calc(100vh - 52px);}
  .panel{border-right:1px solid var(--bd); padding:12px; overflow:auto}
  .preview{position:relative; overflow:auto; background:#fff}
  .canvas{position:relative; margin:0 auto; max-width:1100px; border-left:1px solid var(--bd); border-right:1px solid var(--bd); background:#fff}
  .sec{position:relative; outline:1px dashed #d0d9e2; box-sizing:border-box}
  .sec header{position:sticky; top:0; background:#fafcff; border-bottom:1px dashed #dfe7ef; padding:6px 8px; font-size:12px; color:var(--mut)}
  .item{position:absolute; outline:1px solid rgba(23,105,170,.25); background:rgba(23,105,170,.05)}
  .item .handle{position:absolute; right:-6px; bottom:-6px; width:12px; height:12px; background:var(--pri); border-radius:50%; cursor:nwse-resize}
  .row{display:flex; gap:8px; margin:8px 0; align-items:center}
  .row label{width:100px; font-size:13px; color:var(--mut)}
  .row input[type="text"], .row input[type="number"]{width:100%; padding:6px 8px; border:1px solid var(--bd); border-radius:8px}
  .list{border:1px solid var(--bd); border-radius:12px; padding:8px; background:#fbfdff}
  .list h4{margin:6px 4px 4px 4px; font-size:13px; color:var(--mut)}
  .list .seclink{display:block; padding:8px; border-radius:8px; text-decoration:none; color:var(--ink)}
  .list .seclink:hover{background:#eef6fc}
  .mut{color:var(--mut); font-size:12px}
  .small{font-size:12px}
</style>
</head>
<body>
<header>
  <div><strong>Admin Secciones</strong> <span class="mut">/ página:</span></div>
  <form id="formPage" class="row">
    <input type="text" id="inpPage" value="<?= s($page) ?>" />
    <button type="submit" class="secondary">Cambiar</button>
  </form>
  <div class="right">
    <button id="btnNewSection">➕ Nueva sección</button>
    <button id="btnReload" class="secondary">↻ Recargar</button>
  </div>
</header>

<div class="wrap">
  <aside class="panel">
    <div class="list" id="secList">
      <h4>Secciones</h4>
      <!-- se llena por JS -->
    </div>

    <div class="list" style="margin-top:12px">
      <h4>Agregar bloque</h4>
      <div class="row small"><label>Sección ID</label><input type="number" id="secIdForNew" placeholder="id" /></div>
      <div class="row">
        <button class="secondary" data-type="title">Título</button>
        <button class="secondary" data-type="paragraph">Párrafo</button>
        <button class="secondary" data-type="image">Imagen</button>
      </div>
      <div class="row">
        <button class="secondary" data-type="html">HTML</button>
        <button class="secondary" data-type="link">Link</button>
        <button class="secondary" data-type="video">Video</button>
      </div>
      <div class="mut small">Elegí una sección y agregá bloques. Luego arrastrá/resize en el preview.</div>
    </div>

    <div class="list" style="margin-top:12px">
      <h4>Editar bloque (contenido)</h4>
      <div class="row small"><label>Item ID</label><input type="number" id="editItemId" placeholder="id" /></div>
      <div class="row small"><label>Campo</label><input type="text" id="editKey" placeholder="text | url | alt | html | maxw ..." /></div>
      <div class="row small"><label>Valor</label><input type="text" id="editVal" placeholder="valor" /></div>
      <button id="btnApplyEdit" class="secondary">Aplicar</button>
      <div class="mut small">Guarda dentro de <code>content_json</code>.</div>
    </div>

    <div class="list" style="margin-top:12px">
      <h4>Subir imagen</h4>
      <input type="file" id="upFile" accept="image/*" />
      <div class="mut small">Copia la URL devuelta en el bloque (src).</div>
      <div id="upRes" class="small"></div>
    </div>
  </aside>

  <main class="preview">
    <div id="canvas" class="canvas"></div>
  </main>
</div>

<script>
const PAGE="<?= s($page) ?>";
const API=(a)=>fetch('admin_secciones.php?action='+a,{method:'POST',headers:{'Content-Type':'application/json'}});
let DATA={secciones:[], items:{}};

function reload(){
  API('list').then(r=>r.json()).then(j=>{
    if(!j.ok){ alert('Error list'); return; }
    DATA=j;
    renderList();
    renderPreview();
  }).catch(()=>alert('Error list'));
}
function renderList(){
  const el=document.getElementById('secList');
  el.innerHTML='<h4>Secciones</h4>';
  DATA.secciones.forEach(s=>{
    const a=document.createElement('a');
    a.href="#sx"+s.id;
    a.className='seclink';
    a.textContent=`#${s.id} • h=${s.h} bg=${s.bg} orden=${s.orden} ${s.enabled?'':'(OFF)'}`;
    a.addEventListener('click', e=>{
      e.preventDefault();
      document.getElementById('sec-'+s.id)?.scrollIntoView({behavior:'smooth',block:'start'});
      document.getElementById('secIdForNew').value=s.id;
    });
    el.appendChild(a);
  });
}
function el(tag, cls, html){ const x=document.createElement(tag); if(cls) x.className=cls; if(html!=null) x.innerHTML=html; return x; }

function renderPreview(){
  const c=document.getElementById('canvas'); c.innerHTML='';
  DATA.secciones.forEach(s=>{
    const sec = el('section','sec');
    sec.id='sec-'+s.id;
    sec.style.minHeight=(s.h||700)+'px';
    sec.style.padding=(s.padding||48)+'px';
    sec.style.background=s.bg||'#ffffff';
    sec.style.margin='0';
    const head=el('header','',`Sección #${s.id} — h=${s.h} • padding=${s.padding} • bg=${s.bg} • orden=${s.orden} ${s.enabled?'':'<b>(OFF)</b>'}`);
    sec.appendChild(head);

    const controls=el('div','row small',`
      <label>Alto</label><input type="number" value="${s.h}" style="width:90px" />
      <label>Padding</label><input type="number" value="${s.padding}" style="width:90px" />
      <label>BG</label><input type="text" value="${s.bg}" style="width:120px" />
      <label>Orden</label><input type="number" value="${s.orden}" style="width:80px" />
      <button class="secondary" data-act="save">Guardar</button>
      <button class="secondary" data-act="toggle">${s.enabled? 'Desactivar':'Activar'}</button>
      <button class="secondary" data-act="del">Eliminar</button>
    `);
    controls.querySelector('[data-act="save"]').onclick=()=>{
      const ins=controls.querySelectorAll('input');
      updateSection(s.id, {
        h:parseInt(ins[0].value||700),
        padding:parseInt(ins[1].value||48),
        bg:ins[2].value||'#ffffff',
        orden:parseInt(ins[3].value||0)
      });
    };
    controls.querySelector('[data-act="toggle"]').onclick=()=>{ updateSection(s.id,{ enabled: s.enabled?0:1 }); };
    controls.querySelector('[data-act="del"]').onclick=()=>{
      if(confirm('Eliminar sección y sus ítems?')) delSection(s.id);
    };
    sec.appendChild(controls);

    const children = DATA.items[s.id] || [];
    children.forEach(it=>{
      const box=el('div','item', renderItemInner(it));
      box.style.left=(it.x||0)+'px';
      box.style.top=(it.y||0)+'px';
      if(it.w) box.style.width=it.w+'px';
      if(it.h) box.style.height=it.h+'px';
      box.style.zIndex=it.z||1;
      box.dataset.id=it.id;

      dragify(box, (dx,dy,final)=>{
        it.x += dx; it.y += dy;
        box.style.left=it.x+'px'; box.style.top=it.y+'px';
        if(final) updateItem(it.id,{x:it.x,y:it.y});
      });
      const h=el('div','handle'); box.appendChild(h);
      resizify(box, (dw,dh,final)=>{
        it.w = Math.max(40,(it.w||100)+dw);
        it.h = Math.max(20,(it.h||40)+(dh||0));
        box.style.width=it.w+'px'; if(it.h) box.style.height=it.h+'px';
        if(final) updateItem(it.id,{w:it.w,h:it.h});
      });

      box.onclick=()=>{ document.getElementById('editItemId').value=it.id; };
      sec.appendChild(box);
    });

    c.appendChild(sec);
  });
}

function renderItemInner(it){
  let d={}; try{ d=JSON.parse(it.content_json||'{}')||{}; }catch(e){}
  if(it.type==='title') return `<div style="padding:8px;font-weight:800;font-size:22px">${escapeHtml(d.text||'Nuevo título')}</div>`;
  if(it.type==='paragraph') return `<div style="padding:8px;font-size:15px;line-height:1.6">${(d.text||'Escribe tu texto…').replace(/\n/g,'<br>')}</div>`;
  if(it.type==='image') return `<img src="${escapeAttr(d.src||'')}" alt="${escapeAttr(d.alt||'')}" style="display:block;width:100%;height:auto">`;
  if(it.type==='html') return `<div style="padding:8px">${d.html||'<em>Bloque HTML</em>'}</div>`;
  if(it.type==='link') return `<a href="${escapeAttr(d.url||'#')}" style="display:inline-block;padding:8px">${escapeHtml(d.text||d.url||'Link')}</a>`;
  if(it.type==='video') return `<video src="${escapeAttr(d.url||'')}" controls style="display:block;width:100%;height:auto"></video>`;
  return `<div>Tipo ${it.type}</div>`;
}
function escapeHtml(t){ return (t||'').replace(/[&<>"]/g, m=>({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;' }[m])); }
function escapeAttr(t){ return escapeHtml(t); }

/* drag / resize */
function dragify(el, cb){
  let sx=0, sy=0; el.style.cursor='move';
  el.addEventListener('mousedown', (e)=>{
    if(e.target.classList.contains('handle')) return;
    sx=e.clientX; sy=e.clientY;
    const move=(ev)=>{ const dx=ev.clientX-sx, dy=ev.clientY-sy; sx=ev.clientX; sy=ev.clientY; cb(dx,dy,false); };
    const up =()=>{ document.removeEventListener('mousemove',move); document.removeEventListener('mouseup',up); cb(0,0,true); };
    document.addEventListener('mousemove',move); document.addEventListener('mouseup',up);
  });
}
function resizify(el, cb){
  const handle=el.querySelector('.handle');
  handle.addEventListener('mousedown', (e)=>{
    e.stopPropagation();
    let sx=e.clientX, sy=e.clientY;
    const move=(ev)=>{ const dw=ev.clientX-sx, dh=ev.clientY-sy; sx=ev.clientX; sy=ev.clientY; cb(dw,dh,false); };
    const up =()=>{ document.removeEventListener('mousemove',move); document.removeEventListener('mouseup',up); cb(0,0,true); };
    document.addEventListener('mousemove',move); document.addEventListener('mouseup',up);
  });
}

/* API callers */
function updateSection(id, obj){
  fetch('admin_secciones.php?action=update_section',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({id,...obj})})
    .then(r=>r.json()).then(j=>{ if(j.ok) reload(); else alert('Error update_section'); });
}
function delSection(id){
  fetch('admin_secciones.php?action=delete_section',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({id})})
    .then(r=>r.json()).then(j=>{ if(j.ok) reload(); else alert('Error delete_section'); });
}
function newItem(seccion_id, type){
  const defaults={ title:{text:'Nuevo título'}, paragraph:{text:'Escribe tu texto…'}, image:{src:'',alt:'',maxw:600}, html:{html:'<em>Bloque HTML</em>'}, link:{url:'https://',text:'Abrir enlace'}, video:{url:''} };
  fetch('admin_secciones.php?action=new_item',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({ seccion_id, type, x:40, y:40, w:600, z:1, content_json:defaults[type]||{} })})
    .then(r=>r.json()).then(j=>{ if(j.ok) reload(); else alert('Error new_item'); });
}
function updateItem(id, obj){
  fetch('admin_secciones.php?action=update_item',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({id,...obj})})
    .then(r=>r.json()).then(j=>{ if(!j.ok) alert('Error update_item'); });
}

/* UI */
document.getElementById('btnNewSection').onclick=()=>{
  fetch('admin_secciones.php?action=new_section',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({ page:PAGE, h:700, padding:48, bg:'#ffffff', orden:999 })})
    .then(r=>r.json()).then(j=>{ if(j.ok) reload(); else alert('Error new_section'); });
};
document.getElementById('btnReload').onclick=()=>reload();
document.getElementById('formPage').onsubmit=(e)=>{ e.preventDefault(); location.search='?page='+encodeURIComponent(document.getElementById('inpPage').value||'index.php'); };
document.querySelectorAll('[data-type]').forEach(b=>{
  b.onclick=()=> {
    const secid=parseInt(document.getElementById('secIdForNew').value||0);
    if(!secid) return alert('Elegí una sección primero');
    newItem(secid, b.dataset.type);
  };
});
document.getElementById('btnApplyEdit').onclick=()=>{
  const id=parseInt(document.getElementById('editItemId').value||0);
  const k=document.getElementById('editKey').value.trim();
  const v=document.getElementById('editVal').value;
  if(!id||!k) return alert('Falta Item ID / Campo');
  const it = Object.values(DATA.items).flat().find(x=>x.id==id);
  let d={}; try{ d=it? JSON.parse(it.content_json||'{}')||{} : {}; }catch(e){}
  d[k]=v; updateItem(id,{content_json:d}); setTimeout(reload,200);
};
document.getElementById('upFile').onchange=(e)=>{
  const f=e.target.files[0]; if(!f) return;
  const fd=new FormData(); fd.append('file',f);
  fetch('admin_secciones.php?action=upload',{method:'POST',body:fd}).then(r=>r.json()).then(j=>{
    const r=document.getElementById('upRes'); r.innerHTML = j.ok ? '<code>'+j.url+'</code>' : 'Error upload';
  });
};

reload();
</script>
</body>
</html>
