/* ============================================================
   TRELLIS — app shell, router, role/theme, tweaks
   ============================================================ */

const NAV = [
{ id: 'dashboard', label: 'Dashboard', icon: 'dashboard' },
{ id: 'harvest', label: 'Harvest', icon: 'sprout' },
{ id: 'clients', label: 'Clients', icon: 'clients' },
{ id: 'checkin', label: 'Client Check-In', icon: 'calendar' },
{ id: 'reports', label: 'Reports', icon: 'report' },
{ id: 'import', label: 'Data Import', icon: 'import' },
{ id: 'settings', label: 'Settings', icon: 'sliders' }];


const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "plum",
  "meshEnergy": 1,
  "glassDepth": "deep"
} /*EDITMODE-END*/;

const ACCENTS = {
  plum: { light: ['oklch(0.56 0.13 330)', 'white'], dark: ['oklch(0.74 0.12 330)', 'oklch(0.18 0.04 330)'] },
  blue: { light: ['oklch(0.54 0.11 248)', 'white'], dark: ['oklch(0.72 0.1 248)', 'oklch(0.17 0.04 248)'] },
  moss: { light: ['oklch(0.55 0.1 160)', 'white'], dark: ['oklch(0.72 0.1 160)', 'oklch(0.17 0.04 160)'] }
};

function SideNav({ page, openPage, role, setRole, signOut }) {
  const me = useEhcwUser();
  return (
    <aside className="glass-strong trellis-sidenav" style={{
      width: 232, borderRadius: 'var(--radius-l)', padding: 16, display: 'flex', flexDirection: 'column', gap: 4,
      position: 'sticky', top: 16, height: 'calc(100vh - 32px)', boxShadow: 'var(--shadow-card)'
    }}>
      <div style={{ padding: '8px 10px 18px', display: 'flex', flexDirection: 'column', gap: 14 }}>
        <TrellisWordmark size={30} />
        <EhcwLogo height={22} />
      </div>
      {NAV.map((n) =>
      <button key={n.id} onClick={() => openPage(n.id)} style={{
        display: 'flex', alignItems: 'center', gap: 12, padding: '11px 14px', borderRadius: 13,
        fontSize: 14, fontWeight: page === n.id ? 700 : 600, textAlign: 'left',
        background: page === n.id ? 'var(--accent-soft)' : 'transparent',
        color: page === n.id ? 'var(--accent)' : 'var(--ink-soft)', transition: 'all .15s'
      }}
      onMouseEnter={(e) => {if (page !== n.id) e.currentTarget.style.background = 'var(--hover)';}}
      onMouseLeave={(e) => {if (page !== n.id) e.currentTarget.style.background = 'transparent';}}>
          <BrandIcon name={n.icon} size={18} stroke={page === n.id ? 2.1 : 1.7} color={page === n.id ? 'var(--accent)' : 'var(--ink-soft)'} /> {n.label}
        </button>
      )}
      <div style={{ marginTop: 'auto', display: 'flex', flexDirection: 'column', gap: 10 }} data-comment-anchor="3c6c2327bf-div-18-7">
        {/* role switch */}
        <div className="glass" style={{ borderRadius: 14, padding: 5, display: 'flex', gap: 4 }}>
          {[['caseworker', 'Caseworker'], ['admin', 'Admin']].map(([r, label]) =>
          <button key={r} onClick={() => setRole(r)} style={{
            flex: 1, padding: '8px 6px', borderRadius: 10, fontSize: 12, fontWeight: 700,
            background: role === r ? 'var(--accent)' : 'transparent',
            color: role === r ? 'var(--accent-ink)' : 'var(--ink-faint)', transition: 'all .2s'
          }}>{label}</button>
          )}
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '6px 8px' }}>
          <PersonAvatar name={me?.displayName || 'June Park'} photo={me?.photoURL} size={32} />
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 13, fontWeight: 700, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{me?.displayName || 'June Park'}</div>
            <div className="t-faint" style={{ fontSize: 11 }}>{me?.role === 'superadmin' ? 'Super Admin' : role === 'admin' ? 'Admin' : 'Caseworker'}</div>
          </div>
          <button onClick={signOut} title="Sign out" style={{ padding: 7, borderRadius: 9, color: 'var(--ink-faint)' }}
          onMouseEnter={(e) => e.currentTarget.style.background = 'var(--hover)'}
          onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
            <Icon name="logout" size={16} />
          </button>
        </div>
      </div>
    </aside>);

}

function NotificationsBell({ openPage }) {
  const [open, setOpen] = React.useState(false);
  const [, setTick] = React.useState(0);

  // Re-render whenever the harvest crawl updates the board (every 2h + on sign-in)
  React.useEffect(() => {
    const bump = () => setTick(t => t + 1);
    document.addEventListener('ehcw:data:harvest', bump);
    return () => document.removeEventListener('ehcw:data:harvest', bump);
  }, []);

  // Pending = unhandled mail + upcoming meetings still in "Picked for you".
  // Handled mail (viewed + replied) is auto-archived by the crawl, so it never shows here.
  const pending = (window.TRELLIS_DATA.HARVEST || []).filter(c => c.col === 'picked');
  const count = pending.length;
  const ICON = { email: 'mail', calendar: 'calendar', system: 'spark' };

  return (
    <div style={{ position: 'relative' }}>
      <button onClick={() => setOpen(o => !o)} className="glass" style={{ padding: 11, borderRadius: 13, display: 'grid', placeItems: 'center', position: 'relative' }} title="Notifications">
        <Icon name="bell" size={17} />
        {count > 0 && (
          <span style={{ position: 'absolute', top: 9, right: 9, width: 7, height: 7, borderRadius: 99, background: 'var(--coral)' }}></span>
        )}
      </button>
      {open && (
        <>
          <div onClick={() => setOpen(false)} style={{ position: 'fixed', inset: 0, zIndex: 240 }}></div>
          <div className="glass-strong" style={{
            position: 'absolute', top: '110%', right: 0, zIndex: 250, width: 'min(340px, 86vw)',
            borderRadius: 18, boxShadow: 'var(--shadow-pop)', overflow: 'hidden',
            animation: 'trellis-pop .25s var(--ease-spring)'
          }}>
            {count === 0 ? (
              <div style={{ padding: '30px 24px', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12, textAlign: 'center' }}>
                <span style={{
                  width: 52, height: 52, borderRadius: '50%', display: 'grid', placeItems: 'center',
                  background: 'var(--leaf-soft)', color: 'var(--leaf)'
                }}><Icon name="check" size={24} stroke={2.4} /></span>
                <div style={{ fontFamily: 'var(--font-display)', fontSize: 15.5, fontWeight: 700 }}>Relax — you're all set.</div>
                <div className="t-faint" style={{ fontSize: 12.5, lineHeight: 1.55 }}>No unread mail, no upcoming meetings, nothing waiting on you.</div>
              </div>
            ) : (
              <div>
                <div style={{ padding: '13px 17px', fontSize: 12, fontWeight: 700, letterSpacing: '.07em', textTransform: 'uppercase', color: 'var(--ink-faint)', borderBottom: '1px solid var(--hairline)' }}>
                  {count} waiting for you
                </div>
                {pending.slice(0, 6).map(c => (
                  <button key={c.id} onClick={() => { setOpen(false); openPage && openPage('harvest'); }} style={{
                    width: '100%', textAlign: 'left', display: 'flex', gap: 11, alignItems: 'flex-start',
                    padding: '12px 17px', borderBottom: '1px solid var(--hairline)', background: 'transparent', transition: 'background .12s'
                  }}
                    onMouseEnter={e => e.currentTarget.style.background = 'var(--hover)'}
                    onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                    <span style={{
                      width: 30, height: 30, borderRadius: 10, display: 'grid', placeItems: 'center', flexShrink: 0,
                      background: c.priority === 'high' ? 'var(--coral-soft)' : 'var(--blue-soft)',
                      color: c.priority === 'high' ? 'var(--coral)' : 'var(--blue)'
                    }}><Icon name={ICON[c.src] || 'spark'} size={14} node={false} /></span>
                    <span style={{ minWidth: 0 }}>
                      <span style={{ display: 'block', fontSize: 13, fontWeight: 700, lineHeight: 1.35, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{c.title}</span>
                      <span className="t-faint" style={{ fontSize: 11.5 }}>{c.src === 'calendar' ? 'Meeting' : c.src === 'email' ? 'Needs a reply' : 'Follow-up'}{c.due ? ` · ${c.due}` : ''}</span>
                    </span>
                  </button>
                ))}
                <button onClick={() => { setOpen(false); openPage && openPage('harvest'); }} style={{
                  width: '100%', padding: '12px 17px', fontSize: 12.5, fontWeight: 700, color: 'var(--accent)', background: 'transparent', textAlign: 'center'
                }}>Open Harvest board →</button>
              </div>
            )}
          </div>
        </>
      )}
    </div>
  );
}

function TopBar({ theme, setTheme, push, role, openPage }) {
  return (
    <div style={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', gap: 10 }}>
      {role === 'admin' && (
        <span style={{
          display: 'inline-flex', alignItems: 'center', gap: 7, padding: '8px 14px', borderRadius: 99,
          fontSize: 12, fontWeight: 700, background: 'var(--accent-soft)', color: 'var(--accent)',
          border: '1px solid var(--hairline)', marginRight: 'auto'
        }}><Icon name="shield" size={13} node={false} /> Admin mode — PII reveal, imports &amp; full DB unlocked</span>
      )}
      <NotificationsBell openPage={openPage} />
      <button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')} className="glass" style={{ padding: 11, borderRadius: 13, display: 'grid', placeItems: 'center' }} title="Toggle theme">
        <Icon name={theme === 'dark' ? 'sun' : 'moon'} size={17} />
      </button>
    </div>);

}

function MobileNav({ page, openPage }) {
  return (
    <nav className="glass-strong trellis-mobilenav" style={{
      position: 'fixed', bottom: 12, left: 12, right: 12, zIndex: 200, borderRadius: 22,
      display: 'none', gap: 2, padding: 8, overflowX: 'auto', boxShadow: 'var(--shadow-pop)'
    }}>
      {NAV.map((n) =>
      <button key={n.id} onClick={() => openPage(n.id)} style={{
        flex: 1, minWidth: 56, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
        padding: '8px 4px', borderRadius: 14, minHeight: 50,
        background: page === n.id ? 'var(--accent-soft)' : 'transparent',
        color: page === n.id ? 'var(--accent)' : 'var(--ink-faint)'
      }}>
          <Icon name={n.icon} size={19} stroke={page === n.id ? 2.1 : 1.7} />
          <span style={{ fontSize: 9.5, fontWeight: 700 }}>{n.label.split(' ')[0]}</span>
        </button>
      )}
    </nav>);

}

function App() {
  const [stage, setStage] = React.useState(() => localStorage.getItem('trellis_stage') || 'auth');
  const [page, setPage] = React.useState(() => localStorage.getItem('trellis_page') || 'dashboard');
  const [pageParams, setPageParams] = React.useState({});
  const [theme, setThemeState] = React.useState(() => localStorage.getItem('trellis_theme') || 'dark');
  const [role, setRoleState] = React.useState(() => localStorage.getItem('trellis_role') || 'admin');
  const [adminCheck, setAdminCheck] = React.useState(null); // null | 'checking' | 'granted'
  const [requestOpen, setRequestOpen] = React.useState(false);
  const [toasts, push] = useToasts();
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  // theme side effects
  React.useEffect(() => {
    document.documentElement.setAttribute('data-theme', theme);
    if (window.TrellisMesh) window.TrellisMesh.setTheme(theme);
    localStorage.setItem('trellis_theme', theme);
  }, [theme]);
  // accent tweak
  React.useEffect(() => {
    const a = ACCENTS[t.accent] || ACCENTS.plum;
    const [c, ink] = theme === 'dark' ? a.dark : a.light;
    document.documentElement.style.setProperty('--accent', c);
    document.documentElement.style.setProperty('--accent-ink', ink);
    document.documentElement.style.setProperty('--accent-soft', c.replace(')', ' / 0.13)'));
  }, [t.accent, theme]);
  // mesh energy tweak
  React.useEffect(() => {
    if (window.TrellisMesh) window.TrellisMesh.setIntensity(t.meshEnergy);
  }, [t.meshEnergy]);
  // glass depth tweak
  React.useEffect(() => {
    document.documentElement.style.setProperty('--glass-blur', t.glassDepth === 'deep' ? '28px' : '12px');
  }, [t.glassDepth]);

  const setTheme = setThemeState;
  const setRole = (r) => {
    if (r === role) return;
    if (r === 'admin') {
      // verify the backend admin claim before unlocking
      setAdminCheck('checking');
      setTimeout(() => {
        setAdminCheck('granted');
        setRoleState('admin');
        localStorage.setItem('trellis_role', 'admin');
      }, 1100);
    } else {
      setRoleState(r);
      localStorage.setItem('trellis_role', r);
      push('Viewing as Caseworker — own caseload only, PII locked');
    }
  };
  const requestAdmin = () => setRequestOpen(true);
  const openPage = (p, params = {}) => {setPage(p);setPageParams(params);localStorage.setItem('trellis_page', p);window.scrollTo({ top: 0 });};
  const complete = () => {setStage('splash');localStorage.setItem('trellis_stage', 'app');};
  const signOut = () => {
    if (window.EHCW_AUTH) window.EHCW_AUTH.signOut().catch(() => {});
    setStage('auth');localStorage.setItem('trellis_stage', 'auth');
  };
  // localStorage alone can't keep you "signed in": when Firebase reports
  // signed-out, the app returns to the auth screen instead of showing the
  // shell with demo data behind a remembered stage.
  React.useEffect(() => {
    const enforce = () => {
      if (window.EHCW_AUTH && !window.EHCW_AUTH.getUser()) {
        setStage('auth'); localStorage.setItem('trellis_stage', 'auth');
      }
    };
    document.addEventListener('ehcw:auth:ready', enforce);
    document.addEventListener('ehcw:user', enforce);
    return () => { document.removeEventListener('ehcw:auth:ready', enforce); document.removeEventListener('ehcw:user', enforce); };
  }, []);

  const tweaksPanel =
  <TweaksPanel>
      <TweakSection label="Wallpaper" />
      <TweakSlider label="Energy" value={t.meshEnergy} min={0} max={1} step={0.05}
    onChange={(v) => setTweak('meshEnergy', v)} />
      <TweakSection label="Theme" />
      <TweakRadio label="Accent" value={t.accent} options={['plum', 'blue', 'moss']}
    onChange={(v) => setTweak('accent', v)} />
      <TweakRadio label="Glass" value={t.glassDepth} options={['deep', 'crisp']}
    onChange={(v) => setTweak('glassDepth', v)} />
    </TweaksPanel>;


  if (stage === 'auth') {
    return (
      <React.Fragment>
        <AuthFlow onComplete={complete} />
        <Toasts toasts={toasts} />
        {tweaksPanel}
        <ThemeFab theme={theme} setTheme={setTheme} />
      </React.Fragment>);

  }

  if (stage === 'splash') {
    return <WelcomeSplash onDone={() => setStage('app')} />;
  }

  const pageEl = {
    dashboard: <DashboardPage role={role} openPage={openPage} push={push} />,
    harvest: <HarvestPage push={push} params={pageParams} />,
    clients: <ClientsPage role={role} push={push} params={pageParams} requestAdmin={requestAdmin} />,
    checkin: <FoodBankPage push={push} params={pageParams} />,
    reports: <ReportsPage role={role} push={push} requestAdmin={requestAdmin} />,
    import: <ImportPage role={role} push={push} requestAdmin={requestAdmin} />,
    settings: <SettingsPage role={role} theme={theme} setTheme={setTheme} push={push} />
  }[page];

  return (
    <React.Fragment>
      <div className="trellis-frame" style={{ position: 'relative', zIndex: 1, display: 'flex', gap: 16, padding: 16, maxWidth: 1480, margin: '0 auto', alignItems: 'flex-start' }} data-comment-anchor="44b1438a1b-div-185-7">
        <SideNav page={page} openPage={openPage} role={role} setRole={setRole} signOut={signOut} />
        <main style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 18, minHeight: 'calc(100vh - 32px)' }}>
          <TopBar theme={theme} setTheme={setTheme} push={push} role={role} openPage={openPage} />
          <div key={page} style={{ animation: 'trellis-rise .45s var(--ease-spring)', flex: 1 }}>
            {pageEl}
          </div>
          <footer style={{ padding: '26px 0 10px', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 10 }}>
            <PoweredBy />
            <span className="t-faint" style={{ fontSize: 11.5 }}>Unstoppables · Elspeth Heyworth Centre for Women · data resident in Canada 🇨🇦</span>
          </footer>
        </main>
      </div>
      <MobileNav page={page} openPage={openPage} />
      <Toasts toasts={toasts} />
      {adminCheck && <AdminCheckModal state={adminCheck} onClose={() => setAdminCheck(null)} />}
      {requestOpen && <RequestAdminModal onClose={() => setRequestOpen(false)} push={push} />}
      {tweaksPanel}
    </React.Fragment>);

}

// ---- Admin claim verification (shown when switching to Admin) ----
function AdminCheckModal({ state, onClose }) {
  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 350, display: 'grid', placeItems: 'center', padding: 20 }}>
      <div onClick={state === 'granted' ? onClose : undefined} style={{ position: 'absolute', inset: 0, background: 'oklch(0.1 0.02 305 / 0.45)', backdropFilter: 'blur(3px)' }}></div>
      <div className="glass-strong" style={{ position: 'relative', width: 'min(420px, 100%)', borderRadius: 'var(--radius-xl)', padding: 30, boxShadow: 'var(--shadow-pop)', animation: 'trellis-pop .35s var(--ease-spring)', display: 'flex', flexDirection: 'column', gap: 16, alignItems: 'center', textAlign: 'center' }}>
        {state === 'checking' ? (
          <React.Fragment>
            <div style={{ width: 60, height: 60, borderRadius: '50%', display: 'grid', placeItems: 'center', background: 'var(--blue-soft)', color: 'var(--blue)' }}>
              <span style={{ display: 'inline-flex', animation: 'spin 1s linear infinite' }}><Icon name="refresh" size={26} stroke={2} node={false} /></span>
            </div>
            <h3 style={{ fontSize: 18, fontWeight: 700 }}>Verifying admin claim…</h3>
            <p className="t-soft" style={{ fontSize: 13.5, lineHeight: 1.6, margin: 0 }}>Checking your Firebase custom claims against the org backend. Admin can only be assigned there — never from inside the app.</p>
            <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>
          </React.Fragment>
        ) : (
          <React.Fragment>
            <div style={{ width: 60, height: 60, borderRadius: '50%', display: 'grid', placeItems: 'center', background: 'var(--leaf-soft)', color: 'var(--leaf)' }}>
              <Icon name="check" size={28} stroke={2.4} node={false} />
            </div>
            <h3 style={{ fontSize: 18, fontWeight: 700 }}>Admin verified — {(window.EHCW_AUTH && window.EHCW_AUTH.getUser()?.displayName) || 'June Park'}</h3>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8, width: '100%', textAlign: 'left' }}>
              {[['eye', 'Reveal PII per record (audit-logged)'], ['import', 'Run data imports & migrations'], ['clients', 'See every record, every caseload'], ['report', 'Generate full-detail client reports']].map(([ic, txt]) => (
                <div key={txt} style={{ display: 'flex', alignItems: 'center', gap: 10, fontSize: 13, fontWeight: 600, padding: '8px 12px', borderRadius: 11, background: 'var(--hover)' }}>
                  <Icon name={ic} size={15} node={false} style={{ color: 'var(--accent)' }} /> {txt}
                </div>
              ))}
            </div>
            <button onClick={onClose} style={{ width: '100%', padding: '13px 20px', borderRadius: 14, fontSize: 14, fontWeight: 700, fontFamily: 'var(--font-display)', background: 'var(--accent)', color: 'var(--accent-ink)' }}>Continue as Admin</button>
          </React.Fragment>
        )}
      </div>
    </div>);

}

// ---- Admin access request (gated action while Caseworker) ----
function RequestAdminModal({ onClose, push }) {
  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 350, display: 'grid', placeItems: 'center', padding: 20 }}>
      <div onClick={onClose} style={{ position: 'absolute', inset: 0, background: 'oklch(0.1 0.02 305 / 0.45)', backdropFilter: 'blur(3px)' }}></div>
      <div className="glass-strong" style={{ position: 'relative', width: 'min(420px, 100%)', borderRadius: 'var(--radius-xl)', padding: 30, boxShadow: 'var(--shadow-pop)', animation: 'trellis-pop .35s var(--ease-spring)', display: 'flex', flexDirection: 'column', gap: 14, alignItems: 'center', textAlign: 'center' }}>
        <div style={{ width: 60, height: 60, borderRadius: '50%', display: 'grid', placeItems: 'center', background: 'var(--gold-soft)', color: 'var(--gold-deep)' }}>
          <Icon name="lock" size={24} stroke={2} node={false} />
        </div>
        <h3 style={{ fontSize: 18, fontWeight: 700 }}>Admin access required</h3>
        <p className="t-soft" style={{ fontSize: 13.5, lineHeight: 1.6, margin: 0 }}>
          This action is locked for your account. Admin access is assigned from the backend by your Org Admin — it can't be enabled in the app.
        </p>
        <div className="glass" style={{ borderRadius: 14, padding: '12px 16px', display: 'flex', alignItems: 'center', gap: 12, width: '100%', textAlign: 'left' }}>
          <Avatar initials="EH" hue={290} size={34} />
          <div style={{ fontSize: 13 }}>
            <div style={{ fontWeight: 700 }}>EHCW Org Admin</div>
            <div className="t-faint mono" style={{ fontSize: 11.5 }}>info@ehcw.ca</div>
          </div>
        </div>
        <div style={{ display: 'flex', gap: 10, width: '100%' }}>
          <button onClick={onClose} style={{ flex: 1, padding: '12px 16px', borderRadius: 14, fontSize: 13.5, fontWeight: 700, background: 'var(--hover)', border: '1px solid var(--hairline)' }}>Close</button>
          <button onClick={() => { push('Request sent to admin@ehcw.ca'); onClose(); }} style={{ flex: 1.4, padding: '12px 16px', borderRadius: 14, fontSize: 13.5, fontWeight: 700, fontFamily: 'var(--font-display)', background: 'var(--accent)', color: 'var(--accent-ink)' }}>Request access</button>
        </div>
      </div>
    </div>);

}

// small floating theme toggle for the auth screens
function ThemeFab({ theme, setTheme }) {
  return (
    <button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')} className="glass-strong" style={{
      position: 'fixed', top: 16, right: 16, zIndex: 250, padding: 12, borderRadius: 14, display: 'grid', placeItems: 'center'
    }} title="Toggle theme">
      <Icon name={theme === 'dark' ? 'sun' : 'moon'} size={17} />
    </button>);

}

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