/* ============================================================
   App shell — Router, AuthStore, layout primitives
   Globals: useHashRoute, useAuth, NavBar, TopBar, Footer, Page
   ============================================================ */
const { useState, useEffect, useMemo, useRef, useCallback, createContext, useContext } = React;

/* ---------------- Hash router ---------------- */
function parseHash() {
  const raw = (location.hash || '#/').replace(/^#/, '');
  const [path, query] = raw.split('?');
  const params = {};
  if (query) {
    query.split('&').forEach(kv => {
      const [k, v] = kv.split('=');
      params[decodeURIComponent(k)] = v == null ? '' : decodeURIComponent(v);
    });
  }
  return { path: path || '/', params };
}

function useHashRoute() {
  const [route, setRoute] = useState(parseHash());
  useEffect(() => {
    const on = () => setRoute(parseHash());
    window.addEventListener('hashchange', on);
    return () => window.removeEventListener('hashchange', on);
  }, []);
  return route;
}

function nav(path) {
  if (path.startsWith('#')) {
    location.hash = path;
  } else {
    location.hash = '#' + path;
  }
}

function Link({ to, children, className, onClick, ...rest }) {
  return (
    <a
      href={'#' + to}
      className={className}
      onClick={(e) => {
        if (onClick) onClick(e);
      }}
      {...rest}
    >
      {children}
    </a>
  );
}

/* ---------------- Auth store ---------------- */
const AuthCtx = createContext(null);

function useAuthStore() {
  const [users, setUsers] = useState(() => {
    try { return JSON.parse(localStorage.getItem('ibd:users') || '[]'); } catch { return []; }
  });
  const [session, setSession] = useState(() => {
    try { return JSON.parse(localStorage.getItem('ibd:session') || 'null'); } catch { return null; }
  });

  const persistUsers = (next) => {
    setUsers(next);
    localStorage.setItem('ibd:users', JSON.stringify(next));
  };
  const persistSession = (s) => {
    setSession(s);
    if (s) localStorage.setItem('ibd:session', JSON.stringify(s));
    else localStorage.removeItem('ibd:session');
  };

  const signup = (data) => {
    const exists = users.find(u => u.email.toLowerCase() === data.email.toLowerCase());
    if (exists) return { ok: false, error: 'Já existe uma conta com este e-mail.' };
    const user = {
      id: 'u_' + Date.now().toString(36),
      name: data.name,
      email: data.email,
      phone: data.phone,
      createdAt: new Date().toISOString(),
      progress: {},
      bookmarks: []
    };
    persistUsers([...users, user]);
    persistSession({ userId: user.id, since: Date.now() });
    return { ok: true, user };
  };

  const login = (email, _password) => {
    const user = users.find(u => u.email.toLowerCase() === email.toLowerCase());
    if (!user) return { ok: false, error: 'Não encontramos uma conta com este e-mail.' };
    persistSession({ userId: user.id, since: Date.now() });
    return { ok: true, user };
  };

  const logout = () => persistSession(null);

  const currentUser = useMemo(() => {
    if (!session) return null;
    return users.find(u => u.id === session.userId) || null;
  }, [session, users]);

  const updateUser = (patch) => {
    if (!currentUser) return;
    const next = users.map(u => u.id === currentUser.id ? { ...u, ...patch } : u);
    persistUsers(next);
  };

  return { users, currentUser, signup, login, logout, updateUser };
}

function AuthProvider({ children }) {
  const store = useAuthStore();
  return <AuthCtx.Provider value={store}>{children}</AuthCtx.Provider>;
}
function useAuth() { return useContext(AuthCtx); }

/* ---------------- Brand mark ---------------- */
function BrandMark({ variant = 'navbar' }) {
  if (variant === 'large') {
    return (
      <Link to="/" className="brand brand-large" aria-label="IBD — Instituto Brasileiro de Derivativos · derivativos.org">
        <img src="assets/logo-lockup-dark.png" alt="Instituto Brasileiro de Derivativos" className="brand-img" />
      </Link>
    );
  }
  if (variant === 'large-light') {
    return (
      <Link to="/" className="brand brand-large" aria-label="IBD — Instituto Brasileiro de Derivativos · derivativos.org">
        <img src="assets/logo-lockup.png" alt="Instituto Brasileiro de Derivativos" className="brand-img" />
      </Link>
    );
  }
  // navbar — mark + lockup text alongside
  return (
    <Link to="/" className="brand" aria-label="IBD — Instituto Brasileiro de Derivativos · derivativos.org">
      <img src="assets/logo-mark.png" alt="" className="brand-mark-img" />
      <div className="brand-name">
        <strong>Instituto Brasileiro</strong>
        <strong>de Derivativos</strong>
      </div>
    </Link>
  );
}

/* ---------------- TopBar ---------------- */
function TopBar() {
  return (
    <div className="topbar">
      <div className="container topbar-inner">
        <div className="mono">IBD · Fundação Educativa · CNPJ em constituição</div>
        <div className="topbar-links">
          <a href="#/sobre">Sobre</a>
          <a href="#/biblioteca?cat=imprensa">Imprensa</a>
          <a href="#/biblioteca?cat=pesquisa">Pesquisa</a>
          <span style={{opacity: 0.5}}>·</span>
          <span style={{opacity: 0.85}}>PT-BR</span>
        </div>
      </div>
    </div>
  );
}

/* ---------------- NavBar + submenus + gating + placeholder ---------------- */

// Tabela de menus. children[].premium=true marca itens exclusivos a membros — clique
// quando deslogado desvia para /login?next=<destino>.
const NAV_ITEMS = [
  {
    to: '/biblioteca',
    label: 'Biblioteca',
    children: [
      { to: '/biblioteca', label: 'Visão geral', desc: 'Todo o acervo, sem filtro' },
      { to: '/biblioteca?tema=Fundamentos', label: 'Fundamentos' },
      { to: '/biblioteca?tema=' + encodeURIComponent('Opções'), label: 'Opções' },
      { to: '/biblioteca?tema=' + encodeURIComponent('Câmbio'), label: 'Câmbio' },
      { to: '/biblioteca?tema=Juros', label: 'Juros' },
      { to: '/biblioteca?tema=' + encodeURIComponent('Agropecuário'), label: 'Agropecuário' },
      { to: '/biblioteca?tema=Modelagem', label: 'Quant & modelagem' },
    ],
  },
  {
    to: '/biblioteca?tipo=Aula',
    label: 'Vídeo-aulas',
    children: [
      { to: '/biblioteca?tipo=Aula', label: 'Todas as aulas', desc: 'Catálogo de vídeos' },
      { to: '/aula/intro-derivativos', label: 'Trilha introdutória', desc: 'Fundamentos em 8 aulas' },
      { type: 'separator' },
      { to: '/membros/cursos', label: 'Cursos completos', desc: 'Em desenvolvimento', premium: true },
    ],
  },
  {
    to: '/ferramentas/black-scholes',
    label: 'Ferramentas',
    children: [
      { to: '/ferramentas/black-scholes', label: 'Calculadora Black-Scholes', desc: 'Prêmio e gregas de opções europeias' },
      { to: '/ferramentas/payoff', label: 'Diagrama de Payoff', desc: 'Estratégias multi-pernas' },
      { to: '/ferramentas/futuros', label: 'Simulador de Futuros', desc: 'Mark-to-market e chamadas de margem' },
      { type: 'separator' },
      { to: '/ferramentas/backtest', label: 'Backtest de Estratégias', desc: 'Em desenvolvimento', premium: true },
      { to: '/ferramentas/var', label: 'Calculadora de VaR', desc: 'Em desenvolvimento', premium: true },
    ],
  },
  {
    to: '/post/o-que-sao-derivativos',
    label: 'Conceitos',
    children: [
      { to: '/post/o-que-sao-derivativos', label: 'O que são derivativos' },
      { to: '/biblioteca?nivel=Iniciante', label: 'Para iniciantes', desc: 'Curadoria de leituras' },
      { to: '/conceitos/glossario', label: 'Glossário', desc: 'Em desenvolvimento' },
      { type: 'separator' },
      { to: '/conceitos/quizzes', label: 'Quizzes interativos', desc: 'Em desenvolvimento', premium: true },
    ],
  },
  {
    to: '/sobre',
    label: 'Sobre o IBD',
    children: [
      { to: '/sobre', label: 'Missão e princípios' },
      { to: '/biblioteca?cat=pesquisa', label: 'Pesquisa aplicada' },
      { to: '/biblioteca?cat=imprensa', label: 'Imprensa' },
      { to: '/cadastro', label: 'Apoiar o Instituto', desc: 'Cadastre-se gratuitamente' },
    ],
  },
];

function NavBar() {
  const { currentUser, logout } = useAuth();
  return (
    <nav className="nav">
      <div className="container nav-inner">
        <BrandMark />
        <div className="nav-links">
          {NAV_ITEMS.map(item => (
            <NavMenuItem key={item.label} item={item} />
          ))}
        </div>
        <div className="nav-cta">
          {currentUser ? (
            <>
              <Link to="/dashboard" className="btn btn-ghost btn-sm">
                {currentUser.name.split(' ')[0]}
              </Link>
              <button className="btn-text" onClick={() => { logout(); nav('/'); }}>Sair</button>
            </>
          ) : (
            <>
              <Link to="/login" className="btn-text">Entrar</Link>
              <Link to="/cadastro" className="btn btn-sm">Criar conta</Link>
            </>
          )}
        </div>
      </div>
    </nav>
  );
}

function NavMenuItem({ item }) {
  const { path } = useHashRoute();
  const [open, setOpen] = useState(false);
  const closeTimer = useRef(null);
  const hasChildren = !!(item.children && item.children.length);

  const onEnter = () => {
    if (closeTimer.current) clearTimeout(closeTimer.current);
    setOpen(true);
  };
  const onLeave = () => {
    closeTimer.current = setTimeout(() => setOpen(false), 200);
  };

  const baseOf = (p) => (p || '').split('?')[0].split('#')[0];
  const currentBase = baseOf(path);
  const itemBase = baseOf(item.to);
  const isActive =
    currentBase === itemBase ||
    (itemBase !== '/' && itemBase !== '' && currentBase.startsWith(itemBase)) ||
    (hasChildren && item.children.some(c => c.to && baseOf(c.to) === currentBase));

  const parentLink = (
    <GatedLink
      to={item.to}
      premium={item.premium}
      className={isActive ? 'active' : ''}
      aria-haspopup={hasChildren ? 'true' : undefined}
      aria-expanded={hasChildren ? open : undefined}
    >
      {item.label}
      {hasChildren && <span className="nav-caret" aria-hidden="true">▾</span>}
    </GatedLink>
  );

  if (!hasChildren) return parentLink;

  return (
    <div className="nav-menu-item" onMouseEnter={onEnter} onMouseLeave={onLeave}>
      {parentLink}
      {open && (
        <div className="nav-dropdown" role="menu">
          {item.children.map((child, idx) => {
            if (child.type === 'separator') {
              return <hr key={'sep' + idx} className="nav-dropdown-sep" />;
            }
            return (
              <GatedLink
                key={child.to + '-' + idx}
                to={child.to}
                premium={child.premium}
                className="nav-dropdown-link"
                role="menuitem"
              >
                <span className="nav-dropdown-label">
                  {child.label}
                  {child.premium && <span className="premium-badge">Membros</span>}
                </span>
                {child.desc && <span className="nav-dropdown-desc">{child.desc}</span>}
              </GatedLink>
            );
          })}
        </div>
      )}
    </div>
  );
}

// Link que intercepta cliques em destinos marcados como premium. Se o usuário
// não estiver logado, desvia para /login?next=<destino-original>.
function GatedLink({ to, premium, className, children, onClick, ...rest }) {
  const auth = useAuth();
  const currentUser = auth ? auth.currentUser : null;
  const handleClick = (e) => {
    if (premium && !currentUser) {
      e.preventDefault();
      nav('/login?next=' + encodeURIComponent(to));
    }
    if (onClick) onClick(e);
  };
  return (
    <a href={'#' + to} className={className} onClick={handleClick} {...rest}>
      {children}
    </a>
  );
}

// Página reutilizável "Em desenvolvimento" — usada por rotas de ferramentas
// e conteúdos ainda não construídos. Quando combinada com GatedLink premium,
// só usuários logados conseguem chegar aqui.
function ComingSoonPage({ title, eta, description, kind }) {
  return (
    <Page>
      <section className="coming-soon-stage">
        <div className="container">
          <div className="coming-soon-card">
            <div className="eyebrow eyebrow-accent">Em desenvolvimento</div>
            <h1>{title}</h1>
            <p style={{color: 'var(--fg-muted)', fontSize: 15, lineHeight: 1.65, maxWidth: '54ch', margin: '0 auto'}}>
              {description}
            </p>
            <div className="coming-soon-meta">
              {kind && <span>{kind}</span>}
              {eta && <span>Previsão {eta}</span>}
              <span>Sem custo</span>
            </div>
            <Link to="/dashboard" className="btn btn-ghost" style={{marginTop: 'var(--s-5)'}}>
              Voltar ao painel <span className="icon-arrow"></span>
            </Link>
          </div>
        </div>
      </section>
    </Page>
  );
}

/* ---------------- Footer ---------------- */
function Footer() {
  return (
    <footer className="footer">
      <div className="container">
        <div className="footer-grid">
          <div>
            <img src="assets/logo-lockup-dark.png" alt="Instituto Brasileiro de Derivativos" className="footer-logo" />
            <p className="footer-mission">
              O Instituto Brasileiro de Derivativos é uma iniciativa educativa, sem fins lucrativos,
              dedicada à formação técnica em mercados derivativos no Brasil — financeiros, agropecuários,
              de commodities, energia e clima.
            </p>
          </div>
          <div>
            <h4>Aprenda</h4>
            <ul>
              <li><a href="#/biblioteca">Biblioteca</a></li>
              <li><a href="#/aula/intro-derivativos">Vídeo-aulas</a></li>
              <li><a href="#/post/o-que-sao-derivativos">Conceitos</a></li>
              <li><a href="#/biblioteca?cat=trilhas">Trilhas</a></li>
            </ul>
          </div>
          <div>
            <h4>Ferramentas</h4>
            <ul>
              <li><a href="#/ferramentas/black-scholes">Black-Scholes</a></li>
              <li><a href="#/ferramentas/payoff">Payoff de estratégias</a></li>
              <li><a href="#/ferramentas/futuros">Simulador de futuros</a></li>
            </ul>
          </div>
          <div>
            <h4>Instituto</h4>
            <ul>
              <li><a href="#/sobre">Sobre o IBD</a></li>
              <li><a href="#/biblioteca?cat=pesquisa">Pesquisa aplicada</a></li>
              <li><a href="#/biblioteca?cat=imprensa">Imprensa</a></li>
              <li><a href="#/cadastro">Apoiar / Cadastrar</a></li>
            </ul>
          </div>
        </div>
        <div className="footer-bottom">
          <span>© 2026 IBD · Conteúdo educativo · Não é recomendação de investimento</span>
          <span>v.0.1 · São Paulo / Brasil</span>
        </div>
      </div>
    </footer>
  );
}

/* ---------------- Generic page ---------------- */
function Page({ children, fullBleed }) {
  return (
    <>
      <TopBar />
      <NavBar />
      <main className={fullBleed ? '' : 'page-body'}>
        {children}
      </main>
      <Footer />
    </>
  );
}

/* ---------------- Phone mask ---------------- */
function maskPhoneBR(v) {
  const d = (v || '').replace(/\D/g, '').slice(0, 11);
  if (d.length === 0) return '';
  if (d.length <= 2) return '(' + d;
  if (d.length <= 7) return '(' + d.slice(0, 2) + ') ' + d.slice(2);
  return '(' + d.slice(0, 2) + ') ' + d.slice(2, 7) + '-' + d.slice(7);
}
function isValidPhoneBR(v) {
  const d = (v || '').replace(/\D/g, '');
  return d.length === 11; // (DD) 9NNNN-NNNN
}
function isValidEmail(v) {
  return /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(v || '');
}
function isValidFullName(v) {
  const trimmed = (v || '').trim();
  if (trimmed.length < 4) return false;
  return /\s/.test(trimmed); // at least one space (first + last)
}

/* expose */
Object.assign(window, {
  useHashRoute, nav, Link, GatedLink,
  AuthProvider, useAuth,
  TopBar, NavBar, NavMenuItem, Footer, Page, BrandMark, ComingSoonPage,
  maskPhoneBR, isValidPhoneBR, isValidEmail, isValidFullName
});
