// ============================================================
// APP — shell, nav rail, theme toggle, screen routing.
// ============================================================
const { useState: useStateA, useMemo: useMemoA, useEffect: useEffectA } = React;

function Rail({ route, setRoute, user, trades, onNew, onHome }) {
  const { Icon, useTheme, Btn, fmtUSD, t } = window.CJUI;
  const { theme, setTheme } = useTheme();
  const items = [
    { id: 'trades', label: t('nav.trades'), icon: 'ledger', key: 'B', hint: t('nav.tradesHint') },
    { id: 'analyse', label: t('nav.analyse'), icon: 'chart', key: 'A', hint: t('nav.analyseHint') },
    { id: 'settings', label: t('nav.settings'), icon: 'gear', key: 'S', hint: t('nav.settingsHint') },
  ];
  const todayStr = new Date(window.CJData.NOW).toDateString();
  const today = trades.filter((x) => new Date(x.ts).toDateString() === todayStr);
  const todayNet = today.reduce((s, t) => s + t.pnl, 0);
  const todayW = today.filter((t) => t.pnl > 0).length;

  return (
    <aside className="rail">
      <button className="brand" onClick={onHome} title="Back to homepage" style={{ background: 'none', border: 0, padding: '4px 8px 18px', font: 'inherit', color: 'inherit', textAlign: 'left', cursor: 'pointer', width: '100%' }}>
        <div className="brand-mark">C</div>
        <div>
          <div className="brand-name">Confluence</div>
          <div className="brand-sub">SCORE · {user.instrument.toUpperCase()}</div>
        </div>
      </button>

      <button className="rail-cta" onClick={onNew}>
        <Icon d="plus" size={16} /> {t('common.logTrade')}
      </button>

      <div className="rail-section">{t('rail.workspace')}</div>
      <nav className="nav">
        {items.map((it) => (
          <button key={it.id} className={'nav-item' + (route === it.id ? ' active' : '')} onClick={() => setRoute(it.id)}>
            <span className="nav-ico"><Icon d={it.icon} size={17} /></span>
            <span className="nav-label">
              {it.label}
              <span className="nav-hint">{it.hint}</span>
            </span>
          </button>
        ))}
      </nav>

      <div className="rail-today">
        <div className="rail-section" style={{ margin: '0 0 9px' }}>{t('rail.today')}</div>
        {today.length ? (
          <div className="today-card">
            <div className={'today-net mono ' + (todayNet >= 0 ? 'pos' : 'neg')}>{fmtUSD(todayNet)}</div>
            <div className="today-meta">
              <span>{today.length} {today.length === 1 ? t('common.trade') : t('common.trades')}</span>
              <span className="today-rec"><b className="pos">{todayW}W</b> · <b className="neg">{today.length - todayW}L</b></span>
            </div>
          </div>
        ) : (
          <div className="today-card empty-today">{t('rail.noToday')}</div>
        )}
      </div>

      <div className="rail-foot">
        <div className="theme-toggle">
          <button className={theme === 'light' ? 'on' : ''} onClick={() => setTheme('light')}><Icon d="sun" size={13} />{t('theme.light')}</button>
          <button className={theme === 'dark' ? 'on' : ''} onClick={() => setTheme('dark')}><Icon d="moon" size={13} />{t('theme.dark')}</button>
        </div>
        <window.CJUI.LangToggle />
        <div className="acct">
          <div className="acct-av">{(user.email || '?').replace(/@.*/, '').slice(0, 2).toUpperCase()}</div>
          <div className="acct-txt">
            <div className="acct-mail">{user.email}</div>
            <div className="acct-plan">{t('rail.member')}</div>
          </div>
        </div>
      </div>
    </aside>
  );
}

// Bottom tab bar for mobile (rail is hidden <=920px). CSS in mobile.css.
function MobileNav({ route, setRoute, onNew }) {
  const { Icon, useTheme, t } = window.CJUI;
  const { theme, setTheme } = useTheme();
  const tab = (id, icon, label) => (
    <button className={'mnav-item' + (route === id ? ' active' : '')} onClick={() => setRoute(id)}>
      <Icon d={icon} size={20} /><span>{label}</span>
    </button>
  );
  return (
    <nav className="mnav">
      {tab('trades', 'ledger', t('nav.trades'))}
      {tab('analyse', 'chart', t('nav.analyse'))}
      <button className="mnav-fab" onClick={onNew} aria-label={t('common.logTrade')}><Icon d="plus" size={22} /></button>
      {tab('settings', 'gear', t('nav.settings'))}
      <button className="mnav-item" onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')} aria-label={t('nav.theme')}>
        <Icon d={theme === 'dark' ? 'sun' : 'moon'} size={20} /><span>{t('nav.theme')}</span>
      </button>
    </nav>
  );
}

// Invite-only gate: shown to signed-in users whose profile.pro is not true.
function LockedScreen({ email, onLogout }) {
  const { Icon, Btn, t, LangToggle } = window.CJUI;
  return (
    <div className="locked">
      <div className="locked-card">
        <div className="brand-mark" style={{ width: 40, height: 40, fontSize: 20, margin: '0 auto' }}>C</div>
        <div className="kicker" style={{ marginTop: 16 }}>{t('lock.kicker')}</div>
        <h1>{t('lock.title')}</h1>
        <p>{t('lock.body', { email })}</p>
        <div className="locked-actions">
          <Btn kind="primary" iconR="arrowR" onClick={() => window.location.reload()}>{t('lock.refresh')}</Btn>
          <Btn kind="ghost" onClick={onLogout}>{t('common.logout')}</Btn>
        </div>
        <div style={{ marginTop: 18, display: 'flex', justifyContent: 'center' }}><LangToggle /></div>
      </div>
    </div>
  );
}

// ---- URL routing (History API; SPA fallback served by Cloudflare) ----
const ROUTE_TO_PATH = { trades: '/dashboard', analyse: '/analyse', settings: '/settings' };
const PATH_TO_ROUTE = { '/dashboard': 'trades', '/analyse': 'analyse', '/settings': 'settings' };
const AUTH_PATHS = { '/login': 'login', '/register': 'register' };
// classify a pathname → { kind: 'app'|'auth'|'home', route?, authView? }
function classifyPath(path) {
  if (path === '/reset') return { kind: 'reset' };
  if (PATH_TO_ROUTE[path]) return { kind: 'app', route: PATH_TO_ROUTE[path] };
  if (AUTH_PATHS[path]) return { kind: 'auth', authView: AUTH_PATHS[path] };
  return { kind: 'home' };
}

// Password-recovery screen (reached via the reset email link → /reset)
function ResetScreen() {
  const { Icon, Btn, t } = window.CJUI;
  const [pw, setPw] = useStateA('');
  const [err, setErr] = useStateA('');
  const [busy, setBusy] = useStateA(false);
  const [done, setDone] = useStateA(false);
  const submit = async (e) => {
    e.preventDefault();
    if (busy) return;
    if (pw.length < 6) { setErr(t('reset.placeholder')); return; }
    setErr(''); setBusy(true);
    const { error } = await window.CJSupa.updatePassword(pw);
    if (error) { setErr(error); setBusy(false); return; }
    setDone(true);
    setTimeout(() => { window.history.replaceState({}, '', '/dashboard'); window.dispatchEvent(new Event('popstate')); }, 1200);
  };
  return (
    <div className="auth"><main className="auth-main" style={{ gridColumn: '1 / -1' }}>
      <div className="auth-card">
        <div className="lnav-brand" style={{ marginBottom: 18 }}><div className="brand-mark">C</div><div className="brand-name">Confluence Score</div></div>
        <h1 className="auth-title">{t('reset.title')}</h1>
        <p className="auth-sub">{t('reset.sub')}</p>
        <form onSubmit={submit}>
          <div className="auth-field">
            <label>{t('reset.new')}</label>
            <input className="auth-input" type="password" value={pw} onChange={(e) => setPw(e.target.value)} placeholder={t('reset.placeholder')} autoComplete="new-password" autoFocus />
          </div>
          {err && <div className="auth-err">{err}</div>}
          {done && <div className="auth-info">{t('reset.done')}</div>}
          <Btn kind="primary" size="lg" type="submit" iconR="arrowR" style={{ width: '100%' }} disabled={busy || done}>{t('reset.save')}</Btn>
        </form>
      </div>
    </main></div>
  );
}

function App() {
  const { CONFLUENCES, USER } = window.CJData;
  const { t, useLang, useTheme } = window.CJUI;
  const lang = useLang();          // re-renders the whole app when language changes
  const { theme, setTheme } = useTheme();
  const prefsReady = React.useRef(false); // guards the load→save echo
  const CJSupa = window.CJSupa;
  const [trades, setTrades] = useStateA([]);
  const [user, setUser] = useStateA(USER);
  const [confluences, setConfluences] = useStateA(CONFLUENCES);
  const [logging, setLogging] = useStateA(false);
  const [detail, setDetail] = useStateA(null);
  const [sharing, setSharing] = useStateA(false);
  const [onboarding, setOnboarding] = useStateA(false);
  const [tradeView, setTradeView] = useStateA(() => localStorage.getItem('cj-view') || 'calendar');
  const setView = (v) => { setTradeView(v); localStorage.setItem('cj-view', v); };
  const [authed, setAuthed] = useStateA(false);
  const [booting, setBooting] = useStateA(true);

  // ---- routing: the URL path is the source of truth ----
  const [path, setPath] = useStateA(window.location.pathname);
  const view = classifyPath(path);                       // { kind: 'app'|'auth'|'home', route?, authView? }
  const route = view.kind === 'app' ? view.route : 'trades';
  const authView = view.kind === 'auth' ? view.authView : 'landing';
  const nav = (p, replace) => {
    if (window.location.pathname !== p) window.history[replace ? 'replaceState' : 'pushState']({}, '', p);
    setPath(p);
  };
  const setRoute = (r) => nav(ROUTE_TO_PATH[r] || '/dashboard');
  const setAuthView = (v) => nav(v === 'landing' ? '/' : '/' + v);

  // back/forward buttons → re-sync from the URL
  useEffectA(() => {
    const onPop = () => setPath(window.location.pathname);
    window.addEventListener('popstate', onPop);
    return () => window.removeEventListener('popstate', onPop);
  }, []);

  // ---- session: load profile + trades from Supabase, react to auth changes ----
  const applySession = async (session) => {
    if (!session) {
      setAuthed(false); setTrades([]); prefsReady.current = false;
      // logged out on a private route → back to the public home
      if (classifyPath(window.location.pathname).kind === 'app') nav('/', true);
      return;
    }
    setAuthed(true);
    // logged in but sitting on login/register → go to the dashboard.
    // The homepage ("/") is intentionally left alone so authed users can visit it.
    if (classifyPath(window.location.pathname).kind === 'auth') nav('/dashboard', true);
    const prof = await CJSupa.fetchProfile();
    const email = session.user.email;
    if (prof) {
      setUser((u) => ({ ...u, email, pro: !!prof.pro, instrument: prof.instrument, sessions: prof.sessions, minConfluences: prof.min_confluences }));
      if (Array.isArray(prof.confluences) && prof.confluences.length) setConfluences(prof.confluences);
      // apply saved UI prefs so the account picks up where it left off, on any device
      if (prof.theme) setTheme(prof.theme);
      if (prof.lang) window.CJI18n.set(prof.lang);
      if (prof.trade_view) { setTradeView(prof.trade_view); localStorage.setItem('cj-view', prof.trade_view); }
      // only run onboarding for members with access
      if (prof.pro && !prof.onboarded) { localStorage.removeItem('cj-onboarded'); setOnboarding(true); }
    } else {
      setUser((u) => ({ ...u, email, pro: false }));
    }
    setTrades(await CJSupa.fetchTrades());
    prefsReady.current = true; // future pref changes now persist
  };

  useEffectA(() => {
    // onAuthStateChange fires INITIAL_SESSION immediately. Defer the async
    // work off the callback to avoid the supabase-js deadlock warning.
    const unsub = CJSupa.onAuthChange((session) => {
      setTimeout(() => { applySession(session).finally(() => setBooting(false)); }, 0);
    });
    return unsub;
  }, []);

  // persist UI prefs (theme / language / view) to the profile after they change
  useEffectA(() => {
    if (!prefsReady.current) return;
    persistProfile({ theme, lang, trade_view: tradeView });
  }, [theme, lang, tradeView]);

  // keep nameOf() aware of the active confluence list (incl. custom ones)
  useEffectA(() => { window.CJData.setActiveConfluences(confluences); }, [confluences]);

  const logout = async () => {
    await CJSupa.signOut();
    setAuthed(false); setTrades([]); nav('/');
  };

  // persist a partial profile patch to Supabase (db column names)
  const persistProfile = (patch) => { CJSupa.upsertProfile(patch); };

  const finishOnboarding = async (cfg) => {
    if (cfg) {
      // carry the onboarding confluence picks (defaults + custom) into the live list
      const all = [...CONFLUENCES, ...(cfg.extra || [])];
      const picked = all.filter((c) => cfg.conf.includes(c.id));
      const nextConf = picked.length ? picked : CONFLUENCES;
      setConfluences(nextConf);
      setUser((u) => ({ ...u, instrument: cfg.instrument, sessions: cfg.sessions, minConfluences: cfg.threshold }));
      await CJSupa.upsertProfile({ instrument: cfg.instrument, sessions: cfg.sessions, min_confluences: cfg.threshold, confluences: nextConf, onboarded: true });
    } else {
      await CJSupa.upsertProfile({ onboarded: true });
    }
    localStorage.setItem('cj-onboarded', '1');
    setOnboarding(false);
  };

  const addTrade = async (t) => {
    const saved = await CJSupa.insertTrade({ ...t, ts: Date.now() });
    if (saved) setTrades((arr) => [saved, ...arr]);
    setLogging(false);
  };
  const deleteTrade = async (id) => {
    const ok = await CJSupa.deleteTrade(id);
    if (ok) setTrades((arr) => arr.filter((x) => x.id !== id));
    setDetail(null);
  };

  const heads = {
    trades: { h: tradeView === 'calendar' ? t('head.calendar') : t('head.tradelog'), sub: tradeView === 'calendar' ? t('head.calendarSub') : t('head.tradelogSub') },
    analyse: { h: t('head.analyse'), sub: t('head.analyseSub') },
    settings: { h: t('head.settings'), sub: t('head.settingsSub') },
  };

  const ViewToggle = () => {
    const { Icon } = window.CJUI;
    return (
      <div className="seg-toggle">
        <button className={tradeView === 'calendar' ? 'on' : ''} onClick={() => setView('calendar')}><Icon d="ledger" size={14} />{t('toggle.calendar')}</button>
        <button className={tradeView === 'list' ? 'on' : ''} onClick={() => setView('list')}><Icon d="M4 6h16M4 12h16M4 18h16" size={14} />{t('toggle.list')}</button>
      </div>
    );
  };

  // ---- password recovery (from the reset email link) ----
  if (view.kind === 'reset') {
    return <ResetScreen />;
  }

  // ---- boot splash while the session resolves ----
  if (booting) {
    return <div className="app-boot"><div className="brand-mark">C</div><div className="app-boot-txt">{t('common.loading')}</div></div>;
  }

  // ---- homepage ("/") — reachable whether logged in or not ----
  if (view.kind === 'home') {
    return <window.Landing
      authed={authed}
      onEnter={() => setRoute('trades')}
      onLogin={() => (authed ? setRoute('trades') : setAuthView('login'))}
      onRegister={() => (authed ? setRoute('trades') : setAuthView('register'))} />;
  }

  // ---- logged out on a private/auth path → auth screen ----
  if (!authed) {
    const mode = view.kind === 'auth' ? authView : 'login';
    return <window.AuthScreen mode={mode} onBack={() => setAuthView('landing')} onSwitch={(m) => setAuthView(m)} />;
  }

  // ---- signed in but not a member → invite-only gate ----
  if (!user.pro) {
    return <LockedScreen email={user.email} onLogout={logout} />;
  }

  return (
    <div className="app">
      <Rail route={route} setRoute={setRoute} user={user} trades={trades} onNew={() => setLogging(true)} onHome={() => nav('/')} />
      <div className="main">
        <div className="phead">
          <div className="phead-in">
            <div>
              <h1>{heads[route].h}</h1>
              <div className="sub">{heads[route].sub}</div>
            </div>
            <div className="phead-actions">
              {route === 'trades' && <ViewToggle />}
              {route === 'trades' && <window.CJUI.Btn kind="primary" icon="plus" onClick={() => setLogging(true)}>{t('common.logTrade')}</window.CJUI.Btn>}
              {route === 'analyse' && <window.CJUI.Btn kind="ghost" icon="share" onClick={() => setSharing(true)}>{t('head.shareEdge')}</window.CJUI.Btn>}
            </div>
          </div>
        </div>

        <div className="main-inner">
          {route === 'trades' && <window.TradesScreen trades={trades} confluences={confluences} user={user} view={tradeView} onNew={() => setLogging(true)} onOpen={setDetail} />}
          {route === 'analyse' && <window.AnalyseScreen trades={trades} confluences={confluences} user={user} onShare={() => setSharing(true)} />}
          {route === 'settings' && <window.SettingsScreen user={user} setUser={setUser} confluences={confluences} setConfluences={setConfluences} persistProfile={persistProfile} trades={trades} onReplay={() => setOnboarding(true)} onLogout={logout} />}
        </div>
      </div>

      <MobileNav route={route} setRoute={setRoute} onNew={() => setLogging(true)} />

      {onboarding && <window.Onboarding confluences={confluences} onDone={finishOnboarding} onClose={() => finishOnboarding(null)} />}
      {logging && <window.LogTrade confluences={confluences} user={user} onClose={() => setLogging(false)} onSave={addTrade} />}
      {detail && <window.TradeDetail trade={detail} user={user} onClose={() => setDetail(null)} onDelete={deleteTrade} />}
      {sharing && <window.ShareCard trades={trades} user={user} onClose={() => setSharing(false)} />}
    </div>
  );
}

// stub fallbacks so the app renders before every screen is wired
window.AnalyseScreen = window.AnalyseScreen || (() => <div className="empty">Analyse — coming up</div>);
window.SettingsScreen = window.SettingsScreen || (() => <div className="empty">Settings — coming up</div>);
window.LogTrade = window.LogTrade || (() => null);
window.TradeDetail = window.TradeDetail || (() => null);
window.ShareCard = window.ShareCard || (() => null);
window.Onboarding = window.Onboarding || (() => null);
window.Landing = window.Landing || (() => null);
window.AuthScreen = window.AuthScreen || (() => null);

window.CJApp = App;
