// Life Memory Tree — responsive app shell + router.
//
// This is the real product shell: it fills the browser window and switches
// between the desktop (sidebar) and mobile (bottom-bar + drawer) chrome based
// on the ACTUAL viewport width. The design-studio scaffolding (device frame,
// Mobile/Desktop/App viewport switcher, Tweaks panel) has been removed — the
// app responds to the real screen instead of a simulated one.
(function () {
const { useState, useEffect, useRef, useCallback } = React;
const { cx } = LMTXUtil;
const I = window.LMTIcons;

// Tunable defaults (formerly driven by the Tweaks panel). Dark mode is still
// toggled live from the top bar; the rest are fixed product defaults.
const TWEAK_DEFAULTS = {
  "dark": false,
  "accent": "evergreen",
  "sidebar": "rich",
  "motion": "full",
  "density": "comfortable",
  "weaveExample": "cand_snow"
};

// Below this width we render the mobile chrome (top bar + bottom tab bar +
// drawer); at or above it, the desktop sidebar layout.
const MOBILE_MAX = 768;

function useIsMobile() {
  const [mobile, setMobile] = useState(
    () => (typeof window !== 'undefined' ? window.innerWidth <= MOBILE_MAX : false)
  );
  useEffect(() => {
    const onResize = () => setMobile(window.innerWidth <= MOBILE_MAX);
    onResize();
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);
  return mobile;
}

// accent → css var overrides
function accentVars(name, dark) {
  const a = (LMTX.ACCENTS[name] || LMTX.ACCENTS.evergreen);
  const hex = dark ? a.soft : a.solid;
  const h = hex.replace('#',''); const r=parseInt(h.slice(0,2),16),g=parseInt(h.slice(2,4),16),b=parseInt(h.slice(4,6),16);
  return {
    '--accent': hex,
    '--accent-soft': a.soft,
    '--accent-fg': dark ? '#04140b' : '#ffffff',
    '--accent-wash': `rgba(${r},${g},${b},${dark?0.20:0.13})`,
    '--accent-line': `rgba(${r},${g},${b},${dark?0.40:0.30})`,
  };
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [route, setRoute] = useState('weaver');
  const [cmd, setCmd] = useState(false);
  const [drawer, setDrawer] = useState(false);
  const [animReady, setAnimReady] = useState(false);
  const mainRef = useRef(null);
  const isMobile = useIsMobile();

  // Let entrance animations play, then force a stable visible end-state so a
  // frozen/paused animation engine can never leave content invisible.
  useEffect(() => {
    setAnimReady(false);
    const id = setTimeout(() => setAnimReady(true), 1000);
    return () => clearTimeout(id);
  }, [route, isMobile, t.motion]);

  // Close the mobile drawer when growing back to desktop.
  useEffect(() => { if (!isMobile) setDrawer(false); }, [isMobile]);

  const dark = !!t.dark;
  const go = useCallback((r) => { setRoute(r); setDrawer(false); requestAnimationFrame(() => { if (mainRef.current) mainRef.current.scrollTop = 0; }); }, []);

  // ⌘K
  useEffect(() => {
    const h = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') { e.preventDefault(); setCmd(c => !c); }
      if (e.key === 'Escape') { setCmd(false); setDrawer(false); }
    };
    window.addEventListener('keydown', h); return () => window.removeEventListener('keydown', h);
  }, []);

  // Full-viewport root. .lmtx paints background:var(--bg) and resolves the
  // theme/density/motion/accent tokens for everything inside.
  const rootStyle = {
    ...accentVars(t.accent, dark),
    '--mo': t.motion === 'calm' ? 0.6 : 1,
    position: 'fixed', inset: 0, width: '100%', height: '100%',
    overflow: 'hidden', background: 'var(--bg)',
  };
  const rootProps = {
    className: cx('lmtx', animReady && 'anim-ready'),
    'data-theme': dark ? 'dark' : 'light',
    'data-density': t.density === 'compact' ? 'compact' : 'comfortable',
    'data-motion': t.motion === 'off' ? 'off' : 'on',
    style: rootStyle,
  };

  const pageEl = renderPage(route, go, { dark, setDark: (v) => setTweak('dark', v), weave: t.weaveExample });

  // ── Auth is full-screen (no chrome) ──
  if (route === 'auth') {
    return (
      <div {...rootProps}>
        <PageAuth go={go}/>
      </div>
    );
  }

  if (isMobile) {
    return (
      <div {...rootProps} style={{ ...rootStyle, display:'flex', flexDirection:'column' }}>
        <TopBar compact route={route} go={go} onCmd={() => setCmd(true)} dark={dark} setDark={v => setTweak('dark', v)} onCapture={() => go('capture')} onMenu={() => setDrawer(true)}/>
        <main ref={mainRef} className="app-main scroll" style={{ flex:1, overflowY:'auto', overflowX:'hidden', position:'relative' }}>
          <div key={route} className="route-anim">{pageEl}</div>
        </main>
        <MobileBar route={route} go={go} onCapture={() => go('capture')}/>
        <MobileDrawer open={drawer} route={route} go={go} onClose={() => setDrawer(false)} dark={dark} setDark={v => setTweak('dark', v)}/>
        <CommandPalette open={cmd} onClose={() => setCmd(false)} go={go}/>
      </div>
    );
  }

  return (
    <div {...rootProps} style={{ ...rootStyle, display:'flex' }}>
      <Sidebar variant={t.sidebar} route={route} go={go} onCapture={() => go('capture')} onCmd={() => setCmd(true)} echoCount={3}/>
      <div style={{ flex:1, minWidth:0, display:'flex', flexDirection:'column' }}>
        <TopBar route={route} go={go} onCmd={() => setCmd(true)} dark={dark} setDark={v => setTweak('dark', v)} onCapture={() => go('capture')}/>
        <main ref={mainRef} className="app-main scroll" style={{ flex:1, overflowY:'auto', overflowX:'hidden', position:'relative' }}>
          <div key={route} className="route-anim">{pageEl}</div>
        </main>
      </div>
      <CommandPalette open={cmd} onClose={() => setCmd(false)} go={go}/>
    </div>
  );
}

function renderPage(route, go, opts) {
  switch (route) {
    case 'today': return <PageToday go={go} onCapture={() => go('capture')}/>;
    case 'tree': return <PageTree go={go}/>;
    case 'graph': return <PageGraph go={go}/>;
    case 'timeline': return <PageTimeline go={go}/>;
    case 'scenes': return <PageScenes go={go}/>;
    case 'scene': return <PageScene go={go}/>;
    case 'people': return <PagePeople go={go}/>;
    case 'person': return <PagePerson go={go}/>;
    case 'places': return <PagePlaces go={go}/>;
    case 'place': return <PagePlace go={go}/>;
    case 'weaver': return <PageWeaver go={go} candidate={opts.weave}/>;
    case 'ask': return <PageAsk go={go}/>;
    case 'collab': return <PageCollab go={go}/>;
    case 'recap': return <PageRecap go={go}/>;
    case 'echoes': return <PageEchoes go={go}/>;
    case 'settings': return <PageSettings go={go} dark={opts.dark} setDark={opts.setDark}/>;
    case 'capture': return <PageCapture go={go}/>;
    default: return <PageToday go={go} onCapture={() => go('capture')}/>;
  }
}

window.LMTXApp = App;
})();
