/* ───────────────────────────────────────────────
   Happy Guts — app shell, navigation, persistence
   ─────────────────────────────────────────────── */
const { useState, useEffect } = React;

const LS = {
  get(k, fb) { try { const v = localStorage.getItem(k); return v == null ? fb : JSON.parse(v); } catch { return fb; } },
  set(k, v) { try { localStorage.setItem(k, JSON.stringify(v)); } catch {} },
  del(k) { try { localStorage.removeItem(k); } catch {} },
};

const DEFAULT_SENS = { gluten: 'no', salicylates: 'no', oxalates: 'no', amines: 'no' };
const DEFAULT_NOTIF = { push: true, expiry: true, newSafe: false };

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "homeLayout": "grid",
  "accent": "#F0552F",
  "showWatchOut": true
}/*EDITMODE-END*/;

const ACCENTS = ['#F0552F', '#E0457E', '#7A5AE0', '#1E9E8A'];

/* ── tab bar with center scan FAB ── */
function TabBar({ screen, go }) {
  const area = ({ home: 'home', foods: 'foods', food: 'foods', recipes: 'recipes', lists: 'lists', section: 'home', settings: 'home' })[screen];
  const tabs = [
    { k: 'home', icon: 'home', label: 'Home' },
    { k: 'foods', icon: 'foods', label: 'Foods' },
    { k: 'recipes', icon: 'recipes', label: 'Recipes' },
    { k: 'lists', icon: 'list', label: 'Lists' },
  ];
  const Tab = ({ t }) => {
    const on = area === t.k;
    return (
      <button className="btn" onClick={() => go(t.k)} style={{
        flexDirection: 'column', gap: 3, background: 'transparent', flex: 1, padding: '4px 0' }}>
        <window.Icon name={t.icon} size={24} color={on ? 'var(--spark)' : 'var(--ink-3)'} strokeWidth={on ? 2.4 : 2} />
        <span style={{ fontSize: 10.5, fontWeight: 700, color: on ? 'var(--spark)' : 'var(--ink-3)' }}>{t.label}</span>
      </button>
    );
  };
  return (
    <div style={{ position: 'relative', flexShrink: 0, background: 'var(--card)',
      borderTop: '1px solid var(--line)', paddingTop: 8,
      paddingBottom: 'calc(8px + env(safe-area-inset-bottom, 0px))',
      boxShadow: '0 -6px 24px rgba(40,30,20,.05)' }}>
      <div style={{ display: 'flex', alignItems: 'center', padding: '0 6px' }}>
        <Tab t={tabs[0]} /><Tab t={tabs[1]} />
        <div style={{ width: 64, flexShrink: 0 }} />
        <Tab t={tabs[2]} /><Tab t={tabs[3]} />
      </div>
      <button className="btn" onClick={() => go('scan')} aria-label="Scan a barcode" style={{
        position: 'absolute', top: -22, left: '50%', transform: 'translateX(-50%)',
        width: 60, height: 60, borderRadius: 20, background: 'var(--spark)',
        boxShadow: '0 8px 22px oklch(0.66 0.20 33 / .42)' }}>
        <window.Icon name="scan" size={28} color="#fff" strokeWidth={2.2} />
      </button>
    </div>
  );
}

/* ── content inside the device ── */
function AppShell({ gate, onGateDone, onboarded, setOnboarded, sens, setSens, notif, setNotif, list, setList, nav, go, addToList, resetAll, t }) {
  // opened in a phone browser and not installed: suggest installing first, every open (see app/pwa.jsx)
  if (gate) {
    return <window.InstallGate onContinue={onGateDone} />;
  }
  if (!onboarded) {
    return (
      <div className="app-root" style={{ height: '100%' }}>
        <window.Onboarding initial={sens} onComplete={(s) => { setSens(s); setOnboarded(true); go('home'); }} />
      </div>
    );
  }

  const { screen, params } = nav;
  const screens = {
    home:     <window.HomeScreen sens={sens} go={go} t={t} />,
    foods:    <window.FoodsScreen sens={sens} go={go} />,
    food:     <window.FoodDetail id={params.id} sens={sens} go={go} onAddToList={addToList} />,
    section:  <window.SectionScreen ckey={params.key} sens={sens} setSens={setSens} go={go} />,
    recipes:  <window.RecipesScreen sens={sens} go={go} />,
    lists:    <window.ShoppingScreen sens={sens} list={list} setList={setList} go={go} />,
    scan:     <window.ScanScreen sens={sens} go={go} onAddToList={addToList} />,
    settings: <window.SettingsScreen sens={sens} setSens={setSens} notif={notif} setNotif={setNotif} go={go} onReset={resetAll} />,
  };
  const isScan = screen === 'scan';

  return (
    <div className="app-root" style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
      {/* top safe-area inset — the OS status bar overlays here on a device; 0 on desktop */}
      <div style={{ height: 'env(safe-area-inset-top, 0px)', flexShrink: 0, background: isScan ? '#14110f' : 'var(--bg)' }} />
      <div style={{ flex: 1, minHeight: 0, position: 'relative' }}>
        {screens[screen] || screens.home}
      </div>
      {!isScan && <TabBar screen={screen} go={go} />}
    </div>
  );
}

function App() {
  const [t, setTweak] = window.useTweaks(TWEAK_DEFAULTS);
  const [onboarded, setOnboarded] = useState(() => LS.get('hg_onboarded', false));
  const [sens, setSens] = useState(() => LS.get('hg_sens', DEFAULT_SENS));
  const [notif, setNotif] = useState(() => LS.get('hg_notif', DEFAULT_NOTIF));
  const [list, setList] = useState(() => LS.get('hg_list', window.SHOPPING_SEED));
  const [nav, setNav] = useState({ screen: 'home', params: {} });
  const [gate, setGate] = useState(() => window.shouldShowInstallGate());
  const onGateDone = () => { window.markInstallGateSeen(); setGate(false); };

  useEffect(() => LS.set('hg_sens', sens), [sens]);
  useEffect(() => LS.set('hg_notif', notif), [notif]);
  useEffect(() => LS.set('hg_list', list), [list]);
  useEffect(() => LS.set('hg_onboarded', onboarded), [onboarded]);

  useEffect(() => {
    const a = t.accent || ACCENTS[0];
    const root = document.documentElement.style;
    root.setProperty('--spark', a);
    root.setProperty('--spark-press', `color-mix(in oklch, ${a} 82%, black)`);
    root.setProperty('--spark-tint', `color-mix(in oklch, ${a} 13%, white)`);
    root.setProperty('--spark-ink', `color-mix(in oklch, ${a} 62%, black)`);
  }, [t.accent]);

  const go = (screen, params = {}) => setNav({ screen, params });
  const addToList = (foodId) => setList(l => l.items.some(i => i.foodId === foodId) ? l
    : ({ ...l, items: [...l.items, { id: 'x' + Date.now(), foodId, qty: '1', done: false }] }));
  const resetAll = () => {
    LS.del('hg_onboarded'); LS.del('hg_sens'); LS.del('hg_notif'); LS.del('hg_list');
    setSens(DEFAULT_SENS); setNotif(DEFAULT_NOTIF); setList(window.SHOPPING_SEED);
    setNav({ screen: 'home', params: {} }); setOnboarded(false);
  };

  return (
    <React.Fragment>
      {/* full-bleed app surface — fills the viewport like a deployed build */}
      <div style={{ position: 'fixed', inset: 0, overflow: 'hidden', background: 'var(--bg)' }}>
        <AppShell {...{ gate, onGateDone, onboarded, setOnboarded, sens, setSens, notif, setNotif, list, setList, nav, go, addToList, resetAll, t }} />
        <window.UpdateToast />
      </div>
      <window.TweaksPanel title="Tweaks">
        <window.TweakSection label="Home layout" />
        <window.TweakRadio label="Top cards" value={t.homeLayout}
          options={[{ value: 'grid', label: '2×2 grid' }, { value: 'feature', label: 'Scan hero' }, { value: 'list', label: 'List' }]}
          onChange={v => setTweak('homeLayout', v)} />
        <window.TweakToggle label="Show 'worth avoiding'" value={t.showWatchOut}
          onChange={v => setTweak('showWatchOut', v)} />
        <window.TweakSection label="Brand" />
        <window.TweakColor label="Accent" value={t.accent} options={ACCENTS}
          onChange={v => setTweak('accent', v)} />
      </window.TweaksPanel>
    </React.Fragment>
  );
}

/* ── boot ──────────────────────────────────────────
   Food data lives in CSV tables (data/foods/*.csv) and is
   fetched before the first render, so every screen has FOODS
   ready. fetch() of local files needs an http server — see
   README. A simple splash / error card covers the brief gap. */
function BootMessage({ title, detail, mono }) {
  return (
    <div style={{ position: 'fixed', inset: 0, background: 'var(--bg)', display: 'flex',
      alignItems: 'center', justifyContent: 'center', fontFamily: 'system-ui, sans-serif', padding: 24 }}>
      <div style={{ maxWidth: 360, textAlign: 'center', color: '#3a342c' }}>
        <div style={{ fontSize: 19, fontWeight: 700, marginBottom: 8 }}>{title}</div>
        <div style={{ fontSize: 14, lineHeight: 1.5, color: '#6b6256',
          fontFamily: mono ? 'ui-monospace, monospace' : 'inherit', whiteSpace: 'pre-wrap' }}>{detail}</div>
      </div>
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<BootMessage title="Happy Guts" detail="Loading food data…" />);

window.loadFoodData()
  .then(() => root.render(<App />))
  .catch(err => {
    console.error(err);
    root.render(<BootMessage
      title="Couldn't load food data"
      detail={`${err.message}\n\nThe CSV tables in data/foods/ are fetched over HTTP, so open the app through a local server rather than file://\n\n  npx serve\n  # or\n  python -m http.server`}
      mono />);
  });
