// app.jsx — Mint app shell (5-tab nav, no gamification)

const { useState, useEffect, useRef } = React;

const MINT_LS = 'mint_app_v7';
const MINT_TWEAKS_LS = 'mint_tweaks_v2';

const ICON_BY_CAT_KEY = {
  'Ontbijt': 'IconCup',
  'Lunch':   'IconLeaf',
  'Diner':   'IconFlame',
  'Snacks':  'IconSeed',
  'Feest':   'IconStar',
};

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "serif": "'Playfair Display', serif",
  "accent": "#D9937A",
  "darkStatusBar": false
}/*EDITMODE-END*/;

const DEFAULT_STATE = {
  tab: 'vandaag',
  dagenActief: 49,
  naam: null,        // geladen vanuit Gebruikers tabel
  geboortedatum: null, // geladen vanuit Gebruikers tabel (YYYY-MM-DD)
  gewicht: 70,
  waterDoel: '2,1',
  waterGlazen: 3,
  supps: [],
  leefstijl: { gv: false, sv: true, kv: false },
  leefstijlLog: {}, // { 'YYYY-MM-DD': { gv, sv, kv } } — voor Voortgang
  qty: {},
  dieet: { 'Glutenvrij': false, 'Koemelkvrij': false, 'Suikervrij': false, 'Soja-vrij': false, 'Ei-vrij': false, 'Minder rundvlees': false },
  uitsluitingen: {}, // { [tag]: true } — geladen vanuit client_uitsluitingen (reden-kolom)
  receptenDB: {},    // { [titel]: recipeObject } — geladen vanuit Supabase recepten-tabel
  blogs: null,       // null = nog niet geladen; [] = geladen maar leeg; [...] = geladen
  suppletie: null,   // null = nog niet geladen; [] = geen; [...] = protocol-supplementen
  suppPct: null,     // percentage supplementen bijgehouden (0-100) uit afvinklijst
  protocol: null,    // geladen vanuit Protocollen tabel (naam, fase_titel, fase_omschrijving, fase_bulletpoints)
  aanbevolenProducten: null, // null = nog niet geladen; [] = leeg; [...] = actieve producten
  meals: { 'Ontbijt': true, 'Lunch': true, 'Diner': true, 'Snack 1': true, 'Feest': true },
  favs: {},
  waterGemiddeld: '1,8 l',
  receptenGemaakt: '17',
  // Weekplanning — key = 'Ontbijt|Lunch|Diner|Snack 1' + '_' + dayIndex (0=ma)
  weekplan: {},
  // Boodschappen — per item: { have: bool, checked: bool }
  boodschappenVers: {},
  // Boodschappenlijst geladen vanuit Supabase (weekmenu → recept_ingredienten → Ingredienten)
  boodschappenlijst: { vers: [], voorraad: [] },
  // Voorraadkast — { [naam]: bool } voor 'in huis'-status van voorraadkast-ingrediënten
  voorraadkast: {},
  // Recept-detail state
  gemaakteRecepten: {}, // { [naam]: true }
  extraBoodschappen: [], // eigen items toegevoegd vanuit recept
  receptPorties: {}, // { [naam]: N }
  // Eigen recepten — { [naam]: { cat, tag, time, Ic, prem:false, ings:[], steps:[], thirza:'', source:'self' } }
  eigenRecepten: {},
  // Opgeslagen artikelen — { [articleId]: true }
  savedArticles: {},
  // Cross-screen intent: open SwapSheet voor specifieke {meal, day} bij volgende mount van Recepten
  swapIntent: null,
  // Cross-screen intent: open Lees & Leer met een specifieke categorie voorgeselecteerd
  kennisCatIntent: null,
  // Reflecties per datum — { 'YYYY-MM-DD': { mood: 1..5, tags: {...}, note: '' } }
  reflecties: (() => {
    const out = {};
    const fmt = (d) => `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;
    const seeds = [
      { back: 1, mood: 4, tags: { energie: ['oké'], slaap: ['voldoende'], spijsvertering: ['rustig'] }, note: 'Vandaag minder opgeblazen na de lunch.' },
      { back: 2, mood: 3, tags: { energie: ['moe'], slaap: ['onrustig'], stemming: ['gespannen'] }, note: '' },
      { back: 4, mood: 4, tags: { energie: ['fit'], spijsvertering: ['goed'], stemming: ['kalm'] }, note: '' },
    ];
    seeds.forEach(s => {
      const d = new Date();
      d.setDate(d.getDate() - s.back);
      out[fmt(d)] = { mood: s.mood, tags: s.tags, note: s.note, savedAt: Date.now() };
    });
    return out;
  })(),
  // Cross-screen intent: open Reflectie-formulier bij volgende mount van Voortgang
  openReflectie: false,
  // Meldingen-instellingen op Profiel-scherm
  meldingen: {
    dagelijks: true,
    dagelijksTijd: '08:00',
    dagreflectie: true,
    dagreflectieTijd: '21:00',
    bemoediging: true,
    mijlpalen: true,
  },
  // Actieve bemoediging — geladen vanuit Supabase (bemoedigingen tabel) op basis van dag/fase.
  // null = geen match of nog niet geladen.
  bemoediging: null,
  // Statische demo-toestand: mijlpaal bottom sheet zichtbaar over Vandaag.
  mijlpaalSheetOpen: true,
};

function StatusBarMint({ dark }) {
  const c = dark ? '#9BBAB3' : '#2F4F4F';
  return (
    <div style={{
      height: 44, background: dark ? '#1a2e28' : '#F9F9F9',
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      padding: '0 28px', fontSize: 13, color: c, fontWeight: 500,
      position: 'relative', zIndex: 3,
    }}>
      <span>9:41</span>
      <span style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
        <svg width="17" height="11" viewBox="0 0 17 11" fill="none">
          <rect x="0" y="7" width="3" height="4" rx="0.5" fill={c}/>
          <rect x="4.5" y="5" width="3" height="6" rx="0.5" fill={c}/>
          <rect x="9" y="3" width="3" height="8" rx="0.5" fill={c}/>
          <rect x="13.5" y="0" width="3" height="11" rx="0.5" fill={c}/>
        </svg>
        <svg width="23" height="11" viewBox="0 0 23 11" fill="none">
          <rect x="0.5" y="0.5" width="20" height="10" rx="2.5" stroke={c} fillOpacity="0.4"/>
          <rect x="2" y="2" width="17" height="7" rx="1.5" fill={c}/>
        </svg>
      </span>
    </div>
  );
}

function BottomNav({ tab, setTab }) {
  const items = [
    { id: 'vandaag',  l: 'Vandaag',  Ic: IconToday },
    { id: 'recepten', l: 'Recepten', Ic: IconBook },
    { id: 'kennis',   l: 'Lees & Leer', Ic: IconSparkle },
    { id: 'bestellen',l: 'Bestellen',Ic: IconBag },
    { id: 'voortgang',l: 'Voortgang',Ic: IconChart },
  ];
  return (
    <div style={{
      background: '#fff', borderTop: '1px solid #efefef',
      display: 'flex', padding: '10px 0 24px', flexShrink: 0,
      position: 'relative', zIndex: 4,
    }}>
      {items.map(it => {
        const on = tab === it.id;
        return (
          <div key={it.id} onClick={() => setTab(it.id)} style={{
            flex: 1, display: 'flex', flexDirection: 'column',
            alignItems: 'center', gap: 4, cursor: 'pointer',
            padding: '4px 0',
          }}>
            <it.Ic size={22} color={on ? '#6B8F84' : '#7a7a7a'} stroke={on ? 1.8 : 1.7}/>
            <span style={{
              fontSize: 9, fontWeight: on ? 500 : 400,
              color: on ? '#6B8F84' : '#6e6e6e',
              whiteSpace: 'nowrap',
            }}>{it.l}</span>
          </div>
        );
      })}
    </div>
  );
}

function HeaderBar({ dark, onProfile, profileActive, naam }) {
  return (
    <div style={{
      background: dark ? '#1a2e28' : '#F9F9F9',
      padding: '8px 22px 12px',
      display: 'flex', justifyContent: 'center', alignItems: 'center',
      position: 'relative', zIndex: 2,
      borderBottom: dark ? 'none' : '1px solid #efefef',
    }}>
      <span style={{
        fontFamily: "'Playfair Display', serif",
        fontWeight: 400, fontSize: 22,
        color: dark ? '#9BBAB3' : '#6B8F84',
        letterSpacing: '0.04em',
      }}>Mint</span>
      <div
        onClick={onProfile}
        aria-label="Profiel"
        style={{
          position: 'absolute', right: 18, top: '50%', transform: 'translateY(-50%)',
          width: 32, height: 32, borderRadius: '50%',
          background: '#82A898',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontFamily: "'Playfair Display', serif",
          fontSize: 15, color: '#fff', cursor: 'pointer',
          boxShadow: profileActive ? '0 0 0 2px #fff, 0 0 0 4px #82A898' : 'none',
          transition: 'box-shadow .15s',
          userSelect: 'none',
        }}
      >{naam ? naam[0].toUpperCase() : 'T'}</div>
    </div>
  );
}

function TweaksPanel({ tweaks, setTweaks, onClose, state, setState }) {
  const set = (k, v) => {
    setTweaks(t => ({ ...t, [k]: v }));
    try { window.parent.postMessage({ type: '__edit_mode_set_keys', edits: { [k]: v } }, '*'); } catch(e){}
  };
  return (
    <div style={{
      position: 'fixed', right: 16, bottom: 16, width: 260,
      background: '#fff', borderRadius: 14, padding: 16,
      boxShadow: '0 10px 30px rgba(0,0,0,0.18)',
      fontFamily: "'Montserrat', sans-serif", zIndex: 9999,
    }}>
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom: 12 }}>
        <span style={{ fontFamily: "'Playfair Display', serif", fontSize: 17, color: '#2F4F4F' }}>Tweaks</span>
        <div onClick={onClose} style={{ cursor: 'pointer' }}><IconClose size={16} color="#999"/></div>
      </div>

      <div style={{ fontSize: 10.5, color: '#82A898', marginBottom: 6, letterSpacing: '0.02em' }}>Koppenfont</div>
      <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 14 }}>
        {[
          ["'Playfair Display', serif", 'Playfair'],
          ["'Cormorant Garamond', serif", 'Cormorant'],
          ["'DM Serif Display', serif", 'DM Serif'],
          ["'Fraunces', serif", 'Fraunces'],
        ].map(([f, l]) => (
          <div key={f} onClick={() => set('serif', f)} style={{
            fontFamily: f, fontSize: 12, padding: '5px 10px', borderRadius: 16,
            border: tweaks.serif === f ? '1px solid #82A898' : '1px solid #e0e0e0',
            background: tweaks.serif === f ? '#eaf2ef' : '#fff',
            color: '#2F4F4F', cursor: 'pointer',
          }}>{l}</div>
        ))}
      </div>

      <div style={{ fontSize: 10.5, color: '#82A898', marginBottom: 6, letterSpacing: '0.02em' }}>Accentkleur</div>
      <div style={{ display: 'flex', gap: 8, marginBottom: 14 }}>
        {['#D9937A','#E0A899','#C28872','#A8998A','#82A898'].map(c => (
          <div key={c} onClick={() => set('accent', c)} style={{
            width: 26, height: 26, borderRadius: '50%', background: c, cursor: 'pointer',
            boxShadow: tweaks.accent === c ? '0 0 0 2px #82A898, 0 0 0 4px #fff' : 'none',
          }}/>
        ))}
      </div>

      <div style={{ fontSize: 10.5, color: '#82A898', marginBottom: 6, letterSpacing: '0.02em' }}>Statusbalk</div>
      <div style={{ display:'flex', gap: 6, marginBottom: 14 }}>
        {[[false, 'Licht'], [true, 'Donker']].map(([v, l]) => (
          <div key={l} onClick={() => set('darkStatusBar', v)} style={{
            fontSize: 12, padding: '5px 12px', borderRadius: 16,
            border: tweaks.darkStatusBar === v ? '1px solid #82A898' : '1px solid #e0e0e0',
            background: tweaks.darkStatusBar === v ? '#eaf2ef' : '#fff',
            color: '#2F4F4F', cursor: 'pointer',
          }}>{l}</div>
        ))}
      </div>

      <div style={{ fontSize: 10.5, color: '#82A898', marginBottom: 6, letterSpacing: '0.02em' }}>Mijlpaal-overlay (Vandaag)</div>
      <div style={{ display:'flex', gap: 6, marginBottom: 14 }}>
        {[[true, 'Toon'], [false, 'Verberg']].map(([v, l]) => {
          const on = !!(state && state.mijlpaalSheetOpen) === v;
          return (
            <div key={l} onClick={() => {
              setState(s => ({ ...s, mijlpaalSheetOpen: v, tab: v ? 'vandaag' : s.tab }));
            }} style={{
              fontSize: 12, padding: '5px 12px', borderRadius: 16,
              border: on ? '1px solid #82A898' : '1px solid #e0e0e0',
              background: on ? '#eaf2ef' : '#fff',
              color: '#2F4F4F', cursor: 'pointer',
            }}>{l}</div>
          );
        })}
      </div>

      <div style={{ fontSize: 10.5, color: '#999', lineHeight: 1.5 }}>
        Schakel tweaks uit met de toggle bovenin om de definitieve app te zien.
      </div>
    </div>
  );
}

function MijlpaalSheet({ open, bemoediging, onClose, onGoVandaag }) {
  if (!open || !bemoediging) return null;
  const dagLabel = bemoediging.dag != null ? `Van Thirza · Dag ${bemoediging.dag}` : 'Van Thirza';
  return (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 50,
      display: 'flex', flexDirection: 'column', justifyContent: 'flex-end',
      pointerEvents: 'auto',
    }}>
      {/* Scrim — vervaagt het Vandaag-scherm op de achtergrond */}
      <div
        onClick={onClose}
        style={{
          position: 'absolute', inset: 0,
          background: 'rgba(0,0,0,0.25)',
          animation: 'mintFadeIn .25s ease',
        }}
      />
      {/* Sheet zelf */}
      <div style={{
        position: 'relative',
        height: '55%',
        background: '#FFFFFF',
        borderTopLeftRadius: 20, borderTopRightRadius: 20,
        padding: '12px 26px 26px',
        display: 'flex', flexDirection: 'column',
        boxShadow: '0 -8px 30px rgba(0,0,0,0.15)',
        animation: 'mintSlideUp .35s cubic-bezier(.2,.8,.2,1)',
      }}>
        {/* Trekkerbalk */}
        <div style={{
          width: 40, height: 4, borderRadius: 2, background: '#E0E0E0',
          margin: '0 auto 22px', flexShrink: 0,
        }}/>

        {/* Label */}
        <div style={{
          fontFamily: "'Montserrat', sans-serif", fontWeight: 500,
          fontSize: 10, color: '#D9937A', letterSpacing: '0.06em',
          textTransform: 'uppercase', marginBottom: 14,
        }}>{dagLabel}</div>

        {/* Bemoedigingstekst */}
        <div style={{
          fontFamily: (window.__mintTheme && window.__mintTheme.serif) || "'Playfair Display', serif",
          fontSize: 15, color: '#2F4F4F', lineHeight: 1.7,
          marginBottom: 14,
        }}>
          {bemoediging.tekst}
        </div>

        {/* Auteursregel */}
        <div style={{
          fontSize: 10, color: '#9BBAB3', fontStyle: 'italic',
          lineHeight: 1.5, marginBottom: 'auto',
        }}>
          Samengesteld door Thirza Wondergem, natuurgeneeskundig therapeut bij Mint.
        </div>

        {/* Knoppen */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 22 }}>
          <button
            onClick={onGoVandaag}
            style={{
              background: '#82A898', color: '#fff', border: 'none',
              borderRadius: 12, padding: '14px 18px',
              fontSize: 14, fontWeight: 500, cursor: 'pointer',
              fontFamily: "'Montserrat', sans-serif",
            }}
          >Ga naar vandaag</button>
          <button
            onClick={onClose}
            style={{
              background: 'transparent', color: '#6B8F84',
              border: '1px solid #82A898', borderRadius: 12, padding: '13px 18px',
              fontSize: 14, fontWeight: 500, cursor: 'pointer',
              fontFamily: "'Montserrat', sans-serif",
            }}
          >Sluiten</button>
        </div>
      </div>
    </div>
  );
}

// ─── Login / Aanmelden schermen ───────────────────────────────────────────────
function AuthScherm() {
  const [modus, setModus] = React.useState('login');
  if (modus === 'aanmelden') return <AanmeldenScherm onTerug={() => setModus('login')}/>;
  if (modus === 'vergeten')  return <WachtwoordVergetenScherm onTerug={() => setModus('login')}/>;
  return <LoginScherm onAanmelden={() => setModus('aanmelden')} onVergeten={() => setModus('vergeten')}/>;
}

function LoginScherm({ onAanmelden, onVergeten }) {
  const [email, setEmail]           = React.useState('');
  const [wachtwoord, setWachtwoord] = React.useState('');
  const [fout, setFout]             = React.useState('');
  const [laden, setLaden]           = React.useState(false);

  const login = async () => {
    if (!email || !wachtwoord) { setFout('Vul je e-mailadres en wachtwoord in.'); return; }
    setLaden(true); setFout('');
    const { error } = await window.MintDB.inloggen(email, wachtwoord);
    setLaden(false);
    if (error) {
      setFout(error.message === 'Invalid login credentials'
        ? 'E-mail of wachtwoord klopt niet.'
        : error.message);
    }
    // Bij succes vuurt onAuthChange in App — scherm wisselt automatisch.
  };

  const invoerStijl = {
    width: '100%', border: '1px solid #cfe0db', borderRadius: 10,
    padding: '12px 14px', fontSize: 14, color: '#2F4F4F',
    fontFamily: "'Montserrat', sans-serif", outline: 'none', background: '#fff',
  };

  return (
    <div style={{
      minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center',
      background: 'linear-gradient(180deg, #dfe8e4 0%, #cfd9d4 100%)',
      fontFamily: "'Montserrat', sans-serif", padding: 20,
    }}>
      <div style={{
        width: 340, background: '#fff', borderRadius: 20, padding: '36px 28px',
        boxShadow: '0 8px 40px rgba(47,79,79,0.15)',
      }}>
        <div style={{
          fontFamily: serif(), fontSize: 34, color: '#6B8F84',
          letterSpacing: '0.04em', textAlign: 'center', marginBottom: 6,
        }}>Mint</div>
        <div style={{ fontSize: 13, color: '#82A898', textAlign: 'center', marginBottom: 28 }}>
          Welkom terug
        </div>

        {[
          { lbl: 'E-mailadres',  val: email,      set: setEmail,      type: 'email',    ph: 'naam@voorbeeld.nl' },
          { lbl: 'Wachtwoord',   val: wachtwoord, set: setWachtwoord, type: 'password', ph: '••••••••' },
        ].map(({ lbl, val, set, type, ph }) => (
          <div key={lbl} style={{ marginBottom: 14 }}>
            <div style={{ fontSize: 11.5, color: '#82A898', marginBottom: 6 }}>{lbl}</div>
            <input
              type={type} value={val} placeholder={ph}
              onChange={e => set(e.target.value)}
              onKeyDown={e => e.key === 'Enter' && login()}
              style={invoerStijl}
            />
          </div>
        ))}

        {fout && (
          <div style={{
            background: '#fff0ee', border: '1px solid #f5cdc8', borderRadius: 8,
            padding: '10px 12px', fontSize: 13, color: '#c0392b', marginBottom: 14, lineHeight: 1.5,
          }}>{fout}</div>
        )}

        <div onClick={!laden ? login : null} style={{
          background: laden ? '#c0d4cc' : '#82A898', color: '#fff', borderRadius: 12,
          padding: '14px 18px', textAlign: 'center', fontSize: 14, fontWeight: 500,
          cursor: laden ? 'default' : 'pointer', marginBottom: 16, transition: 'background .15s',
        }}>{laden ? 'Inloggen…' : 'Inloggen'}</div>

        <div style={{ textAlign: 'center', fontSize: 12.5, color: '#888' }}>
          Nog geen account?{' '}
          <span onClick={onAanmelden} style={{ color: '#D9937A', cursor: 'pointer', textDecoration: 'underline' }}>
            Aanmelden
          </span>
        </div>
        <div style={{ textAlign: 'center', marginTop: 10, fontSize: 12.5 }}>
          <span onClick={onVergeten} style={{ color: '#82A898', cursor: 'pointer', textDecoration: 'underline' }}>
            Wachtwoord vergeten?
          </span>
        </div>
      </div>
    </div>
  );
}

function WachtwoordVergetenScherm({ onTerug }) {
  const [email, setEmail] = React.useState('');
  const [fout, setFout]   = React.useState('');
  const [laden, setLaden] = React.useState(false);
  const [klaar, setKlaar] = React.useState(false);

  const verstuur = async () => {
    if (!email) { setFout('Vul je e-mailadres in.'); return; }
    setLaden(true); setFout('');
    const { error } = await window.MintDB.stuurWachtwoordReset(email);
    setLaden(false);
    if (error) { setFout(error.message); return; }
    setKlaar(true);
  };

  const invoerStijl = {
    width: '100%', border: '1px solid #cfe0db', borderRadius: 10,
    padding: '12px 14px', fontSize: 14, color: '#2F4F4F',
    fontFamily: "'Montserrat', sans-serif", outline: 'none', background: '#fff',
  };

  return (
    <div style={{
      minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center',
      background: 'linear-gradient(180deg, #dfe8e4 0%, #cfd9d4 100%)',
      fontFamily: "'Montserrat', sans-serif", padding: 20,
    }}>
      <div style={{
        width: 340, background: '#fff', borderRadius: 20, padding: '36px 28px',
        boxShadow: '0 8px 40px rgba(47,79,79,0.15)',
      }}>
        <div style={{
          fontFamily: serif(), fontSize: 34, color: '#6B8F84',
          letterSpacing: '0.04em', textAlign: 'center', marginBottom: 6,
        }}>Mint</div>
        <div style={{ fontSize: 13, color: '#82A898', textAlign: 'center', marginBottom: 28 }}>
          Wachtwoord vergeten
        </div>

        {klaar ? (
          <div style={{
            background: '#f0f8f5', border: '1px solid #b5d9ce', borderRadius: 8,
            padding: '14px 12px', fontSize: 13, color: '#2F4F4F', marginBottom: 20,
            lineHeight: 1.6, textAlign: 'center',
          }}>
            We hebben een resetlink gestuurd naar <strong>{email}</strong>.
            Controleer ook je spammap.
          </div>
        ) : (
          <>
            <div style={{ fontSize: 13, color: '#82A898', marginBottom: 20, lineHeight: 1.6 }}>
              Vul je e-mailadres in. We sturen je een link waarmee je een nieuw wachtwoord kunt instellen.
            </div>
            <div style={{ marginBottom: 14 }}>
              <div style={{ fontSize: 11.5, color: '#82A898', marginBottom: 6 }}>E-mailadres</div>
              <input
                type="email" value={email} placeholder="naam@voorbeeld.nl"
                onChange={e => setEmail(e.target.value)}
                onKeyDown={e => e.key === 'Enter' && verstuur()}
                style={invoerStijl}
              />
            </div>
            {fout && (
              <div style={{
                background: '#fff0ee', border: '1px solid #f5cdc8', borderRadius: 8,
                padding: '10px 12px', fontSize: 13, color: '#c0392b', marginBottom: 14, lineHeight: 1.5,
              }}>{fout}</div>
            )}
            <div onClick={!laden ? verstuur : null} style={{
              background: laden ? '#c0d4cc' : '#82A898', color: '#fff', borderRadius: 12,
              padding: '14px 18px', textAlign: 'center', fontSize: 14, fontWeight: 500,
              cursor: laden ? 'default' : 'pointer', marginBottom: 16, transition: 'background .15s',
            }}>{laden ? 'Versturen…' : 'Resetlink versturen'}</div>
          </>
        )}

        <div style={{ textAlign: 'center', fontSize: 12.5 }}>
          <span onClick={onTerug} style={{ color: '#D9937A', cursor: 'pointer', textDecoration: 'underline' }}>
            Terug naar inloggen
          </span>
        </div>
      </div>
    </div>
  );
}

function NieuwWachtwoordScherm({ onKlaar }) {
  const [wachtwoord, setWachtwoord] = React.useState('');
  const [bevestig, setBevestig]     = React.useState('');
  const [fout, setFout]             = React.useState('');
  const [laden, setLaden]           = React.useState(false);
  const [klaar, setKlaar]           = React.useState(false);

  const opslaan = async () => {
    if (!wachtwoord || !bevestig)  { setFout('Vul beide velden in.'); return; }
    if (wachtwoord.length < 6)     { setFout('Wachtwoord moet minimaal 6 tekens zijn.'); return; }
    if (wachtwoord !== bevestig)   { setFout('Wachtwoorden komen niet overeen.'); return; }
    setLaden(true); setFout('');
    const { error } = await window.MintDB.updateWachtwoord(wachtwoord);
    setLaden(false);
    if (error) { setFout(error.message); return; }
    setKlaar(true);
    setTimeout(onKlaar, 2000);
  };

  const invoerStijl = {
    width: '100%', border: '1px solid #cfe0db', borderRadius: 10,
    padding: '12px 14px', fontSize: 14, color: '#2F4F4F',
    fontFamily: "'Montserrat', sans-serif", outline: 'none', background: '#fff',
  };

  return (
    <div style={{
      minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center',
      background: 'linear-gradient(180deg, #dfe8e4 0%, #cfd9d4 100%)',
      fontFamily: "'Montserrat', sans-serif", padding: 20,
    }}>
      <div style={{
        width: 340, background: '#fff', borderRadius: 20, padding: '36px 28px',
        boxShadow: '0 8px 40px rgba(47,79,79,0.15)',
      }}>
        <div style={{
          fontFamily: serif(), fontSize: 34, color: '#6B8F84',
          letterSpacing: '0.04em', textAlign: 'center', marginBottom: 6,
        }}>Mint</div>
        <div style={{ fontSize: 13, color: '#82A898', textAlign: 'center', marginBottom: 28 }}>
          Nieuw wachtwoord instellen
        </div>

        {klaar ? (
          <div style={{
            background: '#f0f8f5', border: '1px solid #b5d9ce', borderRadius: 8,
            padding: '14px 12px', fontSize: 13, color: '#2F4F4F', lineHeight: 1.6,
            textAlign: 'center',
          }}>
            Wachtwoord opgeslagen. Je wordt doorgestuurd naar inloggen…
          </div>
        ) : (
          <>
            {[
              { lbl: 'Nieuw wachtwoord',    val: wachtwoord, set: setWachtwoord },
              { lbl: 'Bevestig wachtwoord', val: bevestig,   set: setBevestig  },
            ].map(({ lbl, val, set }) => (
              <div key={lbl} style={{ marginBottom: 14 }}>
                <div style={{ fontSize: 11.5, color: '#82A898', marginBottom: 6 }}>{lbl}</div>
                <input
                  type="password" value={val} placeholder="••••••••"
                  onChange={e => set(e.target.value)}
                  onKeyDown={e => e.key === 'Enter' && opslaan()}
                  style={invoerStijl}
                />
              </div>
            ))}
            {fout && (
              <div style={{
                background: '#fff0ee', border: '1px solid #f5cdc8', borderRadius: 8,
                padding: '10px 12px', fontSize: 13, color: '#c0392b', marginBottom: 14, lineHeight: 1.5,
              }}>{fout}</div>
            )}
            <div onClick={!laden ? opslaan : null} style={{
              background: laden ? '#c0d4cc' : '#82A898', color: '#fff', borderRadius: 12,
              padding: '14px 18px', textAlign: 'center', fontSize: 14, fontWeight: 500,
              cursor: laden ? 'default' : 'pointer', transition: 'background .15s',
            }}>{laden ? 'Opslaan…' : 'Wachtwoord opslaan'}</div>
          </>
        )}
      </div>
    </div>
  );
}

function AanmeldenScherm({ onTerug }) {
  const [naam, setNaam]             = React.useState('');
  const [email, setEmail]           = React.useState('');
  const [wachtwoord, setWachtwoord] = React.useState('');
  const [fout, setFout]             = React.useState('');
  const [laden, setLaden]           = React.useState(false);
  const [klaar, setKlaar]           = React.useState(false);

  const aanmelden = async () => {
    if (!naam || !email || !wachtwoord) { setFout('Vul alle velden in.'); return; }
    if (wachtwoord.length < 6) { setFout('Wachtwoord moet minimaal 6 tekens zijn.'); return; }
    setLaden(true); setFout('');
    const { error } = await window.MintDB.registreren(email, wachtwoord, naam);
    setLaden(false);
    if (error) setFout(error.message);
    else setKlaar(true);
  };

  const invoerStijl = {
    width: '100%', border: '1px solid #cfe0db', borderRadius: 10,
    padding: '12px 14px', fontSize: 14, color: '#2F4F4F',
    fontFamily: "'Montserrat', sans-serif", outline: 'none', background: '#fff',
  };
  const wrapper = {
    minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center',
    background: 'linear-gradient(180deg, #dfe8e4 0%, #cfd9d4 100%)',
    fontFamily: "'Montserrat', sans-serif", padding: 20,
  };
  const kaart = {
    width: 340, background: '#fff', borderRadius: 20, padding: '36px 28px',
    boxShadow: '0 8px 40px rgba(47,79,79,0.15)',
  };

  if (klaar) return (
    <div style={wrapper}>
      <div style={{ ...kaart, textAlign: 'center' }}>
        <div style={{ fontFamily: serif(), fontSize: 34, color: '#6B8F84', marginBottom: 16 }}>Mint</div>
        <div style={{ fontSize: 15, fontWeight: 500, color: '#2F4F4F', marginBottom: 8 }}>Controleer je e-mail</div>
        <div style={{ fontSize: 13, color: '#82A898', lineHeight: 1.65, marginBottom: 22 }}>
          We stuurden een bevestigingslink naar <strong>{email}</strong>.
          Klik op de link en log daarna in.
        </div>
        <div onClick={onTerug} style={{
          background: '#82A898', color: '#fff', borderRadius: 12,
          padding: '13px 18px', fontSize: 14, fontWeight: 500, cursor: 'pointer', textAlign: 'center',
        }}>Terug naar inloggen</div>
      </div>
    </div>
  );

  return (
    <div style={wrapper}>
      <div style={kaart}>
        <div style={{
          fontFamily: serif(), fontSize: 34, color: '#6B8F84',
          letterSpacing: '0.04em', textAlign: 'center', marginBottom: 6,
        }}>Mint</div>
        <div style={{ fontSize: 13, color: '#82A898', textAlign: 'center', marginBottom: 28 }}>Account aanmaken</div>

        {[
          { lbl: 'Naam',       val: naam,       set: setNaam,       type: 'text',     ph: 'Jouw naam' },
          { lbl: 'E-mailadres',val: email,       set: setEmail,      type: 'email',    ph: 'naam@voorbeeld.nl' },
          { lbl: 'Wachtwoord', val: wachtwoord, set: setWachtwoord, type: 'password', ph: '••••••••' },
        ].map(({ lbl, val, set, type, ph }) => (
          <div key={lbl} style={{ marginBottom: 14 }}>
            <div style={{ fontSize: 11.5, color: '#82A898', marginBottom: 6 }}>{lbl}</div>
            <input type={type} value={val} placeholder={ph}
              onChange={e => set(e.target.value)}
              onKeyDown={e => e.key === 'Enter' && aanmelden()}
              style={invoerStijl}
            />
          </div>
        ))}

        {fout && (
          <div style={{
            background: '#fff0ee', border: '1px solid #f5cdc8', borderRadius: 8,
            padding: '10px 12px', fontSize: 13, color: '#c0392b', marginBottom: 14,
          }}>{fout}</div>
        )}

        <div onClick={!laden ? aanmelden : null} style={{
          background: laden ? '#c0d4cc' : '#82A898', color: '#fff', borderRadius: 12,
          padding: '14px 18px', textAlign: 'center', fontSize: 14, fontWeight: 500,
          cursor: laden ? 'default' : 'pointer', marginBottom: 16,
        }}>{laden ? 'Aanmelden…' : 'Aanmelden'}</div>

        <div style={{ textAlign: 'center', fontSize: 12.5, color: '#888' }}>
          Al een account?{' '}
          <span onClick={onTerug} style={{ color: '#D9937A', cursor: 'pointer', textDecoration: 'underline' }}>Inloggen</span>
        </div>
      </div>
    </div>
  );
}

// ─── Hoofd app-component ──────────────────────────────────────────────────────
function App() {
  const [state, setState] = useState(() => {
    try {
      const s = localStorage.getItem(MINT_LS);
      if (s) {
        const saved = JSON.parse(s);
        const merged = { ...DEFAULT_STATE, ...saved };
        // Thirza-supplementen altijd opnieuw laden vanuit Supabase, nooit uit localStorage
        merged.supps = (merged.supps || []).filter(x => x.source === 'self');
        return merged;
      }
    } catch (e) {}
    return DEFAULT_STATE;
  });
  const [tweaks, setTweaks] = useState(() => {
    try {
      const s = localStorage.getItem(MINT_TWEAKS_LS);
      if (s) return { ...TWEAK_DEFAULTS, ...JSON.parse(s) };
    } catch (e) {}
    return TWEAK_DEFAULTS;
  });
  const [tweaksOpen, setTweaksOpen] = useState(false);
  const [loading, setLoading] = useState(true);
  const [authStatus, setAuthStatus] = useState('checking');

  // Auth-check bij opstarten + luister naar auth-wijzigingen
  useEffect(() => {
    if (!window.MintDB) { setAuthStatus('loggedout'); setLoading(false); return; }
    window.MintDB.haalSessie().then(sessie => {
      // Skip if a recovery token is in the URL — onAuthChange will fire PASSWORD_RECOVERY
      if (window.location.hash.includes('type=recovery')) return;
      setAuthStatus(sessie ? 'loggedin' : 'loggedout');
      if (!sessie) setLoading(false);
    });
    const sub = window.MintDB.onAuthChange((event, sessie) => {
      if (event === 'PASSWORD_RECOVERY') {
        setAuthStatus('recovery');
        setLoading(false);
        return;
      }
      setAuthStatus(sessie ? 'loggedin' : 'loggedout');
      if (!sessie) setLoading(false);
    });
    return () => sub.unsubscribe();
  }, []);

  // Laad profiel en supplementen na succesvolle login
  useEffect(() => {
    if (authStatus !== 'loggedin') return;
    (async () => {
      try {
        const [profiel, supps, reflecties, weekplan, favs, artikelen, uitsluitingen, receptenData, boodschappenlijst, blogsData, suppletieData, voortgangData, protocolData, aanbevolenData] = await Promise.all([
          window.MintDB.laadProfiel(),
          window.MintDB.laadSupplementen(),
          window.MintDB.laadReflecties(),
          window.MintDB.laadWeekmenu(),
          window.MintDB.laadFavorieten(),
          window.MintDB.laadBewaardeArtikelen(),
          window.MintDB.laadUitsluitingen(),
          window.MintDB.laadRecepten(),
          window.MintDB.laadBoodschappenlijst(),
          window.MintDB.laadBlogs(),
          window.MintDB.laadSuppletie(),
          window.MintDB.laadVoortgangCijfers(),
          window.MintDB.laadProtocol(),
          window.MintDB.laadAanbevolenProducten(),
        ]);
        setState(prev => {
          const patch = {};
          if (profiel) {
            if (profiel.naam != null)              patch.naam = profiel.naam;
            if (profiel.geboortedatum != null)     patch.geboortedatum = profiel.geboortedatum;
            if (profiel.lichaamsgewicht_kg != null) patch.gewicht = profiel.lichaamsgewicht_kg;
          }
          if (supps !== null)               patch.supps      = supps ?? [];
          if (reflecties)                  patch.reflecties  = reflecties;
          if (weekplan !== null) patch.weekplan = weekplan;
          if (favs)                        patch.favs        = favs;
          if (artikelen)                   patch.savedArticles = artikelen;
          if (uitsluitingen !== null)      patch.uitsluitingen = uitsluitingen;
          if (boodschappenlijst !== null)  patch.boodschappenlijst = boodschappenlijst;
          patch.blogs = blogsData ?? [];
          if (suppletieData != null) patch.suppletie = suppletieData;
          if (voortgangData) {
            if (voortgangData.dagenOnderweg > 0) patch.dagenActief = voortgangData.dagenOnderweg;
            if (voortgangData.suppPct != null)   patch.suppPct = voortgangData.suppPct;
            if (voortgangData.waterGem)          patch.waterGemiddeld = voortgangData.waterGem;
            patch.receptenGemaakt = String(voortgangData.receptenGemaakt);
          }
          if (protocolData) patch.protocol = protocolData;
          if (aanbevolenData !== null) patch.aanbevolenProducten = aanbevolenData;
          patch.bemoediging = null;
          if (receptenData && receptenData.length > 0) {
            const db = {};
            receptenData.forEach(r => {
              // Normaliseer kommagescheiden categorieën: "lunch,ontbijt" → ["Lunch","Ontbijt"]
              const cats = (r.categorie || '').split(',')
                .map(c => { const t = c.trim(); return t ? t[0].toUpperCase() + t.slice(1).toLowerCase() : ''; })
                .filter(Boolean);
              db[r.titel] = {
                cat:      cats.join(', '),          // display: "Lunch, Ontbijt"
                cats:     cats,                     // array voor matching: ["Lunch","Ontbijt"]
                tag:      r.bereidingstijd ? `${r.bereidingstijd} min` : '',
                time:     r.bereidingstijd || 0,
                Ic:       ICON_BY_CAT_KEY[cats[0]] || 'IconBowl',
                prem:     !!r.is_premium,
                tags:     r.tags || '',
                icon_tag: r.icon_tag || null,
                bereiding: r.bereiding || '',
                ings:     [],
                steps:    [],
                thirza:   '',
                personen: r.personen || 2,
                seizoen:  r.seizoen  || null,
                id:       r.id,
              };
            });
            patch.receptenDB = db;
          }
          return { ...prev, ...patch };
        });

        // Bemoediging hangt af van dag+fase, dus na de eerste batch laden
        const dag = voortgangData?.dagenOnderweg ?? null;
        const fase = protocolData?.actieveFase ?? null;
        const bemoediging = await window.MintDB.laadBemoediging(dag, fase);
        if (bemoediging) setState(prev => ({ ...prev, bemoediging }));
      } catch (e) {
        console.warn('[Mint] Laden mislukt, valback op lokale data:', e);
      } finally {
        setLoading(false);
      }
    })();
  }, [authStatus]);

  useEffect(() => {
    try { localStorage.setItem(MINT_LS, JSON.stringify(state)); } catch(e){}
  }, [state]);
  useEffect(() => {
    try { localStorage.setItem(MINT_TWEAKS_LS, JSON.stringify(tweaks)); } catch(e){}
    window.__mintTheme = tweaks;
  }, [tweaks]);

  useEffect(() => {
    const handler = (e) => {
      if (!e.data) return;
      if (e.data.type === '__activate_edit_mode') setTweaksOpen(true);
      if (e.data.type === '__deactivate_edit_mode') setTweaksOpen(false);
    };
    window.addEventListener('message', handler);
    try { window.parent.postMessage({ type: '__edit_mode_available' }, '*'); } catch(e){}
    return () => window.removeEventListener('message', handler);
  }, []);

  window.__mintTheme = tweaks;

  // Alle hooks moeten vóór elke vroege return staan (React-regel)
  const scrollRef = useRef(null);
  useEffect(() => { if (scrollRef.current) scrollRef.current.scrollTop = 0; }, [state.tab]);

  const setTab = (tab) => setState(s => ({ ...s, tab }));

  const screens = {
    vandaag:  <ScreenVandaag  state={state} setState={setState} nav={setTab}/>,
    recepten: <ScreenRecepten state={state} setState={setState} nav={setTab}/>,
    kennis:   <ScreenKennis   state={state} setState={setState} nav={setTab}/>,
    bestellen:<ScreenBestellen state={state} setState={setState}/>,
    voortgang:<ScreenVoortgang state={state} setState={setState}/>,
    profiel:  <ScreenProfiel  state={state} setState={setState}/>,
  };

  if (authStatus === 'checking' || loading) {
    return (
      <div style={{
        minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center',
        background: 'linear-gradient(180deg, #dfe8e4 0%, #cfd9d4 100%)',
        fontFamily: "'Montserrat', sans-serif",
      }}>
        <div style={{ textAlign: 'center' }}>
          <div style={{
            fontFamily: "'Playfair Display', serif",
            fontSize: 36, color: '#6B8F84', letterSpacing: '0.04em', marginBottom: 14,
          }}>Mint</div>
          <div style={{ fontSize: 13, color: '#82A898' }}>Jouw gegevens laden…</div>
        </div>
      </div>
    );
  }

  if (authStatus === 'loggedout') return <AuthScherm/>;
  if (authStatus === 'recovery')  return <NieuwWachtwoordScherm onKlaar={() => {
    setAuthStatus('loggedout');
    window.MintDB.uitloggen();
  }}/>;

  return (
    <div style={{
      minHeight: '100vh', display: 'flex', flexDirection: 'column',
      background: '#F9F9F9', fontFamily: "'Montserrat', sans-serif",
      position: 'relative',
    }}>
      <StatusBarMint dark={tweaks.darkStatusBar}/>
      <HeaderBar
        dark={tweaks.darkStatusBar}
        onProfile={() => setTab('profiel')}
        profileActive={state.tab === 'profiel'}
        naam={state.naam}
      />

      <div ref={scrollRef} style={{ flex: 1, overflowY: 'auto', background: '#F9F9F9' }}>
        {screens[state.tab] || screens.vandaag}
      </div>

      <BottomNav tab={state.tab} setTab={setTab}/>

      {/* Mijlpaal bottom sheet — overlay over Vandaag */}
      <MijlpaalSheet
        open={state.tab === 'vandaag' && !!state.mijlpaalSheetOpen}
        bemoediging={state.bemoediging}
        onClose={() => setState(s => ({ ...s, mijlpaalSheetOpen: false }))}
        onGoVandaag={() => setState(s => ({ ...s, mijlpaalSheetOpen: false, tab: 'vandaag' }))}
      />

      {tweaksOpen && (
        <TweaksPanel tweaks={tweaks} setTweaks={setTweaks} onClose={() => setTweaksOpen(false)} state={state} setState={setState}/>
      )}
    </div>
  );
}

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