// screen-today.jsx — Daily hero: check-in + today's session

function ScreenToday({ user, dayState, band, onChangePersona }) {
  const profile = MOCK.PROFILES[user];
  const [phase, setPhase] = React.useState('checkin'); // checkin | result
  const [sleep, setSleep] = React.useState(() => {
    const suggested = MOCK.PREFILL && MOCK.PREFILL[user] && MOCK.PREFILL[user].sleep_hours;
    if (suggested != null) return suggested;
    const o = MOCK.OURA[user];
    return (o && o.connected && o.sleep_hours != null) ? o.sleep_hours : (user === 'alex_rivera' ? 7.5 : 7.0);
  });
  const [energy, setEnergy] = React.useState(7);
  const [stress, setStress] = React.useState(3);
  const [soreness, setSoreness] = React.useState({}); // region: 0-10
  const [message, setMessage] = React.useState(dayState === 'halted' ? 'felt chest pain on the walk in' : '');
  const [submitting, setSubmitting] = React.useState(false);
  const [response, setResponse] = React.useState(null);

  // when tweak changes (state/band/persona), reset to checkin
  React.useEffect(() => { setPhase('checkin'); setResponse(null); }, [user]);

  const submit = async () => {
    setSubmitting(true);
    try {
      const res = await window.api.day({
        user_id: user,
        date: window.TODAY,
        checkin: { sleep_hours: sleep, energy, stress, soreness },
        message: message || undefined,
      });
      setResponse(res);
    } catch (e) {
      // Backend hiccup — fall back to the canned mock response so something shows.
      console.warn('[today] api.day failed, using mock:', e && e.message);
      setResponse(MOCK.buildDayResponse({ user, state: dayState, band }));
    }
    setPhase('result');
    setSubmitting(false);
  };

  const retry = async () => {
    setSubmitting(true);
    try {
      const res = await window.api.day({
        user_id: user,
        date: window.TODAY,
        checkin: { sleep_hours: sleep, energy, stress, soreness },
        message: message || undefined,
      });
      setResponse(res);
    } catch (e) {
      console.warn('[today] retry api.day failed, using mock:', e && e.message);
      setResponse(MOCK.buildDayResponse({ user, state: 'success', band }));
    }
    setSubmitting(false);
  };

  return (
    <div className="scr">
      <TodayHeader profile={profile} onSwitch={onChangePersona} />
      {phase === 'checkin'
        ? <CheckinForm
            user={user}
            profile={profile}
            sleep={sleep} setSleep={setSleep}
            energy={energy} setEnergy={setEnergy}
            stress={stress} setStress={setStress}
            soreness={soreness} setSoreness={setSoreness}
            message={message} setMessage={setMessage}
            submitting={submitting} onSubmit={submit}
          />
        : <SessionResult
            profile={profile}
            response={response}
            onRedo={() => { setPhase('checkin'); setResponse(null); }}
            onRetry={retry}
            submitting={submitting}
          />}
    </div>
  );
}

function TodayHeader({ profile, onSwitch }) {
  const today = new Date(window.TODAY + 'T00:00:00');
  const dateStr = today.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' });
  return (
    <div style={{ padding: '24px 22px 14px' }}>
      <div className="row between" style={{ alignItems: 'flex-start' }}>
        <div className="col gap-4">
          <div className="h-eyebrow">{dateStr}</div>
          <div className="h-display">
            Morning, <em>{profile.first_name}</em>.
          </div>
        </div>
        <button onClick={onSwitch}
          style={{
            appearance: 'none', border: '0.5px solid var(--line)',
            background: 'var(--card)', borderRadius: 999,
            width: 38, height: 38, cursor: 'pointer',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontFamily: 'var(--serif)', fontSize: 16, color: 'var(--ink)',
          }} title="Switch profile">
          {profile.first_name[0]}
        </button>
      </div>
    </div>
  );
}

function OuraPanel({ user }) {
  const o = MOCK.OURA[user];
  if (!o || !o.connected) {
    return (
      <div className="card mb-12">
        <div className="row between" style={{ alignItems: 'center' }}>
          <div className="col gap-2">
            <Eyebrow>Oura</Eyebrow>
            <div className="t-body" style={{ color: 'var(--ink)' }}>Connect your ring for recovery-aware training.</div>
          </div>
          <button className="chip">Connect</button>
        </div>
      </div>
    );
  }
  if (o.readiness == null) {
    return (
      <div className="card mb-12">
        <div className="row between baseline">
          <Eyebrow>Oura</Eyebrow>
          <span className="t-mono" style={{ fontSize: 11, color: 'var(--ink-3)' }}>{o.last_sync}</span>
        </div>
        <div className="t-body" style={{ color: 'var(--ink-2)', marginTop: 8 }}>Ring connected — this morning's reading hasn't landed yet. Recovery will use what you log below.</div>
      </div>
    );
  }
  const band = o.readiness >= 85 ? 'green' : o.readiness >= 70 ? 'amber' : 'red';
  const label = band === 'green' ? 'Primed' : band === 'amber' ? 'Steady' : 'Strained';
  const color = band === 'green' ? 'var(--green)' : band === 'amber' ? 'var(--amber)' : 'var(--red)';
  return (
    <div className="card-paper mb-12">
      <div className="row between baseline mb-16">
        <Eyebrow>{o.fresh ? 'Oura · this morning' : 'Oura'}</Eyebrow>
        <span className="t-mono" style={{ fontSize: 11, color: 'var(--ink-3)' }}>{o.last_sync}</span>
      </div>
      <div className="row between" style={{ alignItems: 'flex-end', marginBottom: 18 }}>
        <div className="col gap-2">
          <BigNum value={o.readiness} style={{ color }} />
          <div className="h-eyebrow">Readiness</div>
        </div>
        <Band band={band} label={label} />
      </div>
      <div className="rule-hair mb-16" />
      <div className="row between">
        <Stat label="HRV" value={o.hrv_ms} sub="ms" />
        <Stat label="Resting HR" value={o.rhr_bpm} sub="bpm" />
        <Stat label="Sleep" value={o.sleep_score} sub={(o.sleep_hours != null ? o.sleep_hours.toFixed(1) : '—') + 'h'} />
      </div>
    </div>
  );
}

function CheckinForm({ user, sleep, setSleep, energy, setEnergy, stress, setStress, soreness, setSoreness, message, setMessage, submitting, onSubmit }) {
  return (
    <div style={{ padding: '4px 16px 120px' }}>
      <OuraPanel user={user} />
      <Card className="mb-12">
        <Eyebrow style={{ marginBottom: 12 }}>How'd you sleep</Eyebrow>
        <div className="row between baseline mb-12" style={{ flexWrap: 'nowrap' }}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 4 }}>
            <span className="t-num" style={{ fontSize: 36, lineHeight: 1 }}>{sleep.toFixed(1)}</span>
            <span style={{ fontSize: 13, color: 'var(--ink-3)' }}>hrs</span>
          </div>
          <SleepBadge hours={sleep} />
        </div>
        <input type="range" min={3} max={10} step={0.1} value={sleep}
          className="slider"
          style={{ '--p': ((sleep - 3) / 7 * 100) + '%' }}
          onChange={(e) => setSleep(Number(e.target.value))} />
        <div className="row between t-small" style={{ marginTop: 0 }}>
          <span>3h</span><span>10h</span>
        </div>
      </Card>

      <Card className="mb-12">
        <Slider1to10 label="Energy" value={energy} onChange={setEnergy} anchors={['Flat', 'Wired']} />
      </Card>

      <Card className="mb-12">
        <Slider1to10 label="Stress" value={stress} onChange={setStress} anchors={['Calm', 'Tense']} />
      </Card>

      <SorenessCard soreness={soreness} setSoreness={setSoreness} />

      <Card className="mb-16">
        <Eyebrow style={{ marginBottom: 6 }}>Anything else?</Eyebrow>
        <div className="t-small mb-8">Tweaks, tweaks-in-the-knee, big day ahead. Optional.</div>
        <textarea
          value={message}
          onChange={(e) => setMessage(e.target.value)}
          rows={2}
          placeholder="e.g. left knee a bit cranky"
          style={{
            width: '100%', resize: 'none',
            border: '0.5px solid var(--line)',
            borderRadius: 12, padding: '10px 12px',
            fontFamily: 'var(--sans)', fontSize: 14.5,
            color: 'var(--ink)', background: 'rgba(28,26,20,0.02)',
            outline: 'none',
          }}
        />
      </Card>

      <button className="btn" onClick={onSubmit} disabled={submitting}
        style={{ opacity: submitting ? 0.6 : 1 }}>
        {submitting ? 'Reading the signal…' : (<><span>Build today's session</span><Icon name="arrow" size={18} stroke={2} /></>)}
      </button>
    </div>
  );
}

function SleepBadge({ hours }) {
  if (hours >= 7.5) return <Band band="green" label="Restorative" />;
  if (hours >= 6.5) return <Band band="amber" label="Adequate" />;
  return <Band band="red" label="Short" />;
}

function SorenessCard({ soreness, setSoreness }) {
  const regions = ['Quads','Hamstrings','Glutes','Chest','Back','Shoulders','Calves','Lower back'];
  const has = Object.keys(soreness).filter(k => soreness[k] > 0);
  return (
    <Card className="mb-12">
      <Eyebrow style={{ marginBottom: 8 }}>Soreness</Eyebrow>
      <div className="t-small mb-12">Tap the regions that are still talking to you.</div>
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
        {regions.map(r => {
          const k = r.toLowerCase().replace(' ', '_');
          const on = (soreness[k] || 0) > 0;
          return (
            <button key={r}
              onClick={() => setSoreness({ ...soreness, [k]: on ? 0 : 5 })}
              className={on ? 'chip chip-on' : 'chip'}
              style={{ border: 0, cursor: 'pointer' }}>
              {r}
            </button>
          );
        })}
      </div>
      {has.length > 0 && (
        <div className="t-small" style={{ marginTop: 12, color: 'var(--ink-2)' }}>
          <span style={{ color: 'var(--ink-3)' }}>Logged:</span> {has.map(k => k.replace('_', ' ')).join(', ')}
        </div>
      )}
    </Card>
  );
}

// ── Result states ────────────────────────────────────────────────────────

function SessionResult({ profile, response, onRedo, onRetry, submitting }) {
  if (!response) return null;
  if (response.halted) return <HaltState response={response} onRedo={onRedo} />;
  if (response.generation_failed) return <FailedState response={response} onRetry={onRetry} onRedo={onRedo} submitting={submitting} />;
  return <SuccessState profile={profile} response={response} onRedo={onRedo} />;
}

function SuccessState({ profile, response, onRedo }) {
  const { session, computed } = response;
  const [rpe, setRpe] = React.useState(7);
  const [logging, setLogging] = React.useState(false);
  const [logged, setLogged] = React.useState(false);
  const [logErr, setLogErr] = React.useState(null);
  const logSession = async () => {
    setLogging(true); setLogErr(null);
    try {
      await window.api.log({ user_id: profile.user_id, date: window.TODAY, completed: true, session_difficulty_1_10: rpe });
      try {
        const plan = window.MOCK.PLANS[profile.user_id];
        (plan.current_mesocycle.weeks || []).forEach(function (wk) {
          (wk.sessions || []).forEach(function (s) { if (s.date === window.TODAY) { s.completed = true; s.rpe = rpe; } });
        });
      } catch (e) {}
      setLogged(true);
    } catch (e) { setLogErr((e && e.message) || 'Could not log'); } finally { setLogging(false); }
  };
  const sessTitle = SESSION_LABELS[session.session_type] || session.session_type;
  return (
    <div style={{ padding: '0 16px 120px' }}>
      {/* Recovery hero */}
      <Card style={{ padding: '22px 18px 18px' }} className="mb-12">
        <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
          <RecoveryRing score={computed.recovery_score} band={computed.recovery_band} size={140} />
          <div className="col gap-12" style={{ flex: 1 }}>
            <div className="col gap-2">
              <Eyebrow>Volume</Eyebrow>
              <MultiplierBar value={computed.volume_multiplier} />
            </div>
            <div className="col gap-2">
              <Eyebrow>Intensity</Eyebrow>
              <MultiplierBar value={computed.intensity_multiplier} />
            </div>
            {computed.cycle_phase && (
              <div className="col gap-2">
                <Eyebrow>Cycle</Eyebrow>
                <div className="t-body" style={{ color: 'var(--ink)', textTransform: 'capitalize' }}>{computed.cycle_phase}</div>
              </div>
            )}
            {MOCK.OURA[profile.user_id] && MOCK.OURA[profile.user_id].connected && (
              <div className="col gap-2">
                <Eyebrow>From Oura</Eyebrow>
                <div className="t-small" style={{ color: 'var(--ink-2)' }}>
                  Sleep {MOCK.OURA[profile.user_id].sleep_score} · HRV {MOCK.OURA[profile.user_id].hrv_ms} · Readiness {MOCK.OURA[profile.user_id].readiness}
                </div>
              </div>
            )}
          </div>
        </div>
      </Card>

      {/* Session header */}
      <div style={{ padding: '20px 4px 14px' }}>
        <div className="row between" style={{ alignItems: 'flex-start' }}>
          <div className="col gap-4" style={{ flex: 1, minWidth: 0 }}>
            <Eyebrow>Session</Eyebrow>
            <div className="h-title">{sessTitle}</div>
            <div className="t-small" style={{ marginTop: 2 }}>{session.estimated_minutes} min · {session.blocks.length} blocks</div>
          </div>
          <button onClick={onRedo}
            style={{
              appearance: 'none', cursor: 'pointer',
              background: 'transparent', border: 0, padding: '4px 0 0 0',
              fontFamily: 'var(--mono)', fontSize: 10,
              letterSpacing: '0.14em', textTransform: 'uppercase',
              color: 'var(--ink-2)',
              display: 'inline-flex', alignItems: 'center', gap: 6,
              flexShrink: 0,
            }}>
            <Icon name="refresh" size={12} stroke={2} /> Redo
          </button>
        </div>
      </div>

      {/* Why today */}
      {session.why_today_looks_like_this && (
        <Card className="mb-12">
          <Eyebrow style={{ marginBottom: 10 }}>Why today</Eyebrow>
          <div style={{
            fontSize: 17, lineHeight: 1.4, color: 'var(--ink)',
            textWrap: 'pretty',
          }}>
            {session.why_today_looks_like_this}
          </div>
        </Card>
      )}

      {/* Blocks */}
      {session.blocks.map((b, i) => (
        <BlockCard key={i} block={b} />
      ))}

      {/* Footer actions — log the session */}
      <div className="col gap-8" style={{ marginTop: 18 }}>
        {logged ? (
          <div className="card-paper" style={{ textAlign: 'center', padding: 18 }}>
            <div className="row center gap-8">
              <Icon name="check" size={16} stroke={2.4} color="var(--green)" />
              <span className="t-body" style={{ color: 'var(--ink)' }}>Logged — nice work.</span>
            </div>
          </div>
        ) : (
          <>
            <Card className="mb-4">
              <Slider1to10 label="How hard was it?" value={rpe} onChange={setRpe} anchors={['Easy', 'All out']} />
            </Card>
            {logErr && <div className="t-small" style={{ color: 'var(--red)' }}>{logErr}</div>}
            <button className="btn" onClick={logSession} disabled={logging} style={{ opacity: logging ? 0.6 : 1 }}>
              <Icon name="check" size={16} stroke={2.2} /> {logging ? 'Logging…' : 'Log this session as done'}
            </button>
            <button className="btn btn-ghost" onClick={onRedo}>Redo check-in</button>
          </>
        )}
      </div>
    </div>
  );
}

function MultiplierBar({ value }) {
  // value typically 0.5–1.2. Mid = 1.0
  const v = Math.max(0.4, Math.min(1.3, value));
  const pct = ((v - 0.4) / 0.9) * 100;
  const isLow = value < 0.95;
  const isHigh = value > 1.05;
  const color = isHigh ? 'var(--green)' : isLow ? 'var(--amber)' : 'var(--ink)';
  return (
    <div className="row gap-10" style={{ alignItems: 'center' }}>
      <div style={{ flex: 1, position: 'relative', height: 6, borderRadius: 999, background: 'rgba(28,26,20,0.08)' }}>
        {/* center tick */}
        <div style={{ position: 'absolute', left: '50%', top: -3, bottom: -3, width: 1, background: 'rgba(28,26,20,0.18)' }} />
        <div style={{
          position: 'absolute', top: 0, bottom: 0,
          left: value >= 1 ? '50%' : `${pct}%`,
          right: value >= 1 ? `${100 - pct}%` : '50%',
          background: color, borderRadius: 999,
        }} />
      </div>
      <div className="t-num" style={{ fontSize: 16, lineHeight: 1, color, minWidth: 38, textAlign: 'right' }}>
        ×{value.toFixed(2)}
      </div>
    </div>
  );
}

function BlockCard({ block }) {
  const label = BLOCK_LABELS[block.block_type] || block.block_type;
  const accent = block.block_type === 'main' ? 'var(--ink)' : 'var(--ink-3)';
  return (
    <Card className="mb-10" flush>
      <div style={{ padding: '14px 18px 8px', borderBottom: '0.5px solid var(--line-2)' }}>
        <div className="row between baseline">
          <Eyebrow style={{ color: accent }}>{label}</Eyebrow>
          <div className="t-small">{block.items.length} {block.items.length === 1 ? 'movement' : 'movements'}</div>
        </div>
      </div>
      <div>
        {block.items.map((it, i) => (
          <ExerciseRow key={i} item={it} last={i === block.items.length - 1} />
        ))}
      </div>
    </Card>
  );
}

function ExerciseRow({ item, last }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'flex-start', gap: 12,
      padding: '12px 18px',
      borderBottom: last ? '0' : '0.5px solid var(--line-2)',
    }}>
      <div className="grow col gap-2" style={{ minWidth: 0 }}>
        <div style={{ fontSize: 16.5, fontWeight: 500, letterSpacing: '-0.015em', color: 'var(--ink)' }}>{item.name}</div>
        {item.notes && <div className="t-small">{item.notes}</div>}
      </div>
      <div className="t-mono" style={{ fontSize: 13, color: 'var(--ink-2)', textAlign: 'right', flexShrink: 0, minWidth: 70 }}>
        {item.sets != null && <span>{item.sets}<span style={{ color: 'var(--ink-3)' }}>×</span>{item.reps || '—'}</span>}
        {item.sets == null && item.reps && <span>{item.reps}</span>}
      </div>
    </div>
  );
}

function HaltState({ response, onRedo }) {
  const { computed } = response;
  return (
    <div style={{ padding: '0 16px 120px' }}>
      <Card>
        <div className="row gap-10 mb-16" style={{ alignItems: 'center' }}>
          <span style={{ width: 10, height: 10, background: 'var(--red)', flexShrink: 0 }} />
          <span style={{
            fontFamily: 'var(--mono)', fontSize: 10, color: 'var(--red)',
            letterSpacing: '0.18em', textTransform: 'uppercase',
          }}>Stop — seek care</span>
        </div>
        <div style={{
          fontSize: 32, lineHeight: 1.02, fontWeight: 500,
          color: 'var(--red)', letterSpacing: '-0.03em', marginBottom: 16,
        }}>
          We're not <em style={{ color: 'rgba(82,30,15,0.55)', fontWeight: 400 }}>training</em> today.
        </div>
        <div style={{ fontSize: 17, lineHeight: 1.4, color: 'var(--ink)', marginBottom: 12, textWrap: 'pretty' }}>
          Your check-in mentioned <em style={{ fontWeight: 500 }}>"{computed.red_flag_match}"</em>.
        </div>
        <div className="t-body" style={{ marginBottom: 0 }}>
          That sits above any training plan. Please contact your doctor or emergency services if you're not sure how bad it is. Your plan will be here when you're back.
        </div>
      </Card>
      <div className="col gap-8" style={{ marginTop: 20 }}>
        <button className="btn" style={{ background: 'var(--red)' }}>
          Call emergency services
        </button>
        <button className="btn btn-ghost" onClick={onRedo}>Edit check-in</button>
      </div>
    </div>
  );
}

function FailedState({ response, onRetry, onRedo, submitting }) {
  const { computed, error } = response;
  return (
    <div style={{ padding: '0 16px 120px' }}>
      {/* Recovery math IS saved — show it */}
      <Card className="mb-0">
        <div className="row gap-16" style={{ alignItems: 'center' }}>
          <RecoveryRing score={computed.recovery_score} band={computed.recovery_band} size={120} />
          <div className="col gap-8" style={{ flex: 1 }}>
            <Eyebrow>Recovery saved</Eyebrow>
            <div className="t-body" style={{ color: 'var(--ink-2)' }}>
              We logged your numbers. Just the session blueprint didn't make it through.
            </div>
          </div>
        </div>
      </Card>

      <Card style={{ borderTop: 0 }}>
        <div className="row gap-10 mb-12" style={{ alignItems: 'center' }}>
          <span style={{ width: 8, height: 8, background: 'var(--amber)', flexShrink: 0 }} />
          <span style={{
            fontFamily: 'var(--mono)', fontSize: 10, color: 'var(--amber)',
            letterSpacing: '0.18em', textTransform: 'uppercase',
          }}>Couldn't generate session</span>
        </div>
        <div style={{ fontSize: 17, lineHeight: 1.4, color: 'var(--ink)', textWrap: 'pretty' }}>
          {error?.message || 'Something hiccupped on our side.'}
        </div>
      </Card>

      <div className="col gap-8" style={{ marginTop: 20 }}>
        <button className="btn" onClick={onRetry} disabled={submitting} style={{ opacity: submitting ? 0.6 : 1 }}>
          {submitting ? 'Retrying…' : 'Try again'}
        </button>
        <button className="btn btn-ghost" onClick={onRedo}>Edit check-in</button>
      </div>
    </div>
  );
}

Object.assign(window, { ScreenToday });
