// ─────────────────────────────────────────────────────
// MAIN APP — auth gate, route registry, accent/density tweaks.
// Light mode only (manager preference).
// ─────────────────────────────────────────────────────

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "density": "default",
  "accent": "glass",
  "primaryView": "dashboard"
}/*EDITMODE-END*/;

const ACCENT_PRESETS = {
  glass:  { '--accent': '#5fb4d9', '--glass': '#5fb4d9', '--glass-2': '#bfdbe8', '--glass-3': '#e8f2f7', '--accent-ink': '#1f6e92' },
  amber:  { '--accent': '#d97706', '--glass': '#d97706', '--glass-2': '#fbe4b8', '--glass-3': '#fdf3df', '--accent-ink': '#92400e' },
  green:  { '--accent': '#15803d', '--glass': '#15803d', '--glass-2': '#bce5c8', '--glass-3': '#e2f3e8', '--accent-ink': '#14532d' },
  carbon: { '--accent': '#3a4048', '--glass': '#3a4048', '--glass-2': '#c8ccd2', '--glass-3': '#e8eaed', '--accent-ink': '#1a1d21' },
};

const App = () => {
  const { user, logout } = useAuth();

  if (!user) {
    return <Login/>;
  }
  return <AuthedApp user={user} onLogout={logout}/>;
};

const AuthedApp = ({ user, onLogout }) => {
  const saved = (() => { try { return JSON.parse(localStorage.getItem('erpkurten') || '{}'); } catch(e) { return {}; }})();
  const [view, setView] = React.useState(saved.view || TWEAK_DEFAULTS.primaryView);
  const [density, setDensity] = React.useState(saved.density || TWEAK_DEFAULTS.density);
  const [accent, setAccent] = React.useState(saved.accent || TWEAK_DEFAULTS.accent);
  const [openLead, setOpenLead]         = React.useState(null);
  const [openCompra, setOpenCompra]     = React.useState(null);
  const [compraFormMode, setCompraFormMode] = React.useState(null); // null | 'new' | pedidoId
  const [tweaksOpen, setTweaksOpen]     = React.useState(false);
  const [chpwdOpen, setChpwdOpen] = React.useState(false);
  const [mcpTokenOpen, setMcpTokenOpen] = React.useState(false);
  const [toast, setToast] = React.useState(null);
  const [refreshKey, setRefreshKey] = React.useState(0);
  const refresh = React.useCallback(() => setRefreshKey(k => k + 1), []);
  const showToast = React.useCallback((msg, isErr) => {
    setToast({ msg, isErr });
    if (!isErr) setTimeout(() => setToast(null), 2200);
  }, []);

  React.useEffect(() => {
    document.documentElement.setAttribute('data-theme', 'light');
    document.documentElement.setAttribute('data-density', density);
    const preset = ACCENT_PRESETS[accent];
    Object.entries(preset).forEach(([k,v]) => document.documentElement.style.setProperty(k, v));
    localStorage.setItem('erpkurten', JSON.stringify({ view, density, accent }));
  }, [view, density, accent]);

  // GUT-56 — abrir un presupuesto concreto desde el drawer del lead.
  React.useEffect(() => {
    const handler = (e) => {
      const id = e.detail && e.detail.id;
      if (!id) return;
      setView('presupuestos');
      window.__erpPendingPresupuestoId = id;
    };
    window.addEventListener('erp:open-presupuesto', handler);
    return () => window.removeEventListener('erp:open-presupuesto', handler);
  }, []);

  // GUT-63 — abrir un lead concreto desde el detalle del presupuesto (navegación inversa).
  React.useEffect(() => {
    const handler = (e) => {
      const id = e.detail && e.detail.id;
      if (!id) return;
      window.__erpPendingLeadId = id;
      setView('leads');
    };
    window.addEventListener('erp:open-lead', handler);
    return () => window.removeEventListener('erp:open-lead', handler);
  }, []);

  // GUT-63 — abrir un expediente concreto (por pedido_id) desde otra vista.
  React.useEffect(() => {
    const handler = (e) => {
      const pedidoId = e.detail && e.detail.pedidoId;
      if (!pedidoId) return;
      window.__erpPendingExpedienteId = pedidoId;
      setView('expedientes');
    };
    window.addEventListener('erp:open-expediente', handler);
    return () => window.removeEventListener('erp:open-expediente', handler);
  }, []);

  // GUT-67 — abrir una OC concreta desde la línea BOM ligada (la OC manda el estado).
  React.useEffect(() => {
    const handler = (e) => {
      const id = e.detail && e.detail.id;
      if (!id) return;
      window.__erpPendingOrdenId = id;
      setView('ordenes');
    };
    window.addEventListener('erp:open-orden', handler);
    return () => window.removeEventListener('erp:open-orden', handler);
  }, []);

  // Edit-mode protocol (designer preview)
  React.useEffect(() => {
    const handler = (e) => {
      if (e.data?.type === '__activate_edit_mode')   setTweaksOpen(true);
      if (e.data?.type === '__deactivate_edit_mode') setTweaksOpen(false);
    };
    window.addEventListener('message', handler);
    window.parent.postMessage({type:'__edit_mode_available'}, '*');
    return () => window.removeEventListener('message', handler);
  }, []);

  const persistTweak = (key, val) => {
    window.parent.postMessage({type:'__edit_mode_set_keys', edits:{[key]: val}}, '*');
  };

  // GUT-49 — fetch list of sections hidden by APP_ENV (prod gate).
  const [hiddenSections, setHiddenSections] = React.useState([]);
  React.useEffect(() => {
    let cancelled = false;
    fetch('/api/config/visibility')
      .then(r => r.ok ? r.json() : { hiddenSections: [] })
      .then(d => { if (!cancelled) setHiddenSections(d.hiddenSections || []); })
      .catch(() => { /* dev fallback: nothing hidden */ });
    return () => { cancelled = true; };
  }, []);
  const isHidden = React.useCallback(
    (key) => hiddenSections.includes(key),
    [hiddenSections]
  );

  // Permission check — hide views user can't access.
  // RBAC (B3): se usan los permisos EFECTIVOS del nuevo modelo (rol_id +
  // rol_permisos, unidos a los legacy) que devuelve el login/whoami. Si una
  // sesión antigua aún no los tiene, se cae al array legacy `permisos`.
  const isAdmin = user.rol === 'admin';
  const eff = (Array.isArray(user.permisosEfectivos) && user.permisosEfectivos.length)
    ? user.permisosEfectivos
    : (user.permisos || ['leads']);
  const has = (m) => isAdmin || eff.includes('*') || eff.includes(m);
  const can = {
    leads:        has('leads')        && !isHidden('leads'),
    // "compras" agrupa operaciones: lo habilita cualquier módulo de operaciones.
    compras:      (has('compras') || has('expedientes') || has('ordenes') || has('produccion')) && !isHidden('compras'),
    partes:       has('partes')       && !isHidden('partes'),
    configurador: has('configurador') && !isHidden('configurador'),
    tareas:       isAdmin && !isHidden('tareas'),
    misTareas:    !isHidden('mis-tareas'),
    sistema:      isAdmin && !isHidden('sistema'),
    ordenes:      (has('ordenes') || has('compras'))    && !isHidden('ordenes'),
    produccion:   (has('produccion') || has('compras')) && !isHidden('produccion'),
    presupuestos: (has('presupuestos') || has('configurador')) && !isHidden('presupuestos'),
    catalogo:     has('catalogo') && !isHidden('catalogo'),
    catalogoProductos: has('configurador') && !isHidden('catalogo-productos'),
    expedientes:  (has('expedientes') || has('compras')) && !isHidden('expedientes'),
  };

  // Redirect away from forbidden view
  React.useEffect(() => {
    // La vista Pedidos legacy se consolidó en Expedientes.
    if (view === 'compras') { setView('expedientes'); return; }
    const blocked = (
      !crumbsMap[view] ||
      (view === 'leads' && !can.leads) ||
      (view === 'ordenes' && (!can.compras || !can.ordenes)) ||
      (view === 'expedientes' && (!can.compras || !can.expedientes)) ||
      (view === 'produccion' && (!can.compras || !can.produccion)) ||
      (view === 'partes' && !can.partes) ||
      (view === 'presupuestos' && !can.presupuestos) ||
      (view === 'configurador' && !can.configurador) ||
      (view === 'tareas' && !can.tareas) ||
      (view === 'mis-tareas' && !can.misTareas) ||
      (view === 'catalogo' && !can.catalogo) ||
      (view === 'catalogo-productos' && !can.catalogoProductos) ||
      (view === 'sistema' && !can.sistema)
    );
    if (blocked) setView('dashboard');
  }, [view, user]);

  const counts = {
    leads:      window.DATA.LEADS.length,
    ordenes:    window.DATA.ORDENES_COMPRA.length,
    partesLive: window.DATA.PARTES_LIVE.length,
  };

  const crumbsMap = {
    dashboard:    ['ERPkurten', 'Dashboard'],
    leads:        ['ERPkurten', 'Comercial', 'Leads'],
    expedientes:  ['ERPkurten', 'Operaciones', 'Expedientes'],
    ordenes:      ['ERPkurten', 'Operaciones', 'Órdenes a proveedor'],
    produccion:   ['ERPkurten', 'Operaciones', 'Producción'],
    partes:       ['ERPkurten', 'Operaciones', 'Partes de trabajo'],
    presupuestos: ['ERPkurten', 'Comercial', 'Presupuestos'],
    configurador: ['ERPkurten', 'Comercial', 'Configurador'],
    tareas:       ['ERPkurten', 'Operaciones', 'Tareas'],
    'mis-tareas': ['ERPkurten', 'Operaciones', 'Mis tareas'],
    catalogo:     ['ERPkurten', 'Operaciones', 'Catálogo de artículos'],
    'catalogo-productos': ['ERPkurten', 'Comercial', 'Catálogo de productos'],
    sistema:      ['ERPkurten', 'Sistema'],
  };

  return (
    <div className="app">
      <Sidebar
        active={view}
        onNav={setView}
        counts={counts}
        user={user}
        can={can}
        onLogout={onLogout}
        onChangePassword={()=>setChpwdOpen(true)}
        onMcpToken={()=>setMcpTokenOpen(true)}
      />
      <div className="main">
        <Topbar crumbs={crumbsMap[view]} actions={null} />
        <div className="scroll" data-screen-label={`${view} screen`}>
          {view === 'dashboard'  && <Dashboard onNav={setView}/>}
          {view === 'leads'      && can.leads        && <LeadsView onOpen={setOpenLead} refreshKey={refreshKey} onRefresh={refresh} onToast={showToast}/>}
          {view === 'expedientes' && can.compras && can.expedientes && <ExpedientesView onToast={showToast} onNew={()=>setCompraFormMode('new')} onOpenPedido={setOpenCompra} refreshKey={refreshKey}/>}
          {view === 'ordenes'    && can.compras && can.ordenes    && <OrdenesView refreshKey={refreshKey} onToast={showToast}/>}
          {view === 'produccion' && can.compras && can.produccion && <ProduccionView onOpen={setOpenCompra} onToast={showToast}/>}
          {view === 'partes'     && can.partes       && <PartesView user={user} onToast={showToast}/>}
          {view === 'tareas'     && can.tareas       && <TareasView onToast={showToast}/>}
          {view === 'mis-tareas' && can.misTareas    && <MisTareasView onToast={showToast}/>}
          {view === 'catalogo'   && can.catalogo     && <CatalogoView onToast={showToast}/>}
          {view === 'catalogo-productos' && can.catalogoProductos && <CatalogoProductosView onToast={showToast}/>}
          {view === 'presupuestos' && can.presupuestos && <PresupuestosView onToast={showToast}/>}
          {view === 'configurador' && can.configurador && (
            <div style={{display:'flex',alignItems:'center',justifyContent:'center',minHeight:'60vh',padding:24}}>
              <div style={{maxWidth:520,textAlign:'center',background:'var(--surface,#fff)',border:'1px solid var(--line)',borderRadius:12,padding:'36px 32px'}}>
                <span style={{display:'inline-flex',alignItems:'center',gap:6,fontSize:11,fontWeight:600,letterSpacing:.5,textTransform:'uppercase',color:'var(--accent,#6c5ce7)',background:'var(--surface-2,#f4f3ff)',border:'1px solid var(--line)',borderRadius:999,padding:'4px 12px'}}>
                  <Icon name="sparkles" size={12}/> Próximamente
                </span>
                <div style={{margin:'18px 0 6px',display:'flex',justifyContent:'center',color:'var(--ink-3)'}}><Icon name="calc" size={40}/></div>
                <h2 style={{margin:'8px 0 12px',fontSize:20}}>Configurador de precios</h2>
                <p style={{fontSize:14,lineHeight:1.55,color:'var(--ink-2,#444)',margin:'0 0 12px'}}>
                  Aquí vivirá el <strong>cálculo automático de presupuestos</strong>: a partir de las medidas y opciones de cada producto, el sistema calculará materiales, costes y el precio de venta automáticamente, sin introducirlo a mano.
                </p>
                <p style={{fontSize:13,lineHeight:1.5,color:'var(--ink-3)',margin:0}}>
                  Mientras tanto, los presupuestos se hacen con precio manual desde el <strong>Catálogo de productos</strong>.
                </p>
              </div>
            </div>
          )}
          {view === 'sistema'      && can.sistema      && <SistemaView onToast={showToast}/>}
        </div>
      </div>

      <LeadDrawer
        lead={openLead}
        onClose={()=>setOpenLead(null)}
        onToast={showToast}
        onRefresh={refresh}
        onEdit={(id) => {
          setOpenLead(null);
          // Bump refreshKey so LeadsView re-renders with editId via global event
          window.dispatchEvent(new CustomEvent('erp:edit-lead', { detail: { id } }));
        }}
      />

      <ComprasDrawer
        pedido={openCompra}
        onClose={()=>setOpenCompra(null)}
        onToast={showToast}
        onEdit={(id) => { setOpenCompra(null); setCompraFormMode(id); }}
        onDeleted={() => { setOpenCompra(null); refresh(); }}
      />

      {compraFormMode != null && (
        <ComprasForm
          pedidoId={compraFormMode === 'new' ? undefined : compraFormMode}
          onClose={()=>setCompraFormMode(null)}
          onSaved={()=>{ refresh(); }}
          onToast={showToast}
        />
      )}

      {chpwdOpen && <ChangePasswordModal onClose={(ok)=>{ setChpwdOpen(false); if(ok) showToast('Contraseña actualizada ✓'); }}/>}
      {mcpTokenOpen && <McpTokenModal onClose={()=>setMcpTokenOpen(false)} onToast={showToast}/>}
      {toast && (
        <div className={'toast' + (toast.isErr ? ' toast--err' : '')}>
          <span className="toast-msg">{toast.msg}</span>
          {toast.isErr && (
            <button className="toast-close" onClick={() => setToast(null)} aria-label="Cerrar">×</button>
          )}
        </div>
      )}

      {tweaksOpen && (
        <div className="tweaks">
          <div className="h"><span className="dot"/>Tweaks</div>
          <div className="body">
            <div className="row">
              <label>Densidad</label>
              <div className="seg">
                <button className={density==='dense'?'on':''} onClick={()=>{setDensity('dense'); persistTweak('density','dense');}}>Densa</button>
                <button className={density==='default'?'on':''} onClick={()=>{setDensity('default'); persistTweak('density','default');}}>Media</button>
                <button className={density==='comfortable'?'on':''} onClick={()=>{setDensity('comfortable'); persistTweak('density','comfortable');}}>Amplia</button>
              </div>
            </div>
            <div className="row">
              <label>Acento</label>
              <div className="swatches">
                {Object.entries(ACCENT_PRESETS).map(([k,v]) => (
                  <span key={k} className={`sw ${accent===k?'on':''}`} style={{background:v['--accent']}}
                        onClick={()=>{setAccent(k); persistTweak('accent',k);}} />
                ))}
              </div>
            </div>
            <div className="row">
              <label>Vista inicial</label>
              <select value={view} onChange={e=>{setView(e.target.value); persistTweak('primaryView', e.target.value);}}
                style={{padding:'4px 8px',border:'1px solid var(--line)',borderRadius:4,background:'var(--surface)',fontSize:12}}>
                <option value="dashboard">Dashboard</option>
                <option value="leads">Leads</option>
                <option value="expedientes">Expedientes</option>
                <option value="ordenes">Órdenes</option>
                <option value="produccion">Producción</option>
                <option value="partes">Partes</option>
              </select>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
