function App() {
  const [user, setUser]           = React.useState(null);
  const [checking, setChecking]   = React.useState(true);
  const [route, setRoute]         = React.useState('dashboard');
  const [collapsed, setCollapsed] = React.useState(false);
  const fromRectRef     = React.useRef(null);
  const sidebarBrandRef = React.useRef(null);

  React.useEffect(() => {
    fetch(`${API_BASE}/api/auth/me`, { credentials: 'include' })
      .then(r => r.ok ? r.json() : null)
      .then(data => { if (data?.user) setUser(data.user); })
      .finally(() => setChecking(false));
  }, []);

  React.useEffect(() => {
    const saved = localStorage.getItem('lanven.route');
    if (saved) setRoute(saved);
  }, []);
  React.useEffect(() => { localStorage.setItem('lanven.route', route); }, [route]);

  React.useLayoutEffect(() => {
    if (!user || !fromRectRef.current) return;
    const fromRect = fromRectRef.current;
    fromRectRef.current = null;
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    const dest = sidebarBrandRef.current;
    if (!dest) return;
    const to = dest.getBoundingClientRect();
    const fly = document.createElement('span');
    fly.textContent = 'LANVEN';
    fly.style.cssText = [
      'position:fixed',
      'left:' + to.left + 'px',
      'top:' + to.top + 'px',
      'font-family:"Cormorant Garamond",serif',
      'font-weight:500',
      'font-size:26px',
      'line-height:1',
      'letter-spacing:0.02em',
      'color:#ffffff',
      'pointer-events:none',
      'z-index:100',
      'transform-origin:left top',
      'will-change:transform,color',
    ].join(';');
    document.body.appendChild(fly);
    dest.style.opacity = '0';
    const dx = fromRect.left - to.left;
    const dy = fromRect.top  - to.top;
    const sc = fromRect.width / to.width;
    fly.style.transition = 'none';
    fly.style.transform  = 'translate(' + dx + 'px,' + dy + 'px) scale(' + sc + ')';
    fly.style.color      = '#1F2A33';
    requestAnimationFrame(() => {
      requestAnimationFrame(() => {
        fly.style.transition = 'transform 0.85s cubic-bezier(.2,.8,.2,1), color 0.85s ease';
        fly.style.transform  = 'translate(0,0) scale(1)';
        fly.style.color      = '#ffffff';
        const cleanup = () => {
          if (sidebarBrandRef.current) sidebarBrandRef.current.style.opacity = '';
          fly.remove();
        };
        fly.addEventListener('transitionend', function handler(e) {
          if (e.propertyName === 'transform') { fly.removeEventListener('transitionend', handler); cleanup(); }
        });
        setTimeout(cleanup, 1200);
      });
    });
  }, [user]);

  async function handleLogout() {
    await fetch(`${API_BASE}/api/auth/logout`, { method: 'POST', credentials: 'include' });
    setUser(null);
  }

  if (checking) return (
    <div className="min-h-screen bg-canvas flex items-center justify-center text-slate-400 text-[13px]">
      Cargando...
    </div>
  );

  if (!user) return <LoginPage onLogin={(userData, fromRect) => { fromRectRef.current = fromRect; setUser(userData); }} />;

  const ROL_MAP = { ADMIN: 'admin', GERENCIA: 'admin', TEAM_LEADER: 'team_leader', BROKER: 'broker', MARKETING: 'marketing' };
  const userFront = { ...user, rol: ROL_MAP[user.rol] || 'broker', rawRol: user.rol };
  window.CURRENT_USER = userFront;

  const PAGES = {
    'dashboard':          Dashboard,
    'operaciones':        Operaciones,
    'propiedades':        Propiedades,
    'leads':              Leads,
    'rankings':           Rankings,
    'ingresos':           Ingresos,
    'gastos':             Gastos,
    'cajas':              Cajas,
    'movimientos':        Movimientos,
    'reservas':           Reservas,
    'finanzas-dashboard': FinanzasDashboard,
    'sueldos':            Sueldos,
    'usuarios':           Usuarios,
  };
  const Page = PAGES[route] || Dashboard;

  return (
    <div className="flex min-h-screen bg-canvas">
      <Sidebar route={route} setRoute={setRoute} collapsed={collapsed} setCollapsed={setCollapsed} user={userFront} sidebarBrandRef={sidebarBrandRef} />
      <div className="flex-1 min-w-0 flex flex-col">
        <Topbar user={userFront} onLogout={handleLogout} />
        <main className="lv-content-enter flex-1 px-10 py-8 max-w-[1440px] w-full">
          <div key={route + userFront.email}>
            {canSeeRoute(userFront, route) ? <Page /> : <NoAccess user={userFront} />}
          </div>
        </main>
        <footer className="px-10 py-5 border-t border-slate-100 text-[11px] text-slate-400 flex items-center justify-between">
          <div className="flex items-center gap-3">
            <LVNMark size={20} dark />
            <span>Lanven · Sistema de gestión interna · v0.2</span>
          </div>
          <div className="font-mono">build 2026.05.23</div>
        </footer>
      </div>
    </div>
  );
}

function NoAccess({ user }) {
  const rol = ROLES[user.rol];
  return (
    <div className="fade-in py-20 flex flex-col items-center text-center max-w-[480px] mx-auto">
      <div className="w-14 h-14 rounded-full bg-slate-50 border border-slate-200 flex items-center justify-center mb-5">
        <I.Lock size={20} className="text-slate-400" />
      </div>
      <h2 className="font-serif text-[28px] text-ink leading-tight">Sección no habilitada</h2>
      <p className="text-[13px] text-slate-500 mt-3 leading-relaxed">
        Tu rol <b style={{ color: rol?.badge }}>{rol?.label}</b> no incluye acceso a esta vista.
      </p>
      <div className="mt-6 text-[11px] text-slate-400 font-mono">{user.email}</div>
    </div>
  );
}

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