<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<title>ARKHON - IA Importación y Diseño</title>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
<style>
:root{--orange:#f97316;--orange-lt:#fff4ed;--green:#10b981;--green-lt:#e8fbf3;--red:#ef4444;--red-lt:#fff1f2;--text:#111827;--text-2:#4b5563;--text-3:#8b95a1;--bg:#f6f7fb;--surface:#fff;--border:#e5e7eb;--shadow:0 8px 26px rgba(15,23,42,.08);--r:8px;}
*{box-sizing:border-box}body{margin:0;font-family:'Plus Jakarta Sans',system-ui,sans-serif;background:var(--bg);color:var(--text);height:100vh;overflow:hidden}
svg{width:16px;height:16px;stroke:currentColor;stroke-width:2;fill:none}.page{height:100vh;display:flex;flex-direction:column}
.topbar{height:56px;background:var(--surface);border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px;padding:0 18px;flex-shrink:0}
.topbar-icon{width:32px;height:32px;border-radius:8px;background:var(--orange);color:#fff;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 12px rgba(249,115,22,.24)}
h1{font-size:15px;margin:0;font-weight:800;letter-spacing:0}.status{margin-left:auto;font-size:11px;font-weight:700;color:var(--text-3)}
.workspace{flex:1;min-height:0;display:grid;grid-template-columns:minmax(300px,390px) minmax(0,1fr);gap:14px;padding:14px;overflow:hidden}
.panel{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--shadow);min-height:0;display:flex;flex-direction:column;overflow:hidden}
.panel-head{padding:14px 16px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:8px;justify-content:space-between}
.panel-title{font-size:13px;font-weight:800}.panel-body{padding:14px 16px;overflow:auto;min-height:0}.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
label{display:block;font-size:10px;font-weight:800;color:var(--text-3);text-transform:uppercase;margin-bottom:5px}select,input,textarea{width:100%;border:1px solid var(--border);border-radius:7px;background:#fff;color:var(--text);font:inherit;font-size:12px;padding:9px 10px;outline:none}
textarea{min-height:170px;resize:vertical;line-height:1.45}.drop{margin-top:12px;border:1.5px dashed #cfd6e3;border-radius:8px;background:#fbfcff;min-height:120px;display:flex;align-items:center;justify-content:center;text-align:center;cursor:pointer;color:var(--text-2);padding:18px}
.drop.drag{border-color:var(--orange);background:var(--orange-lt)}.drop strong{display:block;font-size:12px;color:var(--text);margin-bottom:3px}.drop span{font-size:11px;color:var(--text-3)}
.actions{display:flex;gap:8px;align-items:center;margin-top:12px;flex-wrap:wrap}.btn{border:none;border-radius:7px;padding:9px 12px;font-size:11px;font-weight:800;display:inline-flex;align-items:center;gap:6px;cursor:pointer}.btn:disabled{opacity:.55;cursor:not-allowed}
.btn-orange{background:var(--orange);color:#fff}.btn-green{background:var(--green);color:#fff}.btn-ghost{background:#fff;border:1px solid var(--border);color:var(--text-2)}.btn-red{background:var(--red-lt);color:var(--red)}
.meta{font-size:11px;color:var(--text-3);margin-top:8px}.table-wrap{overflow:auto;min-height:0;flex:1}.data{width:100%;border-collapse:collapse;font-size:11px;min-width:820px}.data th{position:sticky;top:0;background:#f9fafb;z-index:1;text-align:left;font-size:9.5px;text-transform:uppercase;color:var(--text-3);padding:9px;border-bottom:1px solid var(--border)}.data td{padding:6px;border-bottom:1px solid var(--border);vertical-align:middle}.data input,.data select{font-size:11px;padding:6px 7px}
.badge{display:inline-flex;border-radius:999px;padding:3px 7px;font-size:10px;font-weight:800}.badge.nuevo{background:var(--green-lt);color:var(--green)}.badge.revisar,.badge.actualizar{background:var(--orange-lt);color:var(--orange)}.badge.error{background:var(--red-lt);color:var(--red)}
.empty{height:100%;min-height:260px;display:flex;align-items:center;justify-content:center;text-align:center;color:var(--text-3);font-size:12px}.spin{width:18px;height:18px;border:2px solid var(--border);border-top-color:var(--orange);border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}
.result{padding:12px;border-radius:8px;background:#f9fafb;border:1px solid var(--border);font-size:12px;margin-top:12px}.result.ok{background:var(--green-lt);border-color:#a7f3d0;color:#047857}.result.err{background:var(--red-lt);border-color:#fecdd3;color:#b91c1c}
.sr-list{display:grid;gap:10px;padding:12px;min-width:760px}.sr-table{border:1px solid var(--border);border-radius:8px;background:#fff;overflow:hidden}.sr-table-head{display:grid;grid-template-columns:minmax(160px,1fr) 90px 110px 1.3fr;gap:10px;align-items:center;padding:10px 12px;background:#f9fafb;border-bottom:1px solid var(--border);font-size:11px}.sr-name{font-weight:800}.sr-muted{color:var(--text-3);font-size:10px}.sr-sample{padding:10px 12px;font-size:10.5px;color:var(--text-2);white-space:nowrap;overflow:auto}.sr-sample code{background:#f3f4f6;border:1px solid var(--border);border-radius:6px;padding:3px 5px;margin-right:5px;display:inline-block}
@media(max-width:900px){body{overflow:auto}.page{height:auto;min-height:100vh}.workspace{grid-template-columns:1fr;overflow:visible}.panel{min-height:360px}.data{min-width:760px}}
</style>
</head>
<body>
<div class="page">
  <div class="topbar">
    <div class="topbar-icon"><svg viewBox="0 0 24 24"><path d="M12 3l1.7 4.3L18 9l-4.3 1.7L12 15l-1.7-4.3L6 9l4.3-1.7L12 3z"/><path d="M19 14l.9 2.1L22 17l-2.1.9L19 20l-.9-2.1L16 17l2.1-.9L19 14z"/></svg></div>
    <h1>IA Importación y Diseño</h1>
    <div class="status" id="status">Listo</div>
  </div>

  <div class="workspace">
    <section class="panel">
      <div class="panel-head">
        <div class="panel-title">Entrada</div>
        <button class="btn btn-ghost" onclick="resetAll()"><svg viewBox="0 0 24 24"><path d="M3 12a9 9 0 109-9 9.75 9.75 0 00-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>Limpiar</button>
      </div>
      <div class="panel-body">
        <div class="form-grid">
          <div>
            <label for="tipo">Destino</label>
            <select id="tipo">
              <option value="inventario">Inventario / insumos</option>
              <option value="menu">Menu / productos</option>
              <option value="softrestaurant">Catalogos SoftRestaurant</option>
            </select>
          </div>
          <div>
            <label for="prefijo">Prefijo</label>
            <input id="prefijo" maxlength="6" placeholder="BAR"/>
          </div>
        </div>

        <div class="drop" id="drop" onclick="document.getElementById('file').click()" ondragover="dragOver(event)" ondragleave="dragLeave(event)" ondrop="dropFile(event)">
          <div>
            <strong id="file-name">Seleccionar archivo</strong>
            <span>PDF, XLSX, ZIP, TXT, PNG, JPG o WEBP</span>
          </div>
        </div>
        <input type="file" id="file" accept=".pdf,.txt,.xlsx,.zip,.png,.jpg,.jpeg,.webp" hidden onchange="pickFile(this)"/>

        <div style="margin-top:12px">
          <label for="texto">Texto</label>
          <textarea id="texto" placeholder="Pega aqui el contenido a procesar"></textarea>
        </div>

        <div class="actions">
          <button class="btn btn-orange" id="btn-preview" onclick="previewImport()"><svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.3-4.3"/></svg>Previsualizar</button>
          <button class="btn btn-green" id="btn-apply" onclick="applyImport()" disabled><svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>Importar</button>
          <button class="btn btn-ghost" id="btn-nexus-zip" onclick="downloadNexusZip()" type="button" disabled><svg viewBox="0 0 24 24"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><path d="M3.3 7L12 12l8.7-5"/><path d="M12 22V12"/></svg>ZIP NEXUS</button>
          <button class="btn btn-ghost" id="btn-template" onclick="downloadSrTemplate()" type="button"><svg viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="M7 10l5 5 5-5"/><path d="M12 15V3"/></svg>Plantilla SR</button>
        </div>
        <div class="meta" id="meta">0 filas listas</div>
        <div class="result" id="result" style="display:none"></div>
      </div>
    </section>

    <section class="panel">
      <div class="panel-head">
        <div class="panel-title" id="preview-title">Revision</div>
        <button class="btn btn-red" onclick="removeSelected()" id="btn-remove" disabled><svg viewBox="0 0 24 24"><path d="M3 6h18"/><path d="M8 6V4h8v2"/><path d="M19 6l-1 14H6L5 6"/></svg>Eliminar marcadas</button>
      </div>
      <div class="table-wrap" id="preview">
        <div class="empty">Sin previsualizacion</div>
      </div>
    </section>
  </div>
</div>

<script src="/js/arkhon-utils.js"></script>
<script>
let selectedFile = null;
let filas = [];
let srTables = [];
let catalogPlan = null;
let nexusData = null;
let nexusValidation = null;
let promptMeta = null;
let tipoActual = 'inventario';

function $(id){ return document.getElementById(id); }
function setStatus(txt){ $('status').textContent = txt; }
function esc(v){ return String(v ?? '').replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c])); }
function isMenu(){ return tipoActual === 'menu'; }
function isSr(){ return tipoActual === 'softrestaurant'; }
function normalizeName(value){ return String(value || '').normalize('NFD').replace(/[\u0300-\u036f]/g, '').toUpperCase(); }
function isMenuFileName(name){ return /\b(MENU|CARTA|PRODUCTO|PRODUCTOS|PLATILLO|PLATILLOS)\b/.test(normalizeName(name)); }

function dragOver(e){ e.preventDefault(); $('drop').classList.add('drag'); }
function dragLeave(e){ e.preventDefault(); $('drop').classList.remove('drag'); }
function dropFile(e){ e.preventDefault(); $('drop').classList.remove('drag'); if(e.dataTransfer.files[0]) setFile(e.dataTransfer.files[0]); }
function pickFile(input){ if(input.files[0]) setFile(input.files[0]); }

function setFile(file){
  if(/\.xls$/i.test(file.name) && !/\.xlsx$/i.test(file.name)){
    showResult('El formato XLS antiguo no esta soportado. Guarda el archivo como XLSX.', true);
    return;
  }
  selectedFile = file;
  $('file-name').textContent = file.name;
  if(/\.zip$/i.test(file.name)){
    $('tipo').value = 'softrestaurant';
  } else if(($('tipo').value || 'inventario') === 'inventario' && isMenuFileName(file.name)){
    $('tipo').value = 'menu';
  }
  tipoActual = $('tipo').value || 'inventario';
  if(/\.(txt|csv)$/i.test(file.name)){
    const reader = new FileReader();
    reader.onload = e => { $('texto').value = e.target.result || ''; };
    reader.readAsText(file);
  }
}

function showResult(message, isError){
  const el = $('result');
  el.style.display = '';
  el.className = 'result ' + (isError ? 'err' : 'ok');
  el.textContent = message;
}

function formatNexusValidation(){
  const errors = nexusValidation?.errors || [];
  const warnings = nexusValidation?.warnings || [];
  if (errors.length) return ` | errores NEXUS: ${errors.slice(0, 3).join('; ')}`;
  if (warnings.length) return ` | advertencias NEXUS: ${warnings.slice(0, 2).join('; ')}`;
  if (nexusValidation) return ' | NEXUS valido';
  return '';
}

async function previewImport(){
  const texto = $('texto').value.trim();
  tipoActual = $('tipo').value || 'inventario';
  if(!texto && !selectedFile){
    showResult('Sube un archivo o pega texto antes de previsualizar.', true);
    return;
  }

  $('btn-preview').disabled = true;
  $('btn-apply').disabled = true;
  $('preview').innerHTML = '<div class="empty"><div class="spin"></div></div>';
  setStatus('Analizando');
  $('result').style.display = 'none';

  try {
    const fd = new FormData();
    fd.append('tipo', tipoActual);
    fd.append('prefijo', $('prefijo').value || '');
    if(selectedFile) fd.append('file', selectedFile);
    else fd.append('texto', texto);

    const res = await fetch('/api/inventario/importar-inteligente/preview', {
      method: 'POST',
      headers: { 'X-Api-Token': window.LOCAL_API_KEY || '' },
      body: fd,
    });
    const json = await res.json();
    if(!json.ok) throw new Error(json.error || 'Error al analizar');

    const data = json.data || json;
    if (data.tipo && data.tipo !== tipoActual) {
      tipoActual = data.tipo;
      $('tipo').value = data.tipo;
    }
    if (tipoActual === 'softrestaurant') {
      srTables = Array.isArray(data.tablas) ? data.tablas : [];
      filas = [];
      catalogPlan = null;
      nexusData = null;
      nexusValidation = null;
      promptMeta = null;
      $('btn-nexus-zip').disabled = true;
      renderSrTables(data);
      showResult(`${data.total || 0} registros en ${data.tablas_importables || 0} tablas importables`, false);
    } else {
      srTables = [];
      filas = Array.isArray(data.filas) ? data.filas : [];
      catalogPlan = data.catalog_plan || null;
      nexusData = data.nexus || null;
      nexusValidation = data.nexus_validacion || null;
      promptMeta = data.prompt_meta || null;
      $('btn-nexus-zip').disabled = !filas.length && !nexusData;
      renderRows(data.requieren_revision || 0);
      const plan = catalogPlan?.resumen;
      const planText = plan ? ` | ${plan.grupos || 0} grupos, ${plan.subgrupos || 0} subgrupos, ${plan.modificadores || 0} modificadores` : '';
      const promptText = promptMeta?.hash ? ` | prompt ${promptMeta.version || ''} ${String(promptMeta.hash).slice(0, 8)}` : '';
      showResult(`${filas.length} filas preparadas${planText}${promptText}${formatNexusValidation()}`, !!(nexusValidation?.errors || []).length);
    }
  } catch(e) {
    filas = [];
    catalogPlan = null;
    nexusData = null;
    nexusValidation = null;
    promptMeta = null;
    $('btn-nexus-zip').disabled = true;
    $('preview').innerHTML = `<div class="empty">${esc(e.message || 'Error al analizar')}</div>`;
    showResult(e.message || 'Error al analizar', true);
  } finally {
    $('btn-preview').disabled = false;
    setStatus('Listo');
  }
}

function renderRows(revisionCount){
  $('btn-apply').disabled = !filas.length;
  $('btn-remove').disabled = !filas.length;
  $('meta').textContent = `${filas.length} filas listas`;
  $('preview-title').textContent = `${filas.length} ${isMenu() ? 'productos' : 'insumos'} - ${revisionCount} en revision`;
  if(!filas.length){
    $('preview').innerHTML = '<div class="empty">Sin filas para revisar</div>';
    return;
  }

  $('preview').innerHTML = `
    <table class="data">
      <thead><tr>
        <th style="width:38px"></th>
        <th>Clave</th><th>Descripcion</th>${isMenu() ? '<th>Grupo</th><th>Subgrupo</th>' : ''}<th>Unidad</th><th>${isMenu() ? 'Precio' : 'Costo'}</th><th>Estado</th>
      </tr></thead>
      <tbody>${filas.map((f,i) => rowHtml(f,i)).join('')}</tbody>
    </table>`;
}

function renderSrTables(data){
  const importables = srTables.filter(t => t.estado === 'lista' && Number(t.total || 0) > 0);
  $('btn-apply').disabled = !importables.length;
  $('btn-remove').disabled = true;
  $('meta').textContent = `${data.total || 0} registros listos`;
  $('preview-title').textContent = `${importables.length} tablas importables - ${data.tablas_omitidas || 0} omitidas`;
  if(!srTables.length){
    $('preview').innerHTML = '<div class="empty">Sin tablas para revisar</div>';
    return;
  }
  $('preview').innerHTML = `<div class="sr-list">${srTables.map(srTableHtml).join('')}</div>`;
}

function srTableHtml(t){
  const estado = t.estado === 'lista' ? 'nuevo' : 'error';
  const sample = (t.muestra || []).slice(0, 1).map(row => Object.entries(row).map(([k,v]) => `<code>${esc(k)}=${esc(v)}</code>`).join('')).join('');
  const omitted = (t.columnas_omitidas || []).length ? `Omitidas: ${(t.columnas_omitidas || []).join(', ')}` : '';
  return `<div class="sr-table">
    <div class="sr-table-head">
      <div><div class="sr-name">${esc(t.tabla)}</div><div class="sr-muted">${esc(t.archivo || '')}</div></div>
      <div><strong>${Number(t.total || 0)}</strong><div class="sr-muted">registros</div></div>
      <div><span class="badge ${estado}">${esc(t.estado || 'omitida')}</span></div>
      <div class="sr-muted">${esc(t.motivo || omitted || 'Lista para upsert')}</div>
    </div>
    <div class="sr-sample">${sample || '<span class="sr-muted">Sin muestra</span>'}</div>
  </div>`;
}

function rowHtml(f,i){
  const idKey = isMenu() ? 'idproducto' : 'idinsumo';
  const costKey = isMenu() ? 'precio' : 'ultimo_costo';
  const units = ['KGS','PZA','LT','ML','GALON','CAJA','OZ','GR','BOLSA','PAQ','BOT'];
  const menuCols = isMenu() ? `
    <td><input value="${esc(f.grupo || f.idgrupo || '')}" maxlength="40" onchange="filas[${i}].grupo=this.value.toUpperCase()"></td>
    <td><input value="${esc(f.subgrupo || f.idsubgrupo || '')}" maxlength="40" onchange="filas[${i}].subgrupo=this.value.toUpperCase()"></td>` : '';
  return `<tr>
    <td><input type="checkbox" data-check="${i}" style="width:16px;height:16px"></td>
    <td><input value="${esc(f[idKey] || '')}" maxlength="${isMenu() ? 15 : 10}" onchange="filas[${i}]['${idKey}']=this.value.toUpperCase()"></td>
    <td><input value="${esc(f.descripcion || '')}" maxlength="80" onchange="filas[${i}].descripcion=this.value.toUpperCase()"></td>
    ${menuCols}
    <td><select onchange="filas[${i}].unidad=this.value">${units.map(u => `<option ${f.unidad===u?'selected':''}>${u}</option>`).join('')}</select></td>
    <td><input type="number" min="0" step="0.01" value="${Number(f[costKey] || 0)}" onchange="filas[${i}]['${costKey}']=Number(this.value)||0"></td>
    <td><span class="badge ${esc(f.estado || 'revisar')}">${esc(f.estado || 'revisar')}</span></td>
  </tr>`;
}

function removeSelected(){
  const selected = [...document.querySelectorAll('[data-check]:checked')].map(x => Number(x.dataset.check));
  filas = filas.filter((_,i) => !selected.includes(i));
  renderRows(0);
}

async function applyImport(){
  if(!filas.length && !srTables.length) return;
  $('btn-apply').disabled = true;
  setStatus('Importando');
  try {
    const body = tipoActual === 'softrestaurant'
      ? { tipo: tipoActual, tablas: srTables.filter(t => t.estado === 'lista' && Number(t.total || 0) > 0) }
      : { tipo: tipoActual, filas, catalog_plan: catalogPlan };
    const data = await apiFetch('/api/inventario/importar-inteligente/aplicar', {
      method: 'POST',
      body: JSON.stringify(body)
    });
    const result = data || {};
    const errors = (result.resultados || []).filter(x => !x.ok);
    showResult(`${result.guardados || 0} de ${result.total || filas.length} filas importadas${errors.length ? `, ${errors.length} con error` : ''}`, !!errors.length);
  } catch(e) {
    showResult(e.message || 'Error al importar', true);
  } finally {
    $('btn-apply').disabled = false;
    setStatus('Listo');
  }
}

function resetAll(){
  selectedFile = null;
  filas = [];
  srTables = [];
  catalogPlan = null;
  nexusData = null;
  nexusValidation = null;
  promptMeta = null;
  $('file').value = '';
  $('file-name').textContent = 'Seleccionar archivo';
  $('texto').value = '';
  $('result').style.display = 'none';
  $('preview-title').textContent = 'Revision';
  $('preview').innerHTML = '<div class="empty">Sin previsualizacion</div>';
  $('meta').textContent = '0 filas listas';
  $('btn-apply').disabled = true;
  $('btn-nexus-zip').disabled = true;
  $('btn-remove').disabled = true;
}

async function downloadNexusZip(){
  if(!filas.length && !nexusData) return;
  const btn = $('btn-nexus-zip');
  btn.disabled = true;
  setStatus('Generando ZIP NEXUS');
  try {
    const res = await fetch('/api/inventario/importar-inteligente/exportar-nexus-zip', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Api-Token': window.LOCAL_API_KEY || ''
      },
      body: JSON.stringify({ tipo: tipoActual, filas, nexus: nexusData, catalog_plan: catalogPlan })
    });
    if (!res.ok) {
      let message = `Error ${res.status}`;
      try {
        const data = await res.json();
        message = data.error || message;
      } catch (_) {}
      throw new Error(message);
    }
    const blob = await res.blob();
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'ARKHON-NEXUS-Catalogos.zip';
    document.body.appendChild(a);
    a.click();
    a.remove();
    setTimeout(() => URL.revokeObjectURL(url), 1000);
    showResult('ZIP NEXUS descargado.', false);
  } catch(e) {
    showResult(e.message || 'No se pudo generar el ZIP NEXUS', true);
  } finally {
    btn.disabled = false;
    setStatus('Listo');
  }
}

async function downloadSrTemplate(){
  const btn = $('btn-template');
  btn.disabled = true;
  setStatus('Descargando plantilla');
  try {
    const res = await fetch('/api/inventario/importar-inteligente/plantilla-sr', {
      headers: { 'X-Api-Token': window.LOCAL_API_KEY || '' },
    });
    if (!res.ok) {
      let message = `Error ${res.status}`;
      try {
        const data = await res.json();
        message = data.error || message;
      } catch (_) {}
      throw new Error(message);
    }
    const blob = await res.blob();
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'ARKHON-Plantilla-Catalogos-SoftRestaurant.xlsx';
    document.body.appendChild(a);
    a.click();
    a.remove();
    setTimeout(() => URL.revokeObjectURL(url), 1000);
    showResult('Plantilla SR descargada.', false);
  } catch(e) {
    showResult(e.message || 'No se pudo descargar la plantilla', true);
  } finally {
    btn.disabled = false;
    setStatus('Listo');
  }
}

(async function init(){
  try { await _initAuth(); } catch(e) { showResult(e.message || 'Sesion no disponible', true); }
})();
</script>
</body>
</html>
