// app.jsx — shell, routing, tweaks, auth
const { useState: uSA, useEffect: uEA } = React;

const NAV = [
  { key: 'home', label: 'Home', icon: 'home' },
  { key: 'budget', label: 'Budget', icon: 'budget' },
  { key: 'claims', label: 'Claims', icon: 'receipt' },
  { key: 'invoices', label: 'Invoice vault', icon: 'doc', feature: 'document_vault' },
  { key: 'workers', label: 'Support workers', icon: 'people', feature: 'support_workers' },
  { key: 'providers', label: 'Providers', icon: 'card' },
  { key: 'review', label: 'Plan review', icon: 'sparkles', feature: 'plan_review_prep' },
];

// curated accent palettes [primary, ink, soft]
const ACCENTS = {
  Rose: ['#c2557a', '#a23d62', '#f8e7ee'],
  Teal: ['#3f9488', '#2f7569', '#e1efec'],
  Indigo: ['#6a6bd0', '#4f50b0', '#e8e8f7'],
  Plum: ['#9a5ba6', '#7c4488', '#f1e6f3'],
};

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "Rose",
  "headingFont": "Warm serif",
  "density": "regular",
  "plainEnglish": true
}/*EDITMODE-END*/;

function NavItem({ item, active, onClick, badge, locked }) {
  const [h, setH] = uSA(false);
  const I = Icons[item.icon];
  return (
    <button onClick={onClick} onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)} style={{
      display: 'flex', alignItems: 'center', gap: 12, width: '100%', textAlign: 'left',
      padding: '10px 13px', borderRadius: 12, border: 'none', fontSize: 14.5, fontWeight: active ? 600 : 500,
      color: active ? 'var(--primary-ink)' : (h ? 'var(--ink)' : 'var(--ink-2)'),
      background: active ? 'var(--primary-soft)' : (h ? 'var(--surface-2)' : 'transparent'),
      transition: 'all .14s', position: 'relative', opacity: locked ? 0.55 : 1,
    }}>
      <I size={20} />
      <span style={{ flex: 1 }}>{item.label}</span>
      {locked && <Icons.card size={14} />}
      {!locked && badge > 0 && <span style={{ background: active ? 'var(--primary)' : 'var(--amber)', color: '#fff', fontSize: 11.5, fontWeight: 700, borderRadius: 99, padding: '1px 7px', minWidth: 18, textAlign: 'center' }}>{badge}</span>}
    </button>
  );
}

// ── loading / error placeholders (no doc yet, no PIN/screen chrome) ──
function CenteredCard({ children }) {
  return (
    <div style={{ height: '100%', display: 'grid', placeItems: 'center', background: 'var(--canvas)' }}>
      <div style={{ textAlign: 'center', maxWidth: 380, animation: 'pop .3s ease both' }}>{children}</div>
    </div>
  );
}
function Brand() {
  return (
    <div style={{ width: 54, height: 54, borderRadius: 16, background: 'var(--primary)', display: 'grid', placeItems: 'center', margin: '0 auto 18px', boxShadow: 'var(--shadow)' }}>
      <Icons.heart size={28} fill="#fff" stroke={0} />
    </div>
  );
}
function LoadingScreen() {
  return <CenteredCard><Brand /><p style={{ color: 'var(--ink-2)', fontSize: 14.5 }}>Loading your records…</p></CenteredCard>;
}
function ErrorScreen({ S }) {
  return (
    <CenteredCard>
      <Brand />
      <h1 style={{ margin: '0 0 6px', fontFamily: 'var(--serif)', fontWeight: 500, fontSize: 26 }}>Something went wrong</h1>
      <p style={{ margin: '0 0 20px', color: 'var(--ink-2)', fontSize: 14.5 }}>We couldn't load your records. Try again, or sign in again.</p>
      {S.lastError && <div style={{ marginBottom: 16, textAlign: 'left' }}><Note tone="amber" icon="alert">{S.lastError}</Note></div>}
      <div style={{ display: 'flex', gap: 10, justifyContent: 'center' }}>
        <Button variant="white" onClick={() => location.reload()}>Try again</Button>
        <Button onClick={() => S.signOut()}>Sign out</Button>
      </div>
    </CenteredCard>
  );
}

// ── sign in / sign up ──
// Defaults to 'signup' — a real subscriber's FIRST visit is always account
// creation, never sign-in (there's no account yet to sign in to). Once
// someone has actually signed in successfully once, remember that and
// default to 'signin' for them next time. Getting this default backwards is
// exactly what confused the very first real subscriber to try it.
function AuthScreen({ S }) {
  const [mode, setMode] = uSA(() => {
    try { return localStorage.getItem('haven_has_signed_in') ? 'signin' : 'signup'; } catch (e) { return 'signup'; }
  });
  const [email, setEmail] = uSA(() => { try { return localStorage.getItem('haven_last_email') || ''; } catch (e) { return ''; } });
  const [password, setPassword] = uSA('');
  const [busy, setBusy] = uSA(false);
  const [err, setErr] = uSA('');

  const submit = async () => {
    if (!email.trim() || !password) return;
    setBusy(true); setErr('');
    try {
      if (mode === 'signin') await S.signIn(email.trim(), password);
      else await S.signUp(email.trim(), password);
      try { localStorage.setItem('haven_has_signed_in', '1'); } catch (e) {}
    } catch (e) {
      setErr(e.message || 'Something went wrong.');
    } finally { setBusy(false); }
  };

  return (
    <CenteredCard>
      <Brand />
      <h1 style={{ margin: '0 0 6px', fontFamily: 'var(--serif)', fontWeight: 500, fontSize: 28 }}>
        {mode === 'signin' ? 'Welcome back' : 'Activate your Haven subscription'}
      </h1>
      <p style={{ margin: '0 0 20px', color: 'var(--ink-2)', fontSize: 14.5 }}>
        {mode === 'signin' ? 'Sign in to open your records.' : 'Enter the email your Haven subscription is under, and choose a password for your account.'}
      </p>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10, textAlign: 'left' }}>
        <input type="email" autoFocus value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Email"
          style={{ padding: '13px 16px', fontSize: 15, fontFamily: 'var(--sans)', border: '1.5px solid var(--line-2)', borderRadius: 13, outline: 'none', background: 'var(--surface)', color: 'var(--ink)' }} />
        <input type="password" value={password} onChange={(e) => setPassword(e.target.value)}
          onKeyDown={(e) => e.key === 'Enter' && submit()} placeholder="Password"
          style={{ padding: '13px 16px', fontSize: 15, fontFamily: 'var(--sans)', border: '1.5px solid var(--line-2)', borderRadius: 13, outline: 'none', background: 'var(--surface)', color: 'var(--ink)' }} />
      </div>
      {err && <div style={{ marginTop: 12 }}><Note tone="amber" icon="alert">{err}</Note></div>}
      <div style={{ marginTop: 14 }}><Button full size="lg" disabled={busy} onClick={submit}>{busy ? 'Please wait…' : (mode === 'signin' ? 'Sign in' : 'Create account')}</Button></div>
      <button onClick={() => { setMode(mode === 'signin' ? 'signup' : 'signin'); setErr(''); }}
        style={{ marginTop: 14, background: 'none', border: 'none', color: 'var(--primary-ink)', fontWeight: 600, fontSize: 13.5 }}>
        {mode === 'signin' ? "First time here? Create your account" : 'Already have an account? Sign in'}
      </button>
    </CenteredCard>
  );
}

// ── first-time onboarding: create the participant profile ──
function OnboardingScreen({ S }) {
  const [name, setName] = uSA('');
  const [ndis, setNdis] = uSA('');
  const [parent, setParent] = uSA('Mum');
  const [busy, setBusy] = uSA(false);
  const [err, setErr] = uSA('');

  const submit = async () => {
    if (!name.trim()) return;
    setBusy(true); setErr('');
    try {
      await S.createParticipant({ name: name.trim(), ndis: ndis.trim(), parent: parent.trim() || 'Mum' });
    } catch (e) { setErr(e.message || 'Something went wrong.'); setBusy(false); }
  };

  return (
    <CenteredCard>
      <Brand />
      <h1 style={{ margin: '0 0 6px', fontFamily: 'var(--serif)', fontWeight: 500, fontSize: 28 }}>Let's set up your records</h1>
      <p style={{ margin: '0 0 20px', color: 'var(--ink-2)', fontSize: 14.5 }}>Just the basics for now — you can add everything else as you go.</p>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10, textAlign: 'left' }}>
        <input value={name} onChange={(e) => setName(e.target.value)} placeholder="Child's name" autoFocus
          style={{ padding: '13px 16px', fontSize: 15, fontFamily: 'var(--sans)', border: '1.5px solid var(--line-2)', borderRadius: 13, outline: 'none', background: 'var(--surface)', color: 'var(--ink)' }} />
        <input value={ndis} onChange={(e) => setNdis(e.target.value)} placeholder="NDIS number (optional)"
          style={{ padding: '13px 16px', fontSize: 15, fontFamily: 'var(--sans)', border: '1.5px solid var(--line-2)', borderRadius: 13, outline: 'none', background: 'var(--surface)', color: 'var(--ink)' }} />
        <input value={parent} onChange={(e) => setParent(e.target.value)} placeholder="What should we call you? (e.g. Mum, Dad)"
          style={{ padding: '13px 16px', fontSize: 15, fontFamily: 'var(--sans)', border: '1.5px solid var(--line-2)', borderRadius: 13, outline: 'none', background: 'var(--surface)', color: 'var(--ink)' }} />
      </div>
      {err && <div style={{ marginTop: 12 }}><Note tone="amber" icon="alert">{err}</Note></div>}
      <div style={{ marginTop: 14 }}><Button full size="lg" disabled={busy || !name.trim()} onClick={submit}>{busy ? 'Setting up…' : 'Get started'}</Button></div>
    </CenteredCard>
  );
}

// ── account badge (sidebar) ──
function AccountBadge({ S }) {
  const email = S.session && S.session.user && S.session.user.email;
  return (
    <div style={{ marginTop: 12 }}>
      <div style={{ fontSize: 11.5, color: 'var(--ink-2)', fontWeight: 600, marginBottom: 4 }}>{email}</div>
      <button onClick={() => S.signOut()} style={{ background: 'none', border: 'none', color: 'var(--ink-3)', fontSize: 11.5, fontWeight: 600 }}>Sign out</button>
    </div>
  );
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const S = useHaven();
  const [route, setRoute] = uSA(() => {
    const h = (location.hash || '').replace('#', '');
    return NAV.some((n) => n.key === h) || h === 'settings' ? h : 'home';
  });
  const [arg, setArg] = uSA(null);

  const go = (r, a = null) => { setRoute(r); setArg(a); location.hash = r; const m = document.getElementById('main'); if (m) m.scrollTop = 0; };
  const clearArg = () => setArg(null);

  // apply accent + heading font + plain-english + density
  uEA(() => {
    const a = ACCENTS[t.accent] || ACCENTS.Rose;
    const r = document.documentElement;
    r.style.setProperty('--primary', a[0]);
    r.style.setProperty('--primary-ink', a[1]);
    r.style.setProperty('--primary-soft', a[2]);
    r.style.setProperty('--capacity', a[0]);
    r.style.setProperty('--capacity-soft', a[2]);
    r.style.setProperty('--serif', t.headingFont === 'Clean sans' ? "'Figtree', sans-serif" : "'Newsreader', Georgia, serif");
    document.body.setAttribute('data-density', t.density);
    setPlain(t.plainEnglish);
  }, [t.accent, t.headingFont, t.density, t.plainEnglish]);

  if (S.status === 'loading') return <LoadingScreen />;
  if (S.status === 'need-auth') return <AuthScreen S={S} />;
  if (S.status === 'need-onboarding') return <OnboardingScreen S={S} />;
  if (S.status === 'error' || !S.doc) return <ErrorScreen S={S} />;

  // badge counts (live, from the store) — S.doc is guaranteed non-null past this point
  const claimTodo = S.doc.claims.filter((c) => c.status === 'draft' || c.status === 'rejected').length;
  const invWaiting = S.doc.invoices.filter((i) => !i.claimed).length;
  const sheetsTodo = S.doc.timesheets.filter((s) => s.status === 'pending').length;
  const badges = { claims: claimTodo, invoices: invWaiting, workers: sheetsTodo };

  const Screen = { home: Dashboard, budget: Budget, claims: Claims, invoices: Invoices, workers: Workers, providers: Providers, review: Review, settings: Settings }[route] || Dashboard;

  return (
    <div style={{ display: 'flex', height: '100%', overflow: 'hidden' }}>
      {/* ── Sidebar ── */}
      <aside style={{ width: 256, flexShrink: 0, background: 'var(--surface)', borderRight: '1px solid var(--line)', display: 'flex', flexDirection: 'column', padding: '22px 16px' }}>
        {/* brand */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 11, padding: '2px 8px 22px' }}>
          <div style={{ width: 38, height: 38, borderRadius: 11, background: 'var(--primary)', display: 'grid', placeItems: 'center', boxShadow: 'var(--shadow-sm)' }}>
            <Icons.heart size={21} fill="#fff" stroke={0} />
          </div>
          <div>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 21, fontWeight: 600, lineHeight: 1, letterSpacing: '-.01em' }}>Haven</div>
            <div style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 2 }}>your NDIS, in one place</div>
          </div>
        </div>

        {/* child profile */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 11, padding: '11px 12px', background: 'var(--surface-2)', borderRadius: 14, marginBottom: 18 }}>
          <Avatar initials={(S.doc.child.name || '?')[0]} size={38} />
          <div style={{ minWidth: 0 }}>
            <div style={{ fontSize: 14.5, fontWeight: 700, lineHeight: 1.1 }}>{S.doc.child.name || 'Your child'}</div>
            <div style={{ fontSize: 11.5, color: 'var(--ink-2)' }}>Self-managed · {S.doc.child.ndis}</div>
          </div>
        </div>

        {/* nav — items with a `feature` key are gated; locked ones still navigate but the
            screen itself should also self-check (not all screens do this yet, see README) */}
        <nav style={{ display: 'flex', flexDirection: 'column', gap: 3, flex: 1 }}>
          {NAV.map((n) => <NavItem key={n.key} item={n} active={route === n.key} badge={badges[n.key]}
            locked={n.feature && S.entitlements != null && !S.hasFeature(n.feature)} onClick={() => go(n.key)} />)}
          <div style={{ flex: 1 }}></div>
          <div style={{ borderTop: '1px solid var(--line)', margin: '6px 4px' }}></div>
          <NavItem item={{ key: 'settings', label: 'Settings', icon: 'gear' }} active={route === 'settings'} onClick={() => go('settings')} />
        </nav>

        {/* plan footer */}
        <div style={{ borderTop: '1px solid var(--line)', paddingTop: 14, marginTop: 8 }}>
          <div style={{ fontSize: 11.5, color: 'var(--ink-3)', marginBottom: 6, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '.04em' }}>Current plan</div>
          <div style={{ fontSize: 12.5, color: 'var(--ink-2)' }}>{fmtDateShort(PLAN_START)} – {fmtDate(PLAN_END)}</div>
          <div style={{ marginTop: 8 }}><Bar pct={PLAN_TIME_PCT} color="var(--ink-3)" height={6} /></div>
          <div style={{ fontSize: 11.5, color: 'var(--ink-3)', marginTop: 5 }}>{PLAN_DAYS_LEFT} days remaining</div>
          <AccountBadge S={S} />
          <div style={{ fontSize: 10.5, color: 'var(--ink-3)', marginTop: 7 }}>Haven {HAVEN_VERSION}</div>
        </div>
      </aside>

      {/* ── Main ── */}
      <main id="main" style={{ flex: 1, overflowY: 'auto', overflowX: 'hidden' }}>
        <div style={{ maxWidth: 1080, margin: '0 auto', padding: '38px 44px 80px' }}>
          <Screen arg={arg} go={go} clearArg={clearArg} />
        </div>
      </main>

      {/* ── Tweaks ── */}
      <TweaksPanel title="Tweaks">
        <TweakSection label="Look & feel" />
        <TweakColor label="Accent" value={(ACCENTS[t.accent] || ACCENTS.Rose)}
          options={Object.values(ACCENTS)}
          onChange={(v) => { const name = Object.keys(ACCENTS).find((k) => ACCENTS[k][0] === v[0]) || 'Rose'; setTweak('accent', name); }} />
        <TweakRadio label="Headings" value={t.headingFont} options={['Warm serif', 'Clean sans']} onChange={(v) => setTweak('headingFont', v)} />
        <TweakRadio label="Density" value={t.density} options={['compact', 'regular', 'comfy']} onChange={(v) => setTweak('density', v)} />
        <TweakSection label="Helpful extras" />
        <TweakToggle label="Plain-English helper" value={t.plainEnglish} onChange={(v) => setTweak('plainEnglish', v)} />
      </TweaksPanel>
    </div>
  );
}

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