/* ============================================================
   FLOWSHIELD — Shell: Sidebar + Topbar
   ============================================================ */
function Sidebar({ active, onNav, theme }) {
  usePlan();   // re-render del nav al cambiar de plan
  const op = window.NAV.filter(n => n.group === 'op');
  const cfg = window.NAV.filter(n => n.group === 'cfg');
  const [act, setAct] = useStateL(null);   // {running, today, total}
  useEffectL(() => {
    let alive = true;
    const load = () => window.fsApi('/api/results/activity', { method:'GET' })
      .then(d => { if (alive) setAct(d); }).catch(() => {});
    load();
    const t = setInterval(load, 20000);
    return () => { alive = false; clearInterval(t); };
  }, [active]);

  const Item = ({ n }) => {
    const isActive = active === n.id;
    const locked = window.fsModuleAllowed && !window.fsModuleAllowed(n.id);
    return (
      <button onClick={() => onNav(n.id)} title={locked ? 'No incluido en tu plan' : undefined}
        className={'side-item' + (isActive ? ' on' : '') + (n.theme ? ' theme-' + n.theme : '')}
        style={locked ? { opacity:.55 } : undefined}>
        <span className="side-rail" />
        <Icon name={n.icon} size={18} />
        <span style={{ flex:1, textAlign:'left' }}>{n.label}</span>
        {locked ? <Icon name="lock" size={13} style={{ color:'var(--txt-mute)' }} />
                : (n.tag && <span className="side-tag mono">{n.tag}</span>)}
      </button>
    );
  };

  return (
    <aside style={{ width:'var(--sidebar-w)', flex:'0 0 var(--sidebar-w)', background:'linear-gradient(180deg,#070A11,#05070D)', borderRight:'1px solid var(--line)', display:'flex', flexDirection:'column', height:'100vh', position:'relative', zIndex:5 }}>
      <div style={{ padding:'20px 18px 16px' }}>
        <Logo size={32} />
      </div>

      <div style={{ padding:'4px 14px 14px' }}>
        <button className="newscan-btn" onClick={() => onNav('redteam')}>
          <Icon name="bolt" size={17} />
          <span>Nuevo escaneo</span>
        </button>
      </div>

      <nav className="hidden-scroll" style={{ flex:1, overflowY:'auto', padding:'4px 10px 20px' }}>
        <div className="side-group mono">OPERACIONES</div>
        {op.map(n => <Item key={n.id} n={n} />)}
        <div className="side-group mono" style={{ marginTop:18 }}>CONFIGURACIÓN</div>
        {cfg.map(n => <Item key={n.id} n={n} />)}
      </nav>

      <div style={{ padding:'12px 14px', borderTop:'1px solid var(--line)' }}>
        <div className="panel" style={{ padding:'11px 12px', display:'flex', gap:9, alignItems:'center', background:'var(--bg-panel-2)' }}>
          <div style={{ width:9, height:9, borderRadius:99, background: (act && act.running) ? 'var(--amber)' : 'var(--ok)', color:(act && act.running) ? 'var(--amber)' : 'var(--ok)', boxShadow:`0 0 8px ${(act && act.running) ? 'var(--amber)' : 'var(--ok)'}` }} className="pulse" />
          <div style={{ flex:1 }}>
            <div className="mono" style={{ fontSize:10.5, color:'var(--txt)' }}>{act ? (act.running ? `${act.running} escaneo${act.running===1?'':'s'} en curso` : 'sin escaneos en curso') : '…'}</div>
            <div className="mono" style={{ fontSize:9, color:'var(--txt-mute)' }}>{act ? `hoy: ${act.today} · total: ${act.total}` : ''}</div>
          </div>
        </div>
      </div>

      <style>{`
        .newscan-btn{position:relative;width:100%;display:flex;align-items:center;justify-content:center;gap:9px;font-family:var(--font-display);font-weight:700;font-size:13.5px;letter-spacing:.03em;color:#04110D;background:linear-gradient(135deg,var(--fs),#29E0FF);border:none;border-radius:9px;padding:13px;cursor:pointer;overflow:hidden;box-shadow:0 6px 22px -8px var(--fs-glow);transition:transform .15s,box-shadow .2s}
        .newscan-btn:hover{transform:translateY(-2px);box-shadow:0 12px 30px -8px var(--fs-glow),0 0 22px -4px var(--fs-glow)}
        .newscan-btn::before{content:'';position:absolute;top:0;left:-120%;width:55%;height:100%;background:linear-gradient(100deg,transparent,rgba(255,255,255,.4),transparent);transform:skewX(-20deg);transition:left .55s}
        .newscan-btn:hover::before{left:150%}
        .side-group{font-size:9.5px;letter-spacing:.2em;color:var(--txt-mute);padding:6px 12px 8px}
        .side-item{position:relative;width:100%;display:flex;align-items:center;gap:11px;font-family:var(--font-body);font-weight:500;font-size:13.5px;color:var(--txt-dim);background:none;border:none;padding:10px 12px;border-radius:8px;cursor:pointer;margin-bottom:2px;transition:color .18s,background .18s}
        .side-item:hover{color:var(--txt-hi);background:var(--bg-panel-2)}
        .side-item.on{color:var(--acc);background:color-mix(in srgb,var(--acc) 9%,transparent)}
        .side-item .side-rail{position:absolute;left:0;top:50%;transform:translateY(-50%) scaleY(0);width:3px;height:60%;background:var(--acc);border-radius:0 3px 3px 0;box-shadow:0 0 10px var(--acc);transition:transform .2s}
        .side-item.on .side-rail{transform:translateY(-50%) scaleY(1)}
        .side-item.on{ --acc: var(--fs); }
        .side-item.theme-red.on{--acc:var(--red)} .side-item.theme-blue.on{--acc:var(--blue)} .side-item.theme-amber.on{--acc:var(--amber)}
        .side-item.theme-red:hover{--acc:var(--red)} .side-item.theme-blue:hover{--acc:var(--blue)} .side-item.theme-amber:hover{--acc:var(--amber)}
        .side-tag{font-size:8px;letter-spacing:.1em;padding:2px 6px;border-radius:99px;background:color-mix(in srgb,var(--acc) 14%,transparent);color:var(--acc);border:1px solid color-mix(in srgb,var(--acc) 30%,transparent)}
      `}</style>
    </aside>
  );
}

function Topbar({ user, section, onLogout, onCmd }) {
  const meta = window.NAV.find(n => n.id === section);
  return (
    <header style={{ height:58, flex:'0 0 58px', display:'flex', alignItems:'center', gap:16, padding:'0 24px', borderBottom:'1px solid var(--line)', background:'rgba(8,11,20,0.7)', backdropFilter:'blur(10px)', position:'relative', zIndex:4 }}>
      <button onClick={onCmd} className="cmd-trigger">
        <Icon name="search" size={15} />
        <span style={{ flex:1, textAlign:'left' }}>Buscar herramientas, activos, CVEs…</span>
        <kbd className="mono">⌘K</kbd>
      </button>
      <div style={{ flex:1 }} />
      <div className="badge sev-ok" style={{ background:'transparent' }}>
        <span className="dot pulse" style={{ background:'currentColor' }} />NODO OPERATIVO
      </div>
      <div style={{ width:1, height:26, background:'var(--line)' }} />
      <button className="user-chip" onClick={onLogout} title="Cerrar sesión">
        <div style={{ width:30, height:30, borderRadius:8, background:'linear-gradient(135deg,var(--fs),#29E0FF)', display:'grid', placeItems:'center', color:'#04110D', fontFamily:'var(--font-display)', fontWeight:700, fontSize:13 }}>{(String(user||'?').trim()[0]||'?').toUpperCase()}</div>
        <div style={{ textAlign:'left', lineHeight:1.2 }}>
          <div style={{ fontSize:12.5, color:'var(--txt-hi)', fontWeight:600 }}>{user}</div>
          <div className="mono" style={{ fontSize:9, color:'var(--txt-mute)' }}>OPERADOR · BASE</div>
        </div>
        <Icon name="logout" size={15} style={{ color:'var(--txt-mute)' }} />
      </button>
      <style>{`
        .cmd-trigger{display:flex;align-items:center;gap:10px;width:380px;max-width:38vw;font-size:12.5px;color:var(--txt-mute);background:var(--bg-void);border:1px solid var(--line-bright);border-radius:8px;padding:8px 12px;cursor:pointer;transition:border-color .2s}
        .cmd-trigger:hover{border-color:var(--fs)}
        .cmd-trigger kbd{font-size:10px;padding:2px 6px;border:1px solid var(--line-bright);border-radius:5px;color:var(--txt-dim)}
        .user-chip{display:flex;align-items:center;gap:10px;background:none;border:1px solid transparent;border-radius:9px;padding:5px 8px;cursor:pointer;transition:background .18s,border-color .18s}
        .user-chip:hover{background:var(--bg-panel-2);border-color:var(--line)}
      `}</style>
    </header>
  );
}

/* Command palette */
function CmdPalette({ open, onClose, onNav }) {
  const [q, setQ] = useStateL('');
  useEffectL(() => { if (open) setQ(''); }, [open]);
  if (!open) return null;
  const items = [
    ...window.NAV.map(n => ({ type:'nav', id:n.id, label:n.label, icon:n.icon })),
    ...window.REDTEAM_TABS.flatMap(t => (t.sections||[]).flatMap(s => s.tools||[])).map(t => ({ type:'tool', id:'redteam', label:t.name, icon:t.icon, sub:'Red Team' })),
  ];
  const seen = new Set();
  const filtered = items.filter(i => {
    const k = i.type+i.label; if (seen.has(k)) return false; seen.add(k);
    return i.label.toLowerCase().includes(q.toLowerCase());
  }).slice(0, 9);
  return (
    <div onClick={onClose} style={{ position:'fixed', inset:0, zIndex:9000, background:'rgba(3,5,10,.7)', backdropFilter:'blur(4px)', display:'grid', placeItems:'start center', paddingTop:'12vh' }}>
      <div className="enter theme-fs" onClick={e=>e.stopPropagation()} style={{ width:'min(580px,92vw)', background:'var(--bg-panel)', border:'1px solid var(--line-bright)', borderRadius:14, overflow:'hidden', boxShadow:'0 30px 80px -20px rgba(0,0,0,.7)' }}>
        <div style={{ display:'flex', alignItems:'center', gap:12, padding:'15px 18px', borderBottom:'1px solid var(--line)' }}>
          <Icon name="search" size={18} style={{ color:'var(--fs)' }} />
          <input autoFocus value={q} onChange={e=>setQ(e.target.value)} placeholder="Comando o herramienta…" style={{ flex:1, background:'none', border:'none', outline:'none', color:'var(--txt-hi)', fontSize:15, fontFamily:'var(--font-mono)' }} />
          <kbd className="mono" style={{ fontSize:10, color:'var(--txt-mute)', border:'1px solid var(--line-bright)', borderRadius:5, padding:'2px 6px' }}>ESC</kbd>
        </div>
        <div style={{ maxHeight:340, overflowY:'auto', padding:8 }}>
          {filtered.map((i, idx) => (
            <button key={idx} onClick={()=>{onNav(i.id); onClose();}} className="cmd-row">
              <Icon name={i.icon} size={17} style={{ color:'var(--fs)' }} />
              <span style={{ flex:1, textAlign:'left', color:'var(--txt-hi)', fontSize:13.5 }}>{i.label}</span>
              {i.sub && <span className="mono" style={{ fontSize:10, color:'var(--txt-mute)' }}>{i.sub}</span>}
              <Icon name="chevron" size={14} style={{ color:'var(--txt-mute)' }} />
            </button>
          ))}
          {!filtered.length && <div style={{ padding:'28px', textAlign:'center', color:'var(--txt-mute)', fontSize:13 }}>Sin resultados</div>}
        </div>
        <style>{`.cmd-row{width:100%;display:flex;align-items:center;gap:12px;padding:11px 12px;background:none;border:none;border-radius:8px;cursor:pointer;transition:background .15s}.cmd-row:hover{background:var(--fs-soft)}`}</style>
      </div>
    </div>
  );
}

Object.assign(window, { Sidebar, Topbar, CmdPalette });
