const { useState, useEffect, useMemo, useCallback, useRef } = React;
const D = window.IBIZA;

/* ── CRYPTO ─────────────────────────────────────────────── */
const SALT_KEY  = "ibiza.auth.salt";
const VERIFY_KEY= "ibiza.auth.verifier";
const VERIFY_PT = "ibiza-ok";
const enc = new TextEncoder(), dec = new TextDecoder();

async function deriveKey(pw, salt) {
  const raw = await crypto.subtle.importKey("raw", enc.encode(pw), "PBKDF2", false, ["deriveKey"]);
  return crypto.subtle.deriveKey(
    { name:"PBKDF2", salt, iterations:310000, hash:"SHA-256" },
    raw, { name:"AES-GCM", length:256 }, false, ["encrypt","decrypt"]
  );
}
async function aesEncrypt(key, pt) {
  const iv = crypto.getRandomValues(new Uint8Array(12));
  const ct = await crypto.subtle.encrypt({ name:"AES-GCM", iv }, key, enc.encode(pt));
  const b  = new Uint8Array(12 + ct.byteLength);
  b.set(iv); b.set(new Uint8Array(ct), 12);
  return btoa(String.fromCharCode(...b));
}
async function aesDecrypt(key, b64) {
  const b  = Uint8Array.from(atob(b64), c => c.charCodeAt(0));
  const pt = await crypto.subtle.decrypt({ name:"AES-GCM", iv:b.slice(0,12) }, key, b.slice(12));
  return dec.decode(pt);
}
async function register(pw) {
  const salt = crypto.getRandomValues(new Uint8Array(16));
  const key  = await deriveKey(pw, salt);
  localStorage.setItem(SALT_KEY,   btoa(String.fromCharCode(...salt)));
  localStorage.setItem(VERIFY_KEY, await aesEncrypt(key, VERIFY_PT));
  return key;
}
async function loginWithPassword(pw) {
  const saltB64 = localStorage.getItem(SALT_KEY);
  const verB64  = localStorage.getItem(VERIFY_KEY);
  if (!saltB64 || !verB64) return null;
  const key = await deriveKey(pw, Uint8Array.from(atob(saltB64), c => c.charCodeAt(0)));
  try { return (await aesDecrypt(key, verB64)) === VERIFY_PT ? key : null; } catch { return null; }
}
function isRegistered() { return !!localStorage.getItem(SALT_KEY); }

function useSecureStore(storeKey, initial, cryptoKey) {
  const [val, setVal]       = useState(initial);
  const [loaded, setLoaded] = useState(false);
  useEffect(() => {
    if (!cryptoKey) return;
    const raw = localStorage.getItem(storeKey);
    if (!raw) { setVal(initial); setLoaded(true); return; }
    aesDecrypt(cryptoKey, raw)
      .then(pt => { setVal(JSON.parse(pt)); setLoaded(true); })
      .catch(() => { setVal(initial); setLoaded(true); });
  }, [storeKey, cryptoKey]);
  const setAndSave = useCallback((next) => {
    setVal(next);
    if (!cryptoKey || !loaded) return;
    aesEncrypt(cryptoKey, JSON.stringify(next)).then(ct => localStorage.setItem(storeKey, ct));
  }, [storeKey, cryptoKey, loaded]);
  return [val, setAndSave, loaded];
}

/* ── DATE / PROFILE HELPERS ─────────────────────────────── */
function todayIso() {
  const n = new Date();
  return `${n.getFullYear()}-${String(n.getMonth()+1).padStart(2,"0")}-${String(n.getDate()).padStart(2,"0")}`;
}
function daysBetween(a, b) {
  return Math.round((new Date(b+"T00:00:00") - new Date(a+"T00:00:00")) / 86400000);
}
function addDays(iso, n) {
  const d = new Date(iso+"T00:00:00"); d.setDate(d.getDate()+n);
  return d.toISOString().slice(0,10);
}

const MAANDEN = ["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december"];
const DAGEN   = ["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"];
function fmtDate(iso, kort) {
  const d = new Date(iso+"T00:00:00"), m = MAANDEN[d.getMonth()];
  return kort ? `${d.getDate()} ${m.slice(0,3)}` : `${d.getDate()} ${m} ${d.getFullYear()}`;
}
function fmtDateNL(iso) {
  const d = new Date(iso+"T00:00:00");
  return `${DAGEN[d.getDay()]} ${d.getDate()} ${MAANDEN[d.getMonth()]} ${d.getFullYear()}`;
}

function computeWeegmomenten(p) {
  const n = Math.max(1, Math.round(daysBetween(p.startDatum, p.doelDatum)/7));
  const wl = (p.startGewicht - p.doelGewicht) / n;
  return Array.from({length:n+1}, (_,i) => ({
    week: i, label: i===0?"Start":i===n?"Doel!":`Week ${i}`,
    datum: addDays(p.startDatum, i*7),
    doel: +Math.max(p.doelGewicht, p.startGewicht - i*wl).toFixed(1),
  }));
}

function sortedEntries(weights) {
  return Object.entries(weights)
    .filter(([,v]) => v != null && v !== "")
    .sort(([a],[b]) => a.localeCompare(b))
    .map(([date,val]) => ({ date, val: +val }));
}

function trendText(entries) {
  if (entries.length < 2) return null;
  const recent = entries.slice(-7);
  const delta  = recent[recent.length-1].val - recent[0].val;
  const days   = Math.max(1, daysBetween(recent[0].date, recent[recent.length-1].date));
  const perDay = (delta / days).toFixed(2);
  if (delta < -0.3) return `De laatste ${recent.length} metingen laten een daling zien van ${Math.abs(delta).toFixed(1)} kg — dat is ${Math.abs(perDay)} kg per dag. Goed bezig!`;
  if (delta >  0.3) return `De laatste ${recent.length} metingen laten een lichte stijging zien van ${delta.toFixed(1)} kg. Dat kan door vocht of de tijd van meten zijn. Blijf consistent.`;
  return `Je gewicht is de afgelopen ${recent.length} metingen stabiel. Dat is normaal — blijf de gewoontes volhouden.`;
}

function syncSessionStorage(profiel, wm) {
  try {
    sessionStorage.setItem("ibiza.profiel",      JSON.stringify(profiel));
    sessionStorage.setItem("ibiza.weegmomenten", JSON.stringify(wm));
    sessionStorage.setItem("ibiza.data",         JSON.stringify(D));
  } catch {}
}

/* ── EMAIL VIA CLOUDFLARE WORKER ─────────────────────────── */
const WORKER_URL = "https://ibiza-mailer.hvanbiervliet6.workers.dev";

async function sendViaWorker(toEmail, subject, message) {
  try {
    const res = await fetch(WORKER_URL, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ to: toEmail, subject, message }),
    });
    return res.ok ? { ok: true } : { ok: false, error: `HTTP ${res.status}` };
  } catch(e) { return { ok: false, error: String(e) }; }
}

function buildEmailBody(profiel, date, weight, prevEntry, allEntries) {
  const kg  = n => (+n).toFixed(1).replace(".",",");
  const quotes = D.dagelijkseCitaten || [];
  const dayIdx = daysBetween(profiel.startDatum, date);
  const quote  = quotes[((dayIdx % quotes.length) + quotes.length) % Math.max(1,quotes.length)] || "";

  const totaalAf = +(profiel.startGewicht - weight).toFixed(1);
  const teGaan   = +Math.max(0, weight - profiel.doelGewicht).toFixed(1);
  const pct      = Math.max(0, Math.min(100, Math.round(
    (Math.max(0,totaalAf) / (profiel.startGewicht - profiel.doelGewicht)) * 100)));

  let deltaBlok = "";
  if (prevEntry) {
    const delta = +(weight - prevEntry.val).toFixed(2);
    const arrow = delta < 0 ? "↓" : delta > 0 ? "↑" : "=";
    deltaBlok = `Vorige meting:  ${kg(prevEntry.val)} kg  (${fmtDateNL(prevEntry.date)})\nVerschil:       ${delta>0?"+":""}${(+delta).toFixed(2).replace(".",",")} kg ${arrow}\n`;
  }

  const trend = trendText(allEntries);

  const opmerking = (() => {
    if (pct >= 100) return "Je hebt je doel bereikt! Ibiza is verdiend.";
    if (pct >= 75)  return `Je bent al ${pct}% van de weg. De eindstreep is duidelijk zichtbaar — houd dit vol!`;
    if (pct >= 50)  return `Halverwege! Je hebt al ${kg(Math.max(0,totaalAf))} kg verloren. Je lichaam reageert — het werkt.`;
    if (pct >= 25)  return `Je bent goed op weg. Nog ${kg(teGaan)} kg te gaan — dat is haalbaar als je consistent blijft.`;
    if (totaalAf < 0) return "Een kleine terugval? Geen zorgen. Eén dag is niet het hele programma. Morgen opnieuw.";
    return "Elke dag wegen en bijhouden is al meer dan de meeste mensen doen. Dat telt.";
  })();

  return `Dag ${profiel.naam}!

Je hebt je gewicht ingegeven voor ${fmtDateNL(date)}.

━━━━━━━━━━━━━━━━━━━━━━━━
JOUW METING VANDAAG
━━━━━━━━━━━━━━━━━━━━━━━━
Gewogen:        ${kg(weight)} kg
${deltaBlok}
━━━━━━━━━━━━━━━━━━━━━━━━
VOORTGANG NAAR IBIZA
━━━━━━━━━━━━━━━━━━━━━━━━
Start:       ${kg(profiel.startGewicht)} kg
Nu:          ${kg(weight)} kg
Doel:        ${kg(profiel.doelGewicht)} kg  (${fmtDate(profiel.doelDatum)})
Al kwijt:    ${kg(Math.max(0,totaalAf))} kg
Nog te gaan: ${kg(teGaan)} kg
Bereikt:     ${pct}%

━━━━━━━━━━━━━━━━━━━━━━━━
JOUW TREND
━━━━━━━━━━━━━━━━━━━━━━━━
${trend || "Houd dit bij — je trend wordt zichtbaar naarmate je meer metingen hebt."}

━━━━━━━━━━━━━━━━━━━━━━━━
QUOTE VAN DE DAG
━━━━━━━━━━━━━━━━━━━━━━━━
"${quote}"

━━━━━━━━━━━━━━━━━━━━━━━━
PERSOONLIJKE OPMERKING
━━━━━━━━━━━━━━━━━━━━━━━━
${opmerking}

Tot morgen!
— Jouw Ibiza-programma`;
}

/* ── LOGIN ───────────────────────────────────────────────── */
function LoginScreen({ onAuth }) {
  const [email, setEmail] = useState("");
  const [pw, setPw]       = useState("");
  const [conf, setConf]   = useState("");
  const [mode, setMode]   = useState(isRegistered() ? "login" : "register");
  const [error, setError] = useState("");
  const [busy, setBusy]   = useState(false);

  async function submit(e) {
    e.preventDefault(); setError(""); setBusy(true);
    try {
      if (mode === "register") {
        if (!email.trim())   { setError("Vul je e-mailadres in."); return; }
        if (pw.length < 8)   { setError("Wachtwoord moet minstens 8 tekens zijn."); return; }
        if (pw !== conf)     { setError("Wachtwoorden komen niet overeen."); return; }
        const key = await register(pw);
        localStorage.setItem("ibiza.auth.email", email.trim());
        onAuth(key, email.trim());
      } else {
        const key = await loginWithPassword(pw);
        if (!key) { setError("Ongeldig wachtwoord."); return; }
        onAuth(key, localStorage.getItem("ibiza.auth.email") || "");
      }
    } catch { setError("Er liep iets mis. Probeer opnieuw."); }
    finally  { setBusy(false); }
  }
  const stored = localStorage.getItem("ibiza.auth.email");
  return (
    <div className="login-bg"><div className="login-sun"></div>
      <div className="login-card">
        <div className="login-brand">
          <span className="login-kicker">Afvalprogramma</span>
          <span className="login-title">Op naar Ibiza</span>
          <span className="login-sub">Persoonlijk &amp; versleuteld</span>
        </div>
        <form className="login-form" onSubmit={submit}>
          {mode==="register" && (
            <div className="lf-group"><label className="lf-label">E-mailadres</label>
              <input className="lf-input" type="email" autoComplete="email" placeholder="jouw@email.com"
                value={email} onChange={e=>setEmail(e.target.value)}/></div>
          )}
          {mode==="login" && stored && (
            <div className="lf-group"><label className="lf-label">Ingelogd als</label>
              <div className="lf-static">{stored}</div></div>
          )}
          <div className="lf-group"><label className="lf-label">Wachtwoord</label>
            <input className="lf-input" type="password"
              autoComplete={mode==="register"?"new-password":"current-password"}
              placeholder={mode==="register"?"Minimaal 8 tekens":"Jouw wachtwoord"}
              value={pw} onChange={e=>setPw(e.target.value)}/></div>
          {mode==="register" && (
            <div className="lf-group"><label className="lf-label">Bevestig wachtwoord</label>
              <input className="lf-input" type="password" autoComplete="new-password"
                placeholder="Herhaal wachtwoord" value={conf} onChange={e=>setConf(e.target.value)}/></div>
          )}
          {error && <div className="lf-error">{error}</div>}
          <button className="lf-btn" type="submit" disabled={busy}>
            {busy?"Even geduld…":mode==="register"?"Account aanmaken":"Inloggen"}
          </button>
        </form>
        <div className="login-note">Jouw gegevens zijn versleuteld — enkel jij kan ze lezen.</div>
      </div>
    </div>
  );
}

/* ── ONBOARDING ──────────────────────────────────────────── */
function OnboardingScreen({ onSave }) {
  const [naamV, setNaam] = useState("");
  const [sgV,   setSg]   = useState("");
  const [dgV,   setDg]   = useState("");
  const [sdV,   setSd]   = useState(todayIso());
  const [ddV,   setDd]   = useState("");
  const [motV,  setMot]  = useState("");
  const [error, setError] = useState("");

  const naamH = e => setNaam(e.target.value);
  const sgH   = e => setSg(e.target.value);
  const dgH   = e => setDg(e.target.value);
  const sdH   = e => setSd(e.target.value);
  const ddH   = e => setDd(e.target.value);
  const motH  = e => setMot(e.target.value);

  function submit(e) {
    e.preventDefault(); setError("");
    const startG=parseFloat(sgV.replace(",",".")), doelG=parseFloat(dgV.replace(",","."));
    if (!naamV.trim())            return setError("Vul je voornaam in.");
    if (isNaN(startG)||startG<30) return setError("Vul een geldig startgewicht in.");
    if (isNaN(doelG) ||doelG<30)  return setError("Vul een geldig doelgewicht in.");
    if (doelG>=startG)            return setError("Doelgewicht moet lager zijn dan startgewicht.");
    if (!ddV)                     return setError("Kies een streefdatum.");
    if (daysBetween(sdV,ddV)<7)   return setError("Streefdatum moet minstens 1 week na de startdatum zijn.");
    onSave({naam:naamV.trim(),startGewicht:startG,doelGewicht:doelG,startDatum:sdV,doelDatum:ddV,motivatie:motV.trim()});
  }
  return (
    <div className="login-bg"><div className="login-sun"></div>
      <div className="login-card" style={{maxWidth:480}}>
        <div className="login-brand">
          <span className="login-kicker">Stap 2 van 2</span>
          <span className="login-title">Jouw programma</span>
          <span className="login-sub">Versleuteld — enkel jij ziet het.</span>
        </div>
        <form className="login-form" onSubmit={submit}>
          <div className="lf-group"><label className="lf-label">Voornaam</label>
            <input className="lf-input" type="text" placeholder="bv. Ellen" value={naamV} onChange={naamH}/></div>
          <div className="lf-row">
            <div className="lf-group"><label className="lf-label">Startgewicht (kg)</label>
              <input className="lf-input" type="text" inputMode="decimal" placeholder="bv. 90,1" value={sgV} onChange={sgH}/></div>
            <div className="lf-group"><label className="lf-label">Doelgewicht (kg)</label>
              <input className="lf-input" type="text" inputMode="decimal" placeholder="bv. 85,0" value={dgV} onChange={dgH}/></div>
          </div>
          <div className="lf-row">
            <div className="lf-group"><label className="lf-label">Startdatum</label>
              <input className="lf-input" type="date" value={sdV} onChange={sdH}/></div>
            <div className="lf-group"><label className="lf-label">Streefdatum</label>
              <input className="lf-input" type="date" value={ddV} onChange={ddH}/></div>
          </div>
          <div className="lf-group">
            <label className="lf-label">Waarom wil je dit? <span style={{fontWeight:400,opacity:.7}}>(optioneel)</span></label>
            <textarea className="lf-input lf-textarea" rows="3"
              placeholder="bv. Vol energie op het strand staan." value={motV} onChange={motH}/>
          </div>
          {error && <div className="lf-error">{error}</div>}
          <button className="lf-btn" type="submit">Programma starten →</button>
        </form>
        <div className="login-note">
          Na elke dagelijkse weging wordt automatisch een e-mail verstuurd. Stel EmailJS in via ⚙ Instellingen na het inloggen.
        </div>
      </div>
    </div>
  );
}

/* ── DAILY WEIGH-IN WIDGET ───────────────────────────────── */
function DailyWeighInWidget({ profiel, weights, setWeights, userEmail }) {
  const today   = todayIso();
  const todayVal = weights[today];
  const alreadySaved = todayVal != null && todayVal !== "";
  const [input, setInput]   = useState(alreadySaved ? String(todayVal) : "");
  const [status, setStatus] = useState(null);

  const entries   = sortedEntries(weights);
  const prevEntry = (() => {
    const before = entries.filter(e => e.date < today);
    return before.length ? before[before.length-1] : null;
  })();

  async function save(e) {
    e.preventDefault();
    const v = parseFloat(input.replace(",","."));
    if (isNaN(v) || v < 30 || v > 300) return;
    const next = { ...weights, [today]: v };
    setWeights(next);

    const allE   = sortedEntries(next);
    const body   = buildEmailBody(profiel, today, v, prevEntry, allE);
    const subj   = `${fmtDate(today,true)} ✓ — Gewicht: ${v.toFixed(1).replace(".",",")} kg`;

    setStatus("sending");
    const res = await sendViaWorker(userEmail, subj, body);
    setStatus(res.ok ? "sent" : "error");
  }

  const delta = alreadySaved && prevEntry ? +(+todayVal - prevEntry.val).toFixed(2) : null;

  return (
    <div className="checkin-banner">
      <div className="cb-sun"></div>
      <div className="cb-content">
        <div className="cb-kicker">
          <svg viewBox="0 0 24 24" fill="none" width="15" height="15" style={{flexShrink:0}}>
            <rect x="3" y="4" width="18" height="16" rx="3" stroke="currentColor" strokeWidth="2"/>
            <path d="M12 8l-2.5 4h5L12 8z" fill="currentColor"/>
            <path d="M8 16h8" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
          </svg>
          Dagelijkse weging · {fmtDate(today)}
        </div>
        <div className="cb-title">
          {alreadySaved ? "Weging van vandaag opgeslagen" : "Hoe zwaar ben je vandaag?"}
        </div>

        {alreadySaved ? (
          <div className="cb-saved">
            <span className="cb-saved-weight">
              <span className="cb-check">✓</span>
              {(+todayVal).toFixed(1).replace(".",",")} kg
            </span>
            {delta !== null && (
              <span className={"cb-delta "+(delta<=0?"good":"over")}>
                {delta<0 ? `${Math.abs(delta).toFixed(2).replace(".",",")} kg minder ↓`
                 :delta>0 ? `+${delta.toFixed(2).replace(".",",")} kg meer ↑`
                 : "gelijk aan vorige meting"}
                {prevEntry ? ` dan ${fmtDate(prevEntry.date,true)}` : ""}
              </span>
            )}
            {status==="sending" && <span className="cb-mail-status">Mail wordt verstuurd…</span>}
            {status==="sent"    && <span className="cb-mail-status ok">✓ Mail verzonden!</span>}
            {status==="error"   && <span className="cb-mail-status">Mail mislukt — probeer opnieuw.</span>}
          </div>
        ) : (
          <form className="cb-form" onSubmit={save}>
            <input className="cb-input" type="text" inputMode="decimal"
              placeholder="bv. 87,4" value={input} onChange={e=>setInput(e.target.value)} autoFocus/>
            <span className="cb-unit">kg</span>
            <button className="cb-btn" type="submit">Opslaan &amp; mailen</button>
          </form>
        )}
      </div>
    </div>
  );
}

/* ── ICONS ───────────────────────────────────────────────── */
const icons = {
  overzicht:<svg className="nav-ico" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="4" stroke="currentColor" strokeWidth="2"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3M5 5l2 2M17 17l2 2M19 5l-2 2M7 17l-2 2" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/></svg>,
  weeg: <svg className="nav-ico" viewBox="0 0 24 24" fill="none"><rect x="3" y="4" width="18" height="16" rx="3" stroke="currentColor" strokeWidth="2"/><path d="M12 8l-2.5 4h5L12 8z" fill="currentColor"/><path d="M8 16h8" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/></svg>,
  menu: <svg className="nav-ico" viewBox="0 0 24 24" fill="none"><path d="M5 3v18M5 3c2 0 2 4 0 4M19 3v18M16 3v6a3 3 0 003 3" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  shop: <svg className="nav-ico" viewBox="0 0 24 24" fill="none"><path d="M5 8h14l-1 11a2 2 0 01-2 2H8a2 2 0 01-2-2L5 8z" stroke="currentColor" strokeWidth="2" strokeLinejoin="round"/><path d="M9 8V6a3 3 0 016 0v2" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/></svg>,
  move: <svg className="nav-ico" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="5" r="2" stroke="currentColor" strokeWidth="2"/><path d="M12 8v6m0 0l-3 5m3-5l3 5M8 11h8" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  mind: <svg className="nav-ico" viewBox="0 0 24 24" fill="none"><path d="M12 21s-7-4.5-7-10a4 4 0 017-2.5A4 4 0 0119 11c0 5.5-7 10-7 10z" stroke="currentColor" strokeWidth="2" strokeLinejoin="round"/></svg>,
  gear: <svg viewBox="0 0 24 24" fill="none" width="15" height="15"><circle cx="12" cy="12" r="3" stroke="currentColor" strokeWidth="2"/><path d="M12 2v2m0 16v2M4.22 4.22l1.42 1.42m12.72 12.72l1.42 1.42M2 12h2m16 0h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/></svg>,
};

/* ── SIDEBAR ─────────────────────────────────────────────── */
function Sidebar({ active, setActive, daysLeft, profiel, email, onLogout }) {
  const items = [
    {id:"overzicht",    label:"Overzicht",    ico:icons.overzicht},
    {id:"weegmomenten", label:"Dagboek",      ico:icons.weeg},
    {id:"weekmenu",     label:"Weekmenu",     ico:icons.menu},
    {id:"boodschappen", label:"Boodschappen", ico:icons.shop},
    {id:"beweging",     label:"Beweging",     ico:icons.move},
    {id:"mindset",      label:"Mindset",      ico:icons.mind},
  ];
  return (
    <aside className="sidebar">
      <div className="brand">
        <span className="brand-kicker">Programma 2026</span>
        <span className="brand-title">Ibiza</span>
        <span className="brand-sub">{profiel.naam}s weg naar het strand</span>
      </div>
      <div className="countdown-mini">
        <div className="sun-dot"></div>
        <div className="cd-num">{daysLeft}</div>
        <div className="cd-label">dagen tot je doel</div>
        <div className="cd-date">Streefdatum · {fmtDate(profiel.doelDatum,true)} {new Date(profiel.doelDatum+"T00:00:00").getFullYear()}</div>
      </div>
      <nav className="nav">
        {items.map(it=>(
          <button key={it.id} className={"nav-item"+(active===it.id?" active":"")} onClick={()=>setActive(it.id)}>
            {it.ico}<span className="nav-label">{it.label}</span>
          </button>
        ))}
      </nav>
      <div className="sidebar-foot">
        <div className="sb-user">
          <span className="sb-email">{email}</span>
          <button className="sb-logout" onClick={onLogout}>Afmelden</button>
        </div>
        <button className="reset-link" onClick={()=>window.open('print.html')}>Open het printbare weekplan →</button>
      </div>
    </aside>
  );
}

/* ── OVERZICHT ───────────────────────────────────────────── */
function Overzicht({ profiel, weights, setWeights, userEmail, emailCfg }) {
  const entries = sortedEntries(weights);
  const huidig  = entries.length ? entries[entries.length-1].val : profiel.startGewicht;
  const totaal  = +(profiel.startGewicht - profiel.doelGewicht).toFixed(1);
  const af      = +(profiel.startGewicht - huidig).toFixed(1);
  const teGaan  = +(huidig - profiel.doelGewicht).toFixed(1);
  const pct     = Math.max(0, Math.min(100, (Math.max(0,af)/totaal)*100));
  const waarom  = profiel.motivatie || "Geniet van elke stap op weg naar je doel.";
  return (
    <section className="section" id="overzicht">
      <DailyWeighInWidget profiel={profiel} weights={weights} setWeights={setWeights}
        userEmail={userEmail} emailCfg={emailCfg}/>
      <div className="hero">
        <div className="hero-sun"></div>
        <svg className="hero-waves" viewBox="0 0 1200 90" preserveAspectRatio="none" fill="none">
          <path d="M0 50 Q150 20 300 50 T600 50 T900 50 T1200 50 V90 H0 Z" fill="white" opacity="0.25"/>
          <path d="M0 64 Q150 38 300 64 T600 64 T900 64 T1200 64 V90 H0 Z" fill="white" opacity="0.3"/>
        </svg>
        <div className="hero-content">
          <span className="hero-eyebrow">Afvalprogramma · {fmtDate(profiel.startDatum,true)} → {fmtDate(profiel.doelDatum,true)}</span>
          <h1 className="hero-h1">Dag {profiel.naam}, <em>op naar je doel.</em></h1>
          <p className="hero-because">{waarom}</p>
        </div>
      </div>
      <div className="stat-row">
        <div className="stat">
          <div className="stat-label">Huidig gewicht</div>
          <div className="stat-num">{huidig.toFixed(1)}<span className="unit">kg</span></div>
          <div className="stat-foot">Start was {profiel.startGewicht.toFixed(1)} kg</div>
        </div>
        <div className="stat">
          <div className="stat-label">Al kwijt</div>
          <div className="stat-num accent-sage">{af>=0?"−":"+"}{Math.abs(af).toFixed(1)}<span className="unit">kg</span></div>
          <div className="stat-foot">Van de {totaal} kg die je wil</div>
        </div>
        <div className="stat">
          <div className="stat-label">Nog te gaan</div>
          <div className="stat-num accent-terra">{Math.max(0,teGaan).toFixed(1)}<span className="unit">kg</span></div>
          <div className="stat-foot">Doel: {profiel.doelGewicht.toFixed(1)} kg</div>
        </div>
      </div>
      <div className="progress-wrap">
        <div className="progress-top">
          <span className="pt-l">Voortgang naar je doel</span>
          <span className="pt-r">{Math.round(pct)}% behaald</span>
        </div>
        <div className="bar"><div className="bar-fill" style={{width:pct+"%"}}></div></div>
        <div className="bar-scale">
          <span>{profiel.startGewicht.toFixed(1)} kg</span>
          <span>{profiel.doelGewicht.toFixed(1)} kg · doel</span>
        </div>
      </div>
    </section>
  );
}

/* ── DAGBOEK ─────────────────────────────────────────────── */
function Dagboek({ profiel, weights, setWeights, weegmomenten }) {
  const today   = todayIso();
  const entries = sortedEntries(weights);

  const chart = useMemo(() => {
    const W=500,H=220,pL=42,pR=16,pT=16,pB=28;
    const minV = profiel.doelGewicht - 1, maxV = profiel.startGewicht + 1;
    const total = Math.max(1, daysBetween(profiel.startDatum, profiel.doelDatum));
    const xD = iso => pL + (daysBetween(profiel.startDatum, iso)/total)*(W-pL-pR);
    const y  = v  => pT + (1-(v-minV)/(maxV-minV))*(H-pT-pB);
    const tPts = weegmomenten.map(w=>[xD(w.datum),y(w.doel)]);
    const tPath = tPts.map((p,i)=>(i?"L":"M")+p[0]+" "+p[1]).join(" ");
    const aPts  = entries.filter(e=>e.date>=profiel.startDatum).map(e=>({x:xD(e.date),yv:y(e.val),val:e.val,date:e.date}));
    const aPath = aPts.map((p,i)=>(i?"L":"M")+p.x+" "+p.yv).join(" ");
    return {W,H,y,minV,maxV,tPath,tPts,aPts,aPath};
  }, [weights, weegmomenten, profiel]);

  const recent = [...entries].reverse().slice(0,14);

  function update(date, raw) {
    setWeights({...weights,[date]:raw===""?null:raw.replace(",",".")});
  }

  return (
    <section className="section" id="weegmomenten">
      <div className="sec-head">
        <div className="sec-kicker">Elke dag, 's morgens nuchter</div>
        <h2 className="sec-title">Dagboek</h2>
        <p className="sec-intro">
          Vul je gewicht dagelijks in via het overzicht. Na elk opslaan wordt automatisch een e-mail verstuurd met je delta, trend en een motiverende boodschap.
        </p>
      </div>
      <div className="weeg-grid">
        <div className="card weeg-list" style={{padding:"10px 24px"}}>
          {recent.length===0 && (
            <div style={{padding:"24px 0",color:"var(--ink-faint)",fontSize:14}}>
              Nog geen metingen. Vul je gewicht in op het Overzicht-scherm.
            </div>
          )}
          {recent.map((e,i) => {
            const prev    = recent[i+1];
            const delta   = prev ? +(e.val - prev.val).toFixed(2) : null;
            const isToday = e.date===today;
            const wm      = weegmomenten.find(w=>w.datum===e.date);
            return (
              <div key={e.date} className={"weeg-row done"+(isToday?" current":"")}>
                <div className="weeg-dot" style={{background:"var(--terra)"}}></div>
                <div className="weeg-meta">
                  <div className="wm-label">
                    {fmtDate(e.date,true)}
                    {isToday && <span className="wm-now">vandaag</span>}
                    {wm && <span className="wm-now" style={{background:"var(--zee)"}}>{wm.label}</span>}
                  </div>
                  <div className="wm-date">{DAGEN[new Date(e.date+"T00:00:00").getDay()]}</div>
                </div>
                {wm ? <div className="weeg-target">streef<br/><b>{wm.doel.toFixed(1)} kg</b></div>
                    : <div className="weeg-target"></div>}
                <div style={{display:"flex",alignItems:"center",gap:6,flexWrap:"wrap"}}>
                  <input className="weeg-input" inputMode="decimal" value={String(e.val)}
                    onChange={ev=>update(e.date,ev.target.value)}/>
                  {delta!==null && (
                    <span className={"weeg-pill "+(delta<=0?"pill-good":"pill-over")}>
                      {delta>0?"+":""}{delta.toFixed(2).replace(".",",")}
                    </span>
                  )}
                </div>
              </div>
            );
          })}
        </div>

        <div className="card chart-card">
          <div className="chart-title">Gewichtscurve</div>
          <div className="chart-sub">Dagelijkse metingen vs. streeflijn</div>
          <svg viewBox={`0 0 ${chart.W} ${chart.H}`} width="100%" style={{display:"block"}}>
            {Array.from({length:Math.ceil(chart.maxV-chart.minV)+1},(_,i)=>{
              const v=Math.floor(chart.minV)+i;
              return v<=Math.ceil(chart.maxV)?(
                <g key={v}>
                  <line x1={42} x2={chart.W-16} y1={chart.y(v)} y2={chart.y(v)} stroke="var(--line-soft)" strokeWidth="1"/>
                  <text x={38} y={chart.y(v)+4} textAnchor="end" fontSize="10" fill="var(--ink-faint)" fontFamily="Manrope">{v}</text>
                </g>
              ):null;
            })}
            <path d={chart.tPath} fill="none" stroke="var(--zee)" strokeWidth="2" strokeDasharray="5 4" strokeLinecap="round"/>
            {chart.aPath && <path d={chart.aPath} fill="none" stroke="var(--terra)" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/>}
            {chart.aPts.map((p,i)=>(
              <circle key={i} cx={p.x} cy={p.yv} r={p.date===today?5.5:3.5}
                fill="var(--terra)" stroke="white" strokeWidth={p.date===today?2.5:1.5}/>
            ))}
          </svg>
          <div className="legend">
            <span><i style={{background:"var(--zee)"}}></i>Streeflijn</span>
            <span><i style={{background:"var(--terra)"}}></i>Dagelijkse meting</span>
          </div>
          {entries.length>=2 && (
            <div className="trend-box">
              <div className="trend-label">Trend (laatste {Math.min(7,entries.length)} metingen)</div>
              <div className="trend-text">{trendText(entries)}</div>
            </div>
          )}
        </div>
      </div>
    </section>
  );
}

/* ── WEEKMENU ────────────────────────────────────────────── */
function Weekmenu({ habits, setHabits }) {
  const toggle = key => setHabits({...habits,[key]:!habits[key]});
  return (
    <section className="section" id="weekmenu">
      <div className="sec-head">
        <div className="sec-kicker">7 dagen · gezond &amp; haalbaar</div>
        <h2 className="sec-title">Weekmenu</h2>
        <p className="sec-intro">Volwaardige maaltijden. Genoeg eiwit en groenten om je vol en energiek te houden.</p>
      </div>
      <div className="menu-grid">
        {D.weekmenu.map(d=>(
          <div key={d.dag} className="card day-card">
            <div className="day-name">{d.dag}</div>
            <div className="meal"><div className="meal-tag ontbijt">Ontbijt</div><div className="meal-text">{d.ontbijt}</div></div>
            <div className="meal"><div className="meal-tag lunch">Lunch</div><div className="meal-text">{d.lunch}</div></div>
            <div className="meal"><div className="meal-tag diner">Diner</div><div className="meal-text">{d.diner}</div></div>
            <div className="meal"><div className="meal-tag snack">Snack</div><div className="meal-text">{d.snack}</div></div>
          </div>
        ))}
      </div>
      <div className="card habits">
        <div className="habits-head"><div>
          <div className="habits-title">Dagelijkse gewoontes</div>
          <div className="habits-sub">Vink af wat je vandaag deed.</div>
        </div></div>
        <div className="habit-list">
          {D.gewoontes.map((g,i)=>{
            const key="h"+i,on=!!habits[key];
            return (
              <div key={key} className={"habit"+(on?" on":"")} onClick={()=>toggle(key)}>
                <span className="check"><svg viewBox="0 0 24 24" fill="none"><path d="M5 13l4 4L19 7" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/></svg></span>{g}
              </div>
            );
          })}
        </div>
      </div>
    </section>
  );
}

/* ── BOODSCHAPPEN ────────────────────────────────────────── */
function Boodschappen({ shop, setShop }) {
  const toggle = key => setShop({...shop,[key]:!shop[key]});
  return (
    <section className="section" id="boodschappen">
      <div className="sec-head">
        <div className="sec-kicker">Basis voor één week</div>
        <h2 className="sec-title">Boodschappenlijst</h2>
        <p className="sec-intro">Alles voor het weekmenu, per rayon. Vink af wat in het karretje ligt.</p>
      </div>
      <div className="shop-grid">
        {Object.entries(D.boodschappen).map(([cat,items])=>(
          <div key={cat} className="card shop-cat">
            <h3>{cat}</h3><div className="cat-count">{items.length} producten</div>
            {items.map(it=>{
              const key=cat+"::"+it,on=!!shop[key];
              return (
                <div key={key} className={"shop-item"+(on?" on":"")} onClick={()=>toggle(key)}>
                  <span className="shop-box"><svg viewBox="0 0 24 24" fill="none"><path d="M5 13l4 4L19 7" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/></svg></span>
                  <span>{it}</span>
                </div>
              );
            })}
          </div>
        ))}
      </div>
    </section>
  );
}

/* ── BEWEGING ────────────────────────────────────────────── */
function Beweging() {
  const b=D.beweging;
  return (
    <section className="section" id="beweging">
      <div className="sec-head">
        <div className="sec-kicker">3× per week · 20–30 min</div>
        <h2 className="sec-title">Beweging</h2>
        <p className="sec-intro">Kort, simpel, geen sportschool nodig.</p>
      </div>
      <div className="card move-intro-card">
        <p>{b.intro}</p>
        <div className="daydoel"><span className="dd-num">8.000</span><span className="dd-label">stappen per dag</span></div>
      </div>
      <div className="move-grid">
        {b.sessies.map((s,i)=>(
          <div key={i} className="card move-card">
            <div className={"move-top "+s.kleur}>
              <div className="mt-day">{s.dag}</div><div className="mt-title">{s.titel}</div><div className="mt-duur">{s.duur}</div>
            </div>
            <ul className="move-body">{s.oefeningen.map((o,j)=><li key={j}>{o}</li>)}</ul>
          </div>
        ))}
      </div>
    </section>
  );
}

/* ── MINDSET ─────────────────────────────────────────────── */
function Mindset({ profiel }) {
  const m=D.mindset, waarom=profiel.motivatie||"Geniet van elke stap op weg naar je doel.";
  return (
    <section className="section" id="mindset">
      <div className="sec-head">
        <div className="sec-kicker">Je doel op de horizon</div>
        <h2 className="sec-title">Mindset &amp; motivatie</h2>
      </div>
      <div className="why-card">
        <div className="why-sun"></div>
        <div className="why-kicker">Waarom je dit doet</div>
        <div className="why-text">"{waarom}"</div>
      </div>
      <div className="mant-grid">
        {m.mantras.map((mt,i)=>(
          <div key={i} className="card mant">
            <span className="mant-no">{i+1}</span>
            <div className="mant-week">{mt.week}</div>
            <div className="mant-text">{mt.tekst}</div>
          </div>
        ))}
      </div>
      <div className="card tips-card">
        <h3>Tips die werken</h3>
        {m.tips.map((t,i)=>(
          <div key={i} className="tip">
            <div className="tip-num">{String(i+1).padStart(2,"0")}</div>
            <div className="tip-text">{t}</div>
          </div>
        ))}
      </div>
    </section>
  );
}

/* ── APP ROOT ────────────────────────────────────────────── */
function App() {
  const [cryptoKey,setCryptoKey] = useState(null);
  const [userEmail,setUserEmail] = useState("");
  const [active,setActive]       = useState("overzicht");

  const [profiel, setProfiel, pL] = useSecureStore("ibiza.profiel", null, cryptoKey);
  const [weights, setWeights, wL] = useSecureStore("ibiza.weights", {},   cryptoKey);
  const [habits,  setHabits,  hL] = useSecureStore("ibiza.habits",  {},   cryptoKey);
  const [shop,    setShop,    sL] = useSecureStore("ibiza.shop",    {},   cryptoKey);

  const weegmomenten = useMemo(()=> profiel ? computeWeegmomenten(profiel) : [], [profiel]);
  const daysLeft     = profiel ? Math.max(0, daysBetween(todayIso(), profiel.doelDatum)) : 0;

  useEffect(()=>{
    if (profiel && weegmomenten.length) syncSessionStorage(profiel, weegmomenten);
  },[profiel,weegmomenten]);

  if (!cryptoKey) return <LoginScreen onAuth={(k,e)=>{setCryptoKey(k);setUserEmail(e);}}/>;
  if (!pL||!wL||!hL||!sL) return (
    <div style={{display:"flex",alignItems:"center",justifyContent:"center",minHeight:"100vh",
      fontSize:16,color:"var(--ink-faint)",fontFamily:"var(--sans)"}}>Gegevens ontsleutelen…</div>
  );
  if (!profiel) return <OnboardingScreen onSave={p=>{setProfiel(p);setWeights({});setHabits({});setShop({});}}/>;

  const wp = {profiel, weights, setWeights, userEmail};
  const views = {
    overzicht:    <Overzicht    {...wp}/>,
    weegmomenten: <Dagboek      {...wp} weegmomenten={weegmomenten}/>,
    weekmenu:     <Weekmenu     habits={habits} setHabits={setHabits}/>,
    boodschappen: <Boodschappen shop={shop} setShop={setShop}/>,
    beweging:     <Beweging/>,
    mindset:      <Mindset      profiel={profiel}/>,
  };

  return (
    <div className="app">
      <Sidebar active={active} setActive={setActive} daysLeft={daysLeft}
        profiel={profiel} email={userEmail}
        onLogout={()=>{setCryptoKey(null);setUserEmail("");setActive("overzicht");}}/>
      <main className="main" key={active}>
        {views[active]}
        <section className="section" style={{display:"flex",gap:18,alignItems:"center",flexWrap:"wrap",borderTop:"1px solid var(--line-soft)"}}>
          <button className="print-btn" onClick={()=>window.open('print.html')}>
            <svg viewBox="0 0 24 24" fill="none"><path d="M6 9V3h12v6M6 18H4a2 2 0 01-2-2v-3a2 2 0 012-2h16a2 2 0 012 2v3a2 2 0 01-2 2h-2M6 14h12v7H6v-7z" stroke="currentColor" strokeWidth="2" strokeLinejoin="round"/></svg>
            Printbaar weekplan openen
          </button>
          <button className="reset-link"
            onClick={()=>confirm("Alle gewichten, vinkjes en boodschappen wissen?")&&(setWeights({}),setHabits({}),setShop({}))}>
            Programma terugzetten naar start
          </button>
        </section>
      </main>
    </div>
  );
}

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