// Moderis App — gedeelde app-data, extra iconen & UI-primitives.
// Laadt NA moderis-shared.jsx (gebruikt MIcon, M_ICONS, fmt).

// ---- extra iconen ----
Object.assign(M_ICONS, {
  search: '<circle cx="11" cy="11" r="7"/><path d="m21 21-4.35-4.35"/>',
  barcode: '<path d="M3.5 6v12M6.5 6v12M9 6v12M12 6v12M15 6v12M17.5 6v12M20.5 6v12"/>',
  scan: '<path d="M4 7V5.5A1.5 1.5 0 0 1 5.5 4H7"/><path d="M17 4h1.5A1.5 1.5 0 0 1 20 5.5V7"/><path d="M20 17v1.5a1.5 1.5 0 0 1-1.5 1.5H17"/><path d="M7 20H5.5A1.5 1.5 0 0 1 4 18.5V17"/><path d="M4 12h16"/>',
  close: '<path d="M18 6 6 18M6 6l12 12"/>',
  check: '<path d="M20 6 9 17l-5-5"/>',
  chevron: '<path d="m9 6 6 6-6 6"/>',
  trash: '<path d="M3 6h18M8 6V4.5A1.5 1.5 0 0 1 9.5 3h5A1.5 1.5 0 0 1 16 4.5V6M18.5 6l-1 13.5a2 2 0 0 1-2 1.5h-7a2 2 0 0 1-2-1.5L4.5 6"/>',
  box: '<path d="M21 8 12 3 3 8v8l9 5 9-5Z"/><path d="M3 8l9 5 9-5M12 13v8"/>',
  house: '<path d="M3 10.5 12 3l9 7.5"/><path d="M5 9.7V20a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V9.7"/>',
  flame: '<path d="M12 3c.8 2.6 3.6 4.2 3.6 7.5a3.6 3.6 0 0 1-7.2 0c0-1 .3-1.7.7-2.4.6 1 1.4 1.2 1.4 1.2-.5-1.6.2-3.4 1.5-4.3-.4 1 .2 1.8 1 2.3C13.9 7 13 4.8 12 3Z"/>',
  fridge: '<rect x="6" y="2.5" width="12" height="19" rx="2.5"/><path d="M6 10h12M9.5 6v1.5M9.5 13v2"/>',
  minus: '<path d="M5 12h14"/>',
  utensils: '<path d="M5 3v7a2 2 0 0 0 2 2h0a2 2 0 0 0 2-2V3M7 12v9M16 3c-1.5 0-2.5 2-2.5 4.5S15 12 16 12s2.5 0 2.5 0V3ZM16 12v9"/>',
  book: '<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/>',
  star: '<path d="M12 3.5l2.6 5.3 5.9.9-4.2 4.1 1 5.8L12 17l-5.3 2.6 1-5.8-4.2-4.1 5.9-.9z"/>',
  pencil: '<path d="M12 20h9"/><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z"/>',
  back: '<path d="M19 12H5M12 19l-7-7 7-7"/>',
  user: '<circle cx="12" cy="8" r="3.6"/><path d="M5 20c0-3.6 3.1-5.5 7-5.5s7 1.9 7 5.5"/>',
  clock: '<circle cx="12" cy="12" r="9"/><path d="M12 7.5V12l3 1.8"/>',
  snow: '<path d="M12 3v18M4.2 7.5l15.6 9M19.8 7.5l-15.6 9"/><path d="M9 4.5 12 6l3-1.5M9 19.5 12 18l3 1.5M4.7 10 6 7.5 3.2 7M19.3 10 18 7.5l2.8-.5M4.7 14 6 16.5l-2.8.5M19.3 14 18 16.5l2.8.5"/>',
  bag: '<path d="M8 7V5.5A2.5 2.5 0 0 1 10.5 3h3A2.5 2.5 0 0 1 16 5.5V7"/><rect x="3.5" y="7" width="17" height="13" rx="2.5"/><path d="M3.5 12.5h17"/>',
});

// ===================== UI PRIMITIVES =====================

function Toast({ toast }) {
  if (!toast) return null;
  return (
    <div className="toast-wrap">
      <div className="toast" key={toast.key}>
        <span style={{ width: 20, height: 20, borderRadius: 999, background: 'var(--leaf)',
          display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <MIcon name="check" size={13} sw={2.6} color="var(--forest-950)" />
        </span>
        {toast.msg}
      </div>
    </div>
  );
}

const NAV_TITLES = { home: 'Vandaag', add: 'Loggen', pantry: 'Voorraad', recepten: 'Recepten', profile: 'Profiel' };

function SideNav({ active, onTab }) {
  const items = [
    { id: 'home',     icon: 'house', label: 'Vandaag' },
    { id: 'add',      icon: 'plus',  label: 'Loggen' },
    { id: 'pantry',   icon: 'box',   label: 'Voorraad' },
    { id: 'profile',  icon: 'user',  label: 'Profiel' },
  ];
  return (
    <aside className="sidenav">
      <div className="sidenav-brand">
        <span className="sidenav-brand-mark">
          <MIcon name="leaf" size={18} color="var(--leaf)" />
        </span>
        <span className="sidenav-brand-name">Moderis</span>
      </div>
      <nav className="sidenav-items">
        {items.map((it) => (
          <button key={it.id}
            className={`sidenav-item ${active === it.id ? 'is-active' : ''}`}
            onClick={() => onTab(it.id)}>
            <MIcon name={it.icon} size={18} color="currentColor" />
            {it.label}
          </button>
        ))}
      </nav>
      <div className="sidenav-foot">
        <div className="sidenav-foot-label">Verbonden</div>
        <div className="sidenav-foot-row">
          <span className="sidenav-foot-dot"></span>
          Google Health
        </div>
      </div>
    </aside>
  );
}

// Korte NL-datum voor de topbalk, bv. "do 17 jul".
function topbarDatum() {
  return new Date().toLocaleDateString('nl-NL', { weekday: 'short', day: 'numeric', month: 'short' })
    .replace(/\./g, '');
}

function TopBar({ active }) {
  return (
    <header className="topbar">
      <div className="topbar-brand">
        <span className="topbar-brand-mark">
          <MIcon name="leaf" size={15} color="var(--leaf)" />
        </span>
        {NAV_TITLES[active] || 'Moderis'}
      </div>
      <span className="topbar-date">{topbarDatum().toUpperCase()}</span>
    </header>
  );
}

function BottomNav({ active, onTab }) {
  const item = (id, icon, label) => (
    <button className={`bn-item ${active === id ? 'is-active' : ''}`} onClick={() => onTab(id)}>
      <MIcon name={icon} size={21} sw={active === id ? 2.1 : 1.75} />
      <span>{label}</span>
    </button>
  );
  return (
    <nav className="bottomnav">
      {item('home', 'house', 'Vandaag')}
      {item('pantry', 'box', 'Voorraad')}
      <button className="bn-fab" onClick={() => onTab('add')} title="Eten loggen" aria-label="Eten loggen">
        <MIcon name="plus" size={26} sw={2.3} color="var(--on-forest)" />
      </button>
      {item('profile', 'user', 'Profiel')}
    </nav>
  );
}

function Sheet({ title, onClose, children }) {
  // Scroll-lock: de achtergrond vastzetten zolang de sheet open is. Zonder dit
  // scrolt (vooral op iOS) de lijst onder de sheet door — na sluiten sta je
  // dan ergens anders in de lijst. position:fixed + top:-y is het iOS-proof
  // patroon; bij sluiten zetten we de scrollpositie exact terug.
  React.useEffect(() => {
    const y = window.scrollY;
    const b = document.body.style;
    const vorig = { position: b.position, top: b.top, left: b.left, right: b.right, width: b.width };
    b.position = 'fixed'; b.top = `-${y}px`; b.left = '0'; b.right = '0'; b.width = '100%';
    return () => {
      b.position = vorig.position; b.top = vorig.top; b.left = vorig.left;
      b.right = vorig.right; b.width = vorig.width;
      window.scrollTo(0, y);
    };
  }, []);
  return (
    <div className="sheet-overlay" onClick={onClose}>
      <div className="sheet" onClick={(e) => e.stopPropagation()}>
        <div className="sheet-grip"></div>
        {title && (
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14 }}>
            <h3 style={{ margin: 0, fontSize: 18, fontWeight: 700, letterSpacing: '-0.01em' }}>{title}</h3>
            <button className="m-btn" onClick={onClose}
              style={{ width: 32, height: 32, padding: 0, borderRadius: 999, background: 'var(--m-card-2)' }}>
              <MIcon name="close" size={16} color="var(--ink-2)" />
            </button>
          </div>
        )}
        {children}
      </div>
    </div>
  );
}

// compacte macro-badges (e/k/v)
function MacroBadges({ m, size = 11.5 }) {
  return (
    <React.Fragment>
      <span className="m-badge m-macro-badge m-mb-p" style={{ fontSize: size }}>{m.p}<span style={{ opacity: .7 }}>e</span></span>
      <span className="m-badge m-macro-badge m-mb-c" style={{ fontSize: size }}>{m.c}<span style={{ opacity: .7 }}>k</span></span>
      <span className="m-badge m-macro-badge m-mb-f" style={{ fontSize: size }}>{m.f}<span style={{ opacity: .7 }}>v</span></span>
    </React.Fragment>
  );
}

// Zoekrij — herbruikt door Loggen & Voorraad. In voorraad-stand (pantryMode)
// tonen we géén portie/kcal: de voorraad is een aanwezigheidslijst, grammen
// horen daar niet bij.
function FoodResultRow({ food, onAdd, added, pantryMode }) {
  return (
    <div className="tap" style={{ display: 'flex', alignItems: 'center', gap: 13, padding: '12px 0' }}>
      <div style={{ width: 44, height: 44, flex: '0 0 auto', borderRadius: 13, background: 'var(--m-card-2)',
        border: '1px solid var(--m-line)', display: 'flex', alignItems: 'center', justifyContent: 'center',
        color: 'var(--forest-600)' }}>
        <MIcon name="utensils" size={18} color="var(--forest-600)" />
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 14.5, fontWeight: 600, lineHeight: 1.25, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{food.name}</div>
        <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 2 }}>
          {pantryMode ? food.brand : (
            <React.Fragment>
              {food.brand} · <span className="num">{food.portion}</span> · <span className="num">{food.kcal}</span> kcal
            </React.Fragment>
          )}
        </div>
      </div>
      <button className="m-btn" onClick={() => onAdd(food)}
        style={{ width: 36, height: 36, padding: 0, borderRadius: 12, flex: '0 0 auto',
          background: added ? 'var(--leaf)' : 'var(--forest-700)' }}>
        <MIcon name={added ? 'check' : 'plus'} size={17} sw={2.2} color={added ? 'var(--forest-950)' : 'var(--on-forest)'} />
      </button>
    </div>
  );
}

// Ingrediënt-invoer met autocomplete: matcht tegen onze voedingsdatabase
// (voorraad + basistabel + gecachte OFF). Kiezen vult de naam in; de macro's
// worden daarna serverside herkend.
function IngredientNaamInput({ value, onChange, onPick, onBlur, style, placeholder }) {
  const { useState, useRef } = React;
  const [open, setOpen] = useState(false);
  const [res, setRes] = useState([]);
  const timer = useRef(null);
  const blurTimer = useRef(null);

  const zoek = (q) => {
    clearTimeout(timer.current);
    if (!q || q.trim().length < 2) { setRes([]); return; }
    timer.current = setTimeout(async () => {
      try { const r = await window.api.zoekVoeding(q.trim()); setRes(r.resultaten || []); }
      catch (_) { setRes([]); }
    }, 250);
  };
  const handleChange = (e) => { const v = e.target.value; onChange(v); zoek(v); setOpen(true); };
  const kies = (r) => { clearTimeout(blurTimer.current); onPick(r); setOpen(false); setRes([]); };

  return (
    <div style={{ position: 'relative', flex: (style && style.flex) || 1, minWidth: 0 }}>
      <input value={value} onChange={handleChange} placeholder={placeholder || 'ingrediënt'}
        onFocus={() => { if (res.length) setOpen(true); }}
        onBlur={() => { blurTimer.current = setTimeout(() => setOpen(false), 150); if (onBlur) onBlur(); }}
        style={{ ...style, width: '100%', flex: 'unset' }} />
      {open && res.length > 0 && (
        <div style={{ position: 'absolute', top: '100%', left: 0, right: 0, zIndex: 60, marginTop: 4,
          background: 'var(--m-card)', border: '1px solid var(--m-line-2)', borderRadius: 11,
          boxShadow: 'var(--m-shadow-md)', overflow: 'hidden', maxHeight: 210, overflowY: 'auto' }}>
          {res.map((r, i) => (
            <div key={i} className="tap" onMouseDown={(e) => { e.preventDefault(); kies(r); }}
              style={{ padding: '9px 12px', cursor: 'pointer', display: 'flex', justifyContent: 'space-between',
                alignItems: 'baseline', gap: 8, borderBottom: i < res.length - 1 ? '1px solid var(--m-line)' : 'none' }}>
              <span style={{ fontSize: 13, fontWeight: 500, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                minWidth: 0, display: 'inline-flex', alignItems: 'center', gap: 6 }}>
                {r.naam}
                {r.bron === 'voorraad' && (
                  <span style={{ fontSize: 9.5, fontWeight: 700, color: 'var(--forest-700)', background: 'var(--forest-100)',
                    border: '1px solid var(--forest-200)', borderRadius: 999, padding: '1px 6px', flex: '0 0 auto' }}>
                    in voorraad{r.voorraad_g != null ? ` · ${Math.round(r.voorraad_g)} ${r.eenheid || 'g'}` : ''}
                  </span>
                )}
              </span>
              <span className="num" style={{ fontSize: 11, color: 'var(--ink-3)', flex: '0 0 auto' }}>{Math.round(r.kcal_per_100g || 0)} kcal/100g</span>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

Object.assign(window, {
  Toast, SideNav, TopBar, BottomNav, Sheet, MacroBadges, FoodResultRow, IngredientNaamInput,
});
