// admin-app.jsx — shell, routing, persisted state + auth gate + real-data wiring
const { useState: useSA, useEffect: useEA } = React;

const PAGE_TITLES = {
  overview: ['ov_title', 'ov_sub'], users: ['us_title', 'us_sub'], households: ['hh_title', 'hh_sub'],
  engagement: ['en_title', 'en_sub'], content: ['co_title', 'co_sub'], impact: ['im_title', 'im_sub'],
  revenue: ['re_title', 're_sub'], costs: ['cost_title', 'cost_sub'], geo: ['geo_title', 'geo_sub'], system: ['sys_title', 'sys_sub'],
};
const PAGE_COMP = {
  overview: PageOverview, users: PageUsers, households: PageHouseholds, engagement: PageEngagement,
  content: PageContent, impact: PageImpact, revenue: PageRevenue, costs: PageCosts, geo: PageGeo, system: PageSystem,
};

// ── API helper (admin-gated, Bearer token) ──────────────────────────
function adminApi(path, opts) {
  opts = opts || {};
  const token = sessionStorage.getItem('pw_admin_token') || '';
  const headers = { 'content-type': 'application/json' };
  if (token) headers.authorization = 'Bearer ' + token;
  return fetch('/api' + path, { method: opts.method || 'GET', headers, body: opts.body ? JSON.stringify(opts.body) : undefined })
    .then(async (r) => { let d = null; try { d = await r.json(); } catch (e) {} if (!r.ok) { const e = new Error((d && d.error) || ('HTTP ' + r.status)); e.status = r.status; throw e; } return d; });
}

// ── overlay real data onto the demo constants (mutates in place) ─────
// The design ships with realistic placeholders; here we replace the parts we
// actually measure (accounts, households, active, the real user list) with live
// data, and leave the rest as the designed projections.
async function loadRealData() {
  try {
    const [stats, usersR] = await Promise.all([
      adminApi('/admin/stats'),
      adminApi('/admin/users').catch(() => null),
    ]);
    if (stats && typeof ADMIN_KPIS !== 'undefined') {
      ADMIN_KPIS.users.value = stats.users;
      ADMIN_KPIS.households.value = stats.households;
      ADMIN_KPIS.mau.value = stats.activeUsers7d;
      ADMIN_KPIS.dau.value = stats.activeUsers7d;
      if (typeof HH_STATS !== 'undefined') { HH_STATS.total = stats.households; HH_STATS.invites = stats.pendingInvites; }
    }
    if (usersR && usersR.users && typeof USERS !== 'undefined') {
      const adminEmail = (usersR.adminEmail || '').toLowerCase();
      const mapped = usersR.users.map((u) => {
        const seenTs = u.last_seen || u.last_session || 0;
        const status = u.active_sessions > 0 ? 'active'
          : (Date.now() - seenTs > 30 * 864e5 ? 'dormant' : 'new');
        return {
          id: u.id, name: u.name || '—', email: u.email,
          region: '—', plan: 'free', isAdmin: (u.email || '').toLowerCase() === adminEmail,
          status,
          joinedDaysAgo: Math.floor((Date.now() - (u.created_at || Date.now())) / 864e5),
          seenHrsAgo: seenTs ? Math.floor((Date.now() - seenTs) / 3600000) : 9999,
          items: 0, household: u.household_size || 1, cooked: 0, scans: u.logins || 0,
          householdName: u.household_name || '',
        };
      });
      USERS.length = 0; mapped.forEach((u) => USERS.push(u));
      if (typeof RECENT_SIGNUPS !== 'undefined') {
        RECENT_SIGNUPS.length = 0;
        USERS.slice().sort((a, b) => a.joinedDaysAgo - b.joinedDaysAgo).slice(0, 6).forEach((u) => RECENT_SIGNUPS.push(u));
      }
    }
    window.__pwRealLoaded = true;
  } catch (e) { /* keep demo data on failure */ }
}

function App() {
  const [page, setPage] = useSA(() => localStorage.getItem('pw_admin_page') || 'overview');
  const [lang, setLang] = useSA(() => localStorage.getItem('pw_admin_lang') || 'fr');
  const [theme, setTheme] = useSA(() => localStorage.getItem('pw_admin_theme') || 'nocturne');
  const [period, setPeriod] = useSA(() => localStorage.getItem('pw_admin_period') || '12m');

  useEA(() => { applyAdminTheme(theme); localStorage.setItem('pw_admin_theme', theme); }, [theme]);
  useEA(() => { localStorage.setItem('pw_admin_page', page); }, [page]);
  useEA(() => { localStorage.setItem('pw_admin_lang', lang); document.documentElement.lang = lang; }, [lang]);
  useEA(() => { localStorage.setItem('pw_admin_period', period); }, [period]);

  const Comp = PAGE_COMP[page] || PageOverview;
  const [tKey, sKey] = PAGE_TITLES[page];
  const logout = () => { sessionStorage.removeItem('pw_admin_token'); location.reload(); };

  return (
    <div style={{ display: 'flex', height: '100vh', width: '100vw', overflow: 'hidden', background: 'var(--bg)', backgroundImage: 'var(--bg-grad)' }}>
      <Sidebar page={page} setPage={setPage} lang={lang} onLogout={logout} />
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0, height: '100%' }}>
        <Topbar lang={lang} setLang={setLang} theme={theme} setTheme={setTheme} period={period} setPeriod={setPeriod}
          title={tA(lang, tKey)} sub={tA(lang, sKey)} />
        <main className="pw-scroll" style={{ flex: 1, overflowY: 'auto', padding: '22px 26px 60px' }}>
          <div key={page + lang} className="pw-fade">
            <Comp lang={lang} period={period} />
          </div>
        </main>
      </div>
    </div>
  );
}

// ── Auth gate: login → verify admin → load real data → render App ───
function AuthGate() {
  const [authed, setAuthed] = useSA(false);
  const [checking, setChecking] = useSA(true);
  const [busy, setBusy] = useSA(false);
  const [err, setErr] = useSA('');
  const [email, setEmail] = useSA('');
  const [pass, setPass] = useSA('');

  useEA(() => { applyAdminTheme(localStorage.getItem('pw_admin_theme') || 'nocturne'); }, []);

  const finish = async () => { await loadRealData(); setAuthed(true); };

  useEA(() => {
    const token = sessionStorage.getItem('pw_admin_token');
    if (!token) { setChecking(false); return; }
    adminApi('/admin/stats').then(finish).catch(() => { sessionStorage.removeItem('pw_admin_token'); setChecking(false); });
  }, []);

  const submit = async (e) => {
    if (e && e.preventDefault) e.preventDefault();
    setErr(''); setBusy(true);
    try {
      const r = await adminApi('/auth/login', { method: 'POST', body: { email: email.trim(), password: pass } });
      sessionStorage.setItem('pw_admin_token', r.sessionToken);
      await adminApi('/admin/stats'); // verifies admin role
      await finish();
    } catch (e2) {
      sessionStorage.removeItem('pw_admin_token');
      setErr(e2.status === 403 ? "Ce compte n'est pas administrateur (vérifie ADMIN_EMAIL en Secret dans Cloudflare)." : (e2.message || 'Erreur'));
    } finally { setBusy(false); }
  };

  if (authed) return <App />;
  if (checking) return <div style={{ height: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--ink-3)' }}>…</div>;

  const field = { width: '100%', height: 46, borderRadius: 12, border: '1px solid var(--line)', background: 'var(--card-2)', color: 'var(--ink)', padding: '0 14px', fontSize: 15, fontFamily: 'inherit', outline: 'none', marginTop: 6, boxSizing: 'border-box' };
  return (
    <div style={{ height: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--bg)', backgroundImage: 'var(--bg-grad)' }}>
      <form onSubmit={submit} style={{ width: 380, maxWidth: '92vw', background: 'var(--card)', border: '1px solid var(--line)', borderRadius: 20, padding: 32, boxShadow: 'var(--shadow)' }}>
        <div style={{ width: 48, height: 48, borderRadius: 14, background: 'var(--accent)', color: 'var(--accent-ink)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 24, boxShadow: 'var(--glow)' }}>🥬</div>
        <div style={{ fontSize: 21, fontWeight: 800, marginTop: 16, letterSpacing: '-0.02em' }}>PantryWise Console</div>
        <div style={{ color: 'var(--ink-2)', fontSize: 13, marginTop: 4 }}>Connexion réservée à l'administrateur.</div>
        <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--ink-2)', marginTop: 18 }}>Courriel</div>
        <input style={field} type="email" autoComplete="username" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="toi@email.com" autoFocus />
        <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--ink-2)', marginTop: 14 }}>Mot de passe</div>
        <input style={field} type="password" autoComplete="current-password" value={pass} onChange={(e) => setPass(e.target.value)} placeholder="••••••••" />
        {err && <div style={{ background: 'var(--neg-soft)', color: 'var(--neg)', padding: '10px 12px', borderRadius: 10, fontSize: 13, marginTop: 14 }}>{err}</div>}
        <button type="submit" disabled={busy} style={{ width: '100%', height: 48, borderRadius: 13, border: 'none', background: 'var(--accent)', color: 'var(--accent-ink)', fontSize: 15, fontWeight: 700, cursor: 'pointer', marginTop: 18, opacity: busy ? 0.6 : 1, fontFamily: 'inherit' }}>
          {busy ? 'Une seconde…' : 'Se connecter'}
        </button>
      </form>
    </div>
  );
}

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