/* global React, GlassCard, SectionLabel, ScreenHeader, Pill, Btn */
// Body, Study and Health tabs, plus the Food screen (added 2026-10-01).
//
// The tab bar went from six tabs to five: Home, Body (Gym + Food), Study
// (WAM + Cards + Quiz), Health and Insights. Body and Study are thin wrappers
// that put a segmented switch above the existing screens.

(function () {
  const { useState, useMemo, useRef } = React;
  const opt = () => window.__opt;

  const C = {
    text: '#e8d9bd', muted: '#8a7860', faint: '#5a4d3c',
    amber: '#f4c987', accent: '#c4874b', good: '#7da967', warn: '#e0a766',
  };

  // Local calendar date, not Sydney: food is logged wherever Will is eating.
  function localDate(d = new Date()) {
    const p = (n) => String(n).padStart(2, '0');
    return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
  }
  const fmt = (n) => Math.round(n || 0).toLocaleString('en-AU');
  const sumDay = (entries) => (entries || []).reduce((a, e) => ({
    kcal: a.kcal + (e.kcal || 0), protein: a.protein + (e.protein || 0),
    carbs: a.carbs + (e.carbs || 0), fat: a.fat + (e.fat || 0),
  }), { kcal: 0, protein: 0, carbs: 0, fat: 0 });

  const inputStyle = {
    width: '100%', background: 'rgba(0,0,0,0.3)',
    border: '1px solid rgba(232,217,189,0.10)', borderRadius: 10,
    color: C.text, padding: '12px 14px', fontFamily: 'inherit', fontSize: 15,
    outline: 'none', boxSizing: 'border-box',
  };

  // Downscale on the phone before upload: a 12MP photo becomes ~150KB, which
  // keeps the request fast and the AI image cost to a fraction of a cent.
  function fileToJpegBase64(file, max = 1024) {
    return new Promise((resolve, reject) => {
      const url = URL.createObjectURL(file);
      const img = new Image();
      img.onload = () => {
        const scale = Math.min(1, max / Math.max(img.width, img.height));
        const canvas = document.createElement('canvas');
        canvas.width = Math.round(img.width * scale);
        canvas.height = Math.round(img.height * scale);
        canvas.getContext('2d').drawImage(img, 0, 0, canvas.width, canvas.height);
        URL.revokeObjectURL(url);
        const dataUrl = canvas.toDataURL('image/jpeg', 0.8);
        resolve({ dataUrl, base64: dataUrl.split(',')[1] });
      };
      img.onerror = () => { URL.revokeObjectURL(url); reject(new Error('Could not read that photo.')); };
      img.src = url;
    });
  }

  function Bar({ value, target, color }) {
    const pct = target > 0 ? Math.min(100, (value / target) * 100) : 0;
    return (
      <div style={{ height: 8, borderRadius: 999, background: 'rgba(232,217,189,0.08)', overflow: 'hidden' }}>
        <div style={{ width: pct + '%', height: '100%', borderRadius: 999, background: color, transition: 'width 400ms cubic-bezier(0.2,0,0,1)' }} />
      </div>
    );
  }

  function Segments({ options, value, onChange }) {
    return (
      <div style={{ display: 'flex', gap: 8, padding: '14px 4px 0' }}>
        {options.map(o => (
          <Pill key={o.id} selected={value === o.id} onClick={() => onChange(o.id)}>{o.label}</Pill>
        ))}
      </div>
    );
  }

  function useSegment(key, fallback) {
    const [v, setV] = useState(() => { try { return localStorage.getItem(key) || fallback; } catch { return fallback; } });
    const set = (x) => { setV(x); try { localStorage.setItem(key, x); } catch {} };
    return [v, set];
  }

  // ------------------------------------------------------------------ Food

  window.FoodScreen = function FoodScreen() {
    const [food, setFood] = useState(() => opt().loadFood());
    const today = localDate();
    const entries = food.days[today] || [];
    const totals = sumDay(entries);

    const [photo, setPhoto] = useState(null); // { dataUrl, base64 }
    const [note, setNote] = useState('');
    const [busy, setBusy] = useState(false);
    const [error, setError] = useState('');
    const [draft, setDraft] = useState(null); // estimate being reviewed before saving
    const [saveAsRegular, setSaveAsRegular] = useState(false);
    const [manage, setManage] = useState(false);
    const [editTargets, setEditTargets] = useState(false);
    const [toast, setToast] = useState('');
    const fileRef = useRef(null);

    const commit = (next) => { setFood(next); opt().saveFood(next); };
    const flash = (msg) => { setToast(msg); setTimeout(() => setToast(''), 1800); };

    const addEntry = (entry, alsoSave) => {
      const e = { id: 'f_' + Date.now(), ts: new Date().toISOString(), ...entry };
      const days = { ...food.days, [today]: [...entries, e] };
      let saved = food.saved;
      if (alsoSave && !saved.some(m => m.name.toLowerCase() === e.name.toLowerCase())) {
        saved = [...saved, { id: 'm_' + Date.now(), name: e.name, kcal: e.kcal, protein: e.protein, carbs: e.carbs, fat: e.fat }];
      }
      commit({ ...food, days, saved });
      flash('Added ' + e.name);
    };

    const removeEntry = (id) => commit({ ...food, days: { ...food.days, [today]: entries.filter(e => e.id !== id) } });
    const removeSaved = (id) => commit({ ...food, saved: food.saved.filter(m => m.id !== id) });

    const onPick = async (ev) => {
      const file = ev.target.files && ev.target.files[0];
      ev.target.value = '';
      if (!file) return;
      try { setError(''); setPhoto(await fileToJpegBase64(file)); }
      catch (e) { setError(e.message); }
    };

    const estimate = async () => {
      setBusy(true); setError('');
      try {
        const res = await opt().workerCall('/food/estimate', {
          method: 'POST',
          body: JSON.stringify({ image: photo ? photo.base64 : undefined, note: note.trim() || undefined }),
        });
        const first = (res.items && res.items[0] && res.items[0].name) || 'Meal';
        setDraft({
          name: note.trim() ? note.trim().slice(0, 40) : first,
          items: res.items || [], confidence: res.confidence, comment: res.comment,
          ...res.total,
        });
      } catch (e) {
        const m = String(e.message || '');
        const body = m.replace(/^\d+:\s*/, '');
        try { setError(JSON.parse(body).error || 'Estimate failed.'); }
        catch { setError('Estimate failed: ' + body.slice(0, 120)); }
      } finally { setBusy(false); }
    };

    const startManual = () => setDraft({ name: note.trim().slice(0, 40) || '', items: [], kcal: 0, protein: 0, carbs: 0, fat: 0, manual: true });

    const confirmDraft = () => {
      const clean = (n) => Math.max(0, Math.round(Number(n) || 0));
      addEntry({
        name: (draft.name || 'Meal').trim(), kcal: clean(draft.kcal), protein: clean(draft.protein),
        carbs: clean(draft.carbs), fat: clean(draft.fat), source: draft.manual ? 'manual' : (photo ? 'photo' : 'text'),
      }, saveAsRegular);
      setDraft(null); setPhoto(null); setNote(''); setSaveAsRegular(false);
    };

    const last7 = useMemo(() => {
      const out = [];
      for (let i = 6; i >= 0; i--) {
        const d = new Date(); d.setDate(d.getDate() - i);
        const key = localDate(d);
        out.push({ key, label: i === 0 ? 'Today' : d.toLocaleDateString('en-AU', { weekday: 'short' }), ...sumDay(food.days[key]), n: (food.days[key] || []).length });
      }
      return out;
    }, [food]);
    const logged = last7.filter(d => d.n > 0 && d.key !== today);
    const avg = (k) => logged.length ? logged.reduce((a, d) => a + d[k], 0) / logged.length : null;

    const t = food.targets;
    const proteinHit = totals.protein >= t.protein;
    const kcalOver = totals.kcal > t.kcal * 1.1;

    return (
      <div>
        <ScreenHeader title="Food" sub={new Date().toLocaleDateString('en-AU', { weekday: 'long', day: 'numeric', month: 'long' })} />

        {/* Today */}
        <GlassCard feature>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
            <div style={{ fontSize: 12, color: C.muted, letterSpacing: 0.6, textTransform: 'uppercase', fontWeight: 600 }}>Protein</div>
            <div onClick={() => setEditTargets(v => !v)} style={{ fontSize: 12, color: C.warn, cursor: 'pointer' }}>Targets</div>
          </div>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 6, margin: '4px 0 8px' }}>
            <div style={{ fontSize: 34, fontWeight: 600, color: proteinHit ? C.good : C.amber, fontVariantNumeric: 'tabular-nums' }}>{fmt(totals.protein)}</div>
            <div style={{ fontSize: 15, color: C.muted }}>/ {fmt(t.protein)} g</div>
          </div>
          <Bar value={totals.protein} target={t.protein} color={proteinHit ? C.good : C.accent} />

          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginTop: 16 }}>
            <div style={{ fontSize: 12, color: C.muted, letterSpacing: 0.6, textTransform: 'uppercase', fontWeight: 600 }}>Calories</div>
            <div style={{ fontSize: 13, color: kcalOver ? C.warn : C.muted, fontVariantNumeric: 'tabular-nums' }}>{fmt(totals.kcal)} / {fmt(t.kcal)}</div>
          </div>
          <div style={{ marginTop: 6 }}><Bar value={totals.kcal} target={t.kcal} color={kcalOver ? C.warn : 'rgba(232,217,189,0.45)'} /></div>
          <div style={{ display: 'flex', gap: 18, marginTop: 12, fontSize: 12, color: C.muted, fontVariantNumeric: 'tabular-nums' }}>
            <span>Carbs {fmt(totals.carbs)}g</span><span>Fat {fmt(totals.fat)}g</span><span>{entries.length} logged</span>
          </div>

          {editTargets && (
            <div style={{ display: 'flex', gap: 10, marginTop: 14 }}>
              <label style={{ flex: 1, fontSize: 11, color: C.muted }}>Protein (g)
                <input type="number" inputMode="numeric" defaultValue={t.protein} style={{ ...inputStyle, marginTop: 4 }}
                  onBlur={e => commit({ ...food, targets: { ...t, protein: Math.max(0, Number(e.target.value) || 0) } })} />
              </label>
              <label style={{ flex: 1, fontSize: 11, color: C.muted }}>Calories
                <input type="number" inputMode="numeric" defaultValue={t.kcal} style={{ ...inputStyle, marginTop: 4 }}
                  onBlur={e => commit({ ...food, targets: { ...t, kcal: Math.max(0, Number(e.target.value) || 0) } })} />
              </label>
            </div>
          )}
        </GlassCard>

        {/* Add a meal */}
        <SectionLabel>Add a meal</SectionLabel>
        <GlassCard>
          {!draft && (
            <>
              <input ref={fileRef} type="file" accept="image/*" onChange={onPick} style={{ display: 'none' }} />
              {photo ? (
                <div style={{ position: 'relative', marginBottom: 12 }}>
                  <img src={photo.dataUrl} alt="Meal" style={{ width: '100%', maxHeight: 240, objectFit: 'cover', borderRadius: 12, display: 'block' }} />
                  <button onClick={() => setPhoto(null)} aria-label="Remove photo" style={{
                    position: 'absolute', top: 8, right: 8, width: 30, height: 30, borderRadius: 999, border: 'none',
                    background: 'rgba(10,8,6,0.75)', color: C.text, fontSize: 16, cursor: 'pointer' }}>×</button>
                </div>
              ) : (
                <Btn kind="ghost" full onClick={() => fileRef.current && fileRef.current.click()} style={{ marginBottom: 12 }}>
                  Take or choose a photo
                </Btn>
              )}
              <textarea value={note} onChange={e => setNote(e.target.value)} rows={2}
                placeholder="Describe it (portion, what's hidden, what's in the smoothie)"
                style={{ ...inputStyle, resize: 'none', marginBottom: 12 }} />
              <Btn full onClick={estimate} disabled={busy || (!photo && !note.trim())}>
                {busy ? 'Estimating…' : 'Estimate with AI'}
              </Btn>
              <div onClick={startManual} style={{ textAlign: 'center', fontSize: 13, color: C.warn, marginTop: 12, cursor: 'pointer' }}>
                Enter numbers myself
              </div>
              {error && <div style={{ marginTop: 12, fontSize: 13, color: C.warn }}>{error}</div>}
            </>
          )}

          {draft && (
            <>
              {!draft.manual && (
                <div style={{ marginBottom: 12 }}>
                  {draft.items.map((it, i) => (
                    <div key={i} style={{ display: 'flex', justifyContent: 'space-between', gap: 12, padding: '6px 0', borderBottom: '1px solid rgba(232,217,189,0.06)', fontSize: 13 }}>
                      <span style={{ color: C.text }}>{it.name} <span style={{ color: C.muted }}>· {it.portion}</span></span>
                      <span style={{ color: C.muted, whiteSpace: 'nowrap', fontVariantNumeric: 'tabular-nums' }}>{fmt(it.kcal)} · {fmt(it.protein)}g</span>
                    </div>
                  ))}
                  <div style={{ display: 'flex', gap: 8, alignItems: 'center', marginTop: 10, flexWrap: 'wrap' }}>
                    {draft.confidence && <Pill tone={draft.confidence === 'high' ? 'good' : draft.confidence === 'medium' ? 'amber' : 'warn'}>{draft.confidence} confidence</Pill>}
                    {draft.comment && <span style={{ fontSize: 12, color: C.muted }}>{draft.comment}</span>}
                  </div>
                </div>
              )}
              <input value={draft.name} onChange={e => setDraft({ ...draft, name: e.target.value })} placeholder="Name (e.g. Teriyaki chicken bowl)" style={{ ...inputStyle, marginBottom: 10 }} />
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
                {[['kcal', 'Calories'], ['protein', 'Protein (g)'], ['carbs', 'Carbs (g)'], ['fat', 'Fat (g)']].map(([k, label]) => (
                  <label key={k} style={{ fontSize: 11, color: C.muted }}>{label}
                    <input type="number" inputMode="numeric" value={draft[k]} onChange={e => setDraft({ ...draft, [k]: e.target.value })} style={{ ...inputStyle, marginTop: 4 }} />
                  </label>
                ))}
              </div>
              <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: C.text, margin: '14px 0' }}>
                <input type="checkbox" checked={saveAsRegular} onChange={e => setSaveAsRegular(e.target.checked)} />
                Save as a regular meal (one tap next time)
              </label>
              <div style={{ display: 'flex', gap: 10 }}>
                <Btn kind="ghost" onClick={() => setDraft(null)} style={{ flex: 1 }}>Cancel</Btn>
                <Btn onClick={confirmDraft} disabled={!String(draft.name).trim()} style={{ flex: 2 }}>Add to today</Btn>
              </div>
            </>
          )}
        </GlassCard>

        {/* Regular meals */}
        {food.saved.length > 0 && (
          <>
            <SectionLabel right={<span onClick={() => setManage(m => !m)} style={{ color: C.warn, cursor: 'pointer' }}>{manage ? 'Done' : 'Manage'}</span>}>Regular meals</SectionLabel>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, padding: '0 4px' }}>
              {food.saved.map(m => (
                <Pill key={m.id} onClick={() => manage ? removeSaved(m.id) : addEntry({ name: m.name, kcal: m.kcal, protein: m.protein, carbs: m.carbs, fat: m.fat, source: 'regular' })}>
                  {manage ? '× ' : '+ '}{m.name} · {fmt(m.protein)}g
                </Pill>
              ))}
            </div>
          </>
        )}

        {/* Today's log */}
        <SectionLabel right={entries.length ? fmt(totals.kcal) + ' kcal' : null}>Today</SectionLabel>
        <GlassCard style={{ padding: entries.length ? '6px 18px' : 18 }}>
          {entries.length === 0 && <div style={{ fontSize: 13, color: C.muted }}>Nothing logged yet today.</div>}
          {entries.map(e => (
            <div key={e.id} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '12px 0', borderBottom: '1px solid rgba(232,217,189,0.06)' }}>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 14, color: C.text, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{e.name}</div>
                <div style={{ fontSize: 12, color: C.muted, fontVariantNumeric: 'tabular-nums' }}>
                  {new Date(e.ts).toLocaleTimeString('en-AU', { hour: 'numeric', minute: '2-digit' })} · {fmt(e.kcal)} kcal · {fmt(e.protein)}g protein
                </div>
              </div>
              <button onClick={() => removeEntry(e.id)} aria-label={'Remove ' + e.name} style={{ background: 'transparent', border: 'none', color: C.faint, fontSize: 18, cursor: 'pointer', padding: 6 }}>×</button>
            </div>
          ))}
        </GlassCard>

        {/* Last 7 days */}
        <SectionLabel right={logged.length ? 'Avg ' + fmt(avg('kcal')) + ' kcal · ' + fmt(avg('protein')) + 'g' : null}>Last 7 days</SectionLabel>
        <GlassCard>
          <div style={{ display: 'flex', alignItems: 'flex-end', gap: 8, height: 110 }}>
            {last7.map(d => {
              const h = t.protein > 0 ? Math.min(1, d.protein / (t.protein * 1.3)) : 0;
              const hit = d.protein >= t.protein;
              return (
                <div key={d.key} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6, height: '100%', justifyContent: 'flex-end' }}>
                  <div style={{ fontSize: 10, color: C.muted, fontVariantNumeric: 'tabular-nums' }}>{d.n ? fmt(d.protein) : ''}</div>
                  <div style={{ width: '100%', maxWidth: 26, height: d.n ? Math.max(4, h * 70) : 4, borderRadius: 6,
                    background: !d.n ? 'rgba(232,217,189,0.08)' : hit ? C.good : C.accent }} />
                  <div style={{ fontSize: 10, color: d.key === today ? C.amber : C.muted }}>{d.label}</div>
                </div>
              );
            })}
          </div>
          <div style={{ fontSize: 11, color: C.muted, marginTop: 10 }}>Protein per day. Green means target hit.</div>
        </GlassCard>

        {toast && (
          <div style={{ position: 'fixed', left: '50%', bottom: 110, transform: 'translateX(-50%)', zIndex: 60,
            background: 'rgba(10,8,6,0.92)', border: '1px solid rgba(196,135,75,0.35)', color: C.amber,
            padding: '10px 16px', borderRadius: 999, fontSize: 13 }}>{toast}</div>
        )}
        <div style={{ height: 110 }} />
      </div>
    );
  };

  // ------------------------------------------------------------- Tab wrappers

  window.BodyScreen = function BodyScreen() {
    const [seg, setSeg] = useSegment('optimiser_body_seg', 'gym');
    const Screen = seg === 'food' ? window.FoodScreen : window.GymScreen;
    return (
      <div>
        <Segments options={[{ id: 'gym', label: 'Gym' }, { id: 'food', label: 'Food' }]} value={seg} onChange={setSeg} />
        <Screen key={seg} />
      </div>
    );
  };

  window.StudyScreen = function StudyScreen() {
    const [seg, setSeg] = useSegment('optimiser_study_seg', 'wam');
    const Screen = { wam: window.WamScreen, cards: window.CardsScreen, quiz: window.QuizScreen }[seg] || window.WamScreen;
    return (
      <div>
        <Segments options={[{ id: 'wam', label: 'WAM' }, { id: 'cards', label: 'Cards' }, { id: 'quiz', label: 'Quiz' }]} value={seg} onChange={setSeg} />
        <Screen key={seg} />
      </div>
    );
  };

  window.HealthScreen = function HealthScreen() {
    return (
      <div>
        <ScreenHeader title="Health" sub="Sleep and recovery" />
        <GlassCard feature>
          <div style={{ fontSize: 15, color: C.text, fontWeight: 600, marginBottom: 8 }}>Coming next</div>
          <div style={{ fontSize: 14, color: C.muted, lineHeight: 1.5 }}>
            An iPhone Shortcut will send last night's sleep and your Apple Health data here every morning,
            so the coach can connect your sleep to your training, food and study.
          </div>
        </GlassCard>
      </div>
    );
  };
})();
