/* App shell — hash router, nav, page transitions */

const ROUTES = [
  { path: '/',           id: 'home',       label: 'home',       comp: 'Hero' },
  { path: '/about',      id: 'about',      label: 'about',      comp: 'About' },
  { path: '/experience', id: 'experience', label: 'experience', comp: 'Experience' },
  { path: '/work',       id: 'work',       label: 'work',       comp: 'Projects' },
  { path: '/services',   id: 'services',   label: 'services',   comp: 'Services' },
  { path: '/contact',    id: 'contact',    label: 'contact',    comp: 'Contact' },
  { path: '/docs',       id: 'docs',       label: 'docs',       comp: 'Docs' },
  { path: '/swiftllm',   id: 'swiftllm',   label: 'swiftllm',   comp: 'SwiftLLM', hidden: true },
  { path: '/raybox',     id: 'raybox',     label: 'raybox',     comp: 'Raybox',   hidden: true },
  { path: '/inputmuxd',  id: 'inputmuxd',  label: 'inputmuxd',  comp: 'InputMuxd', hidden: true },
  { path: '__404__',     id: 'notfound',   label: '404',        comp: 'NotFound', hidden: true },
];

function useHashRoute() {
  const parse = () => {
    const h = window.location.hash.replace(/^#/, '') || '/';
    if (h === '/') return ROUTES[0];
    return ROUTES.find(r => r.path === h) || ROUTES.find(r => r.id === 'notfound');
  };
  const [route, setRoute] = React.useState(parse);
  React.useEffect(() => {
    const onHash = () => {
      setRoute(parse());
      window.scrollTo({ top: 0, behavior: 'instant' });
    };
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);
  return [route, setRoute];
}

function Nav({ activeId }) {
  const [lang, setLang] = window.useLang();
  return (
    <nav className="nav scrolled">
      <a href="#/" className="nav-logo">
        <span className="nav-logo-dot" />
        <span>abonnard.dev</span>
      </a>
      <div className="nav-links">
        {ROUTES.filter(r => r.id !== 'home' && !r.hidden).map(r => (
          <a key={r.id} href={`#${r.path}`} className={activeId === r.id ? 'active' : ''}>
            {window.t(`nav.${r.id}`)}
          </a>
        ))}
      </div>
      <button
        type="button"
        className="nav-lang"
        onClick={() => setLang(lang === 'en' ? 'fr' : 'en')}
        aria-label="Toggle language"
      >
        <span className={lang === 'en' ? 'on' : ''}>EN</span>
        <span className="sep">/</span>
        <span className={lang === 'fr' ? 'on' : ''}>FR</span>
      </button>
      <a href="#/contact" className="nav-cta">
        <span>{window.t('nav.letsTalk')}</span>
        <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M3 9L9 3M9 3H4M9 3V8" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></svg>
      </a>
    </nav>
  );
}

// Page breadcrumb — shows where you are + page N of M
function PageCrumb({ route }) {
  window.useLang();
  const visible = ROUTES.filter(r => !r.hidden);
  const idx = visible.findIndex(r => r.id === route.id);
  const prev = visible[(idx - 1 + visible.length) % visible.length];
  const next = visible[(idx + 1) % visible.length];
  const labelOf = (r) => r.id === 'home' ? r.label : window.t(`nav.${r.id}`);
  return (
    <div className="page-crumb">
      <a href={`#${prev.path}`} className="page-crumb-link prev">
        <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M7 2L3 6L7 10" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></svg>
        <span>{labelOf(prev)}</span>
      </a>
      <span className="page-crumb-meta">
        <span className="num">0{idx + 1}</span>
        <span className="bar" />
        <span className="total">0{visible.length}</span>
      </span>
      <a href={`#${next.path}`} className="page-crumb-link next">
        <span>{labelOf(next)}</span>
        <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M5 2L9 6L5 10" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></svg>
      </a>
    </div>
  );
}

function useReveal() {
  React.useEffect(() => {
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          e.target.classList.add('in');
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.08, rootMargin: '0px 0px -40px 0px' });
    const scan = () => {
      document.querySelectorAll('.reveal:not(.in)').forEach(el => io.observe(el));
    };
    scan();
    const mo = new MutationObserver(() => scan());
    mo.observe(document.body, { childList: true, subtree: true });
    const t1 = setTimeout(scan, 100);
    const t2 = setTimeout(scan, 400);
    return () => { io.disconnect(); mo.disconnect(); clearTimeout(t1); clearTimeout(t2); };
  }, []);
}

function App() {
  window.useLang();
  const [state, setState] = React.useState(() => ({ ...window.TWEAK_DEFAULTS }));
  const [tweaksVisible, setTweaksVisible] = React.useState(false);
  const [route] = useHashRoute();
  const [transitioning, setTransitioning] = React.useState(false);
  const [displayRoute, setDisplayRoute] = React.useState(route);

  // Page transition — fade out/in when route changes
  React.useEffect(() => {
    if (route.id === displayRoute.id) return;
    setTransitioning(true);
    const t = setTimeout(() => {
      setDisplayRoute(route);
      setTransitioning(false);
    }, 320);
    return () => clearTimeout(t);
  }, [route.id, displayRoute.id]);

  // apply theme
  React.useEffect(() => {
    document.documentElement.setAttribute('data-theme', state.theme);
    document.documentElement.setAttribute('data-accent', state.accent);
  }, [state.theme, state.accent]);

  useReveal();

  // tweaks host protocol
  React.useEffect(() => {
    const handler = (e) => {
      const d = e.data;
      if (!d || typeof d !== 'object') return;
      if (d.type === '__activate_edit_mode') setTweaksVisible(true);
      if (d.type === '__deactivate_edit_mode') setTweaksVisible(false);
    };
    window.addEventListener('message', handler);
    if (window.parent !== window) {
      window.parent.postMessage({ type: '__edit_mode_available' }, '*');
    }
    return () => window.removeEventListener('message', handler);
  }, []);

  const PageComp = window[displayRoute.comp];

  return (
    <>
      {state.particles && <window.Particles />}

      <Nav activeId={displayRoute.id} />

      <main className={`page-shell ${transitioning ? 'page-out' : 'page-in'}`} key={displayRoute.id}>
        <PageComp />
      </main>

      {!displayRoute.hidden && <PageCrumb route={displayRoute} />}

      <window.TweaksPanel state={state} setState={setState} visible={tweaksVisible} />
    </>
  );
}

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