// screens4.jsx — Plan management: Plans list + Plan editor

// ── PLANS LIST (Plan tab) ────────────────────────────────────
function planIconFor(p) {
  const s = ((p && p.title || '') + ' ' + (p && p.subtitle || '')).toLowerCase();
  if (/\bcore\b|\babs?\b|six.?pack|plank/.test(s)) return 'body-part-six-pack';
  if (/chest|bench|\bpush\b|tricep/.test(s)) return 'equipment-bench-press';
  if (/back|\bpull\b|\brow\b|lat\b|bicep/.test(s)) return 'back-muscle-body';
  if (/leg|quad|ham|glute|calf|squat/.test(s)) return 'body-part-leg';
  if (/shoulder|delt|press/.test(s)) return 'shoulder';
  if (/full|total|condition|hiit|cardio|run/.test(s)) return 'body-part-muscle';
  return 'dumbbell-03';
}

function PlansScreen({ plans, schedule, go, setEditingPlanId, createPlan, todayKey, templates = [], addTemplate, entitled = true, openPaywall, deletePlan, toggleFavPlan, programs = [], activeProgram, viewProgram, openRoutine, initialBrowseTab = 'programs' }) {
  const c = useTheme();
  const todayPid = schedule[todayKey];
  const [browseTab, setBrowseTab] = React.useState(initialBrowseTab);
  // Follow the bottom-nav intent: Programs / Workouts are now separate nav taps,
  // so when the parent's requested tab changes, mirror it here.
  React.useEffect(() => { setBrowseTab(initialBrowseTab); }, [initialBrowseTab]);
  const [tab, setTab]           = React.useState('All');
  const [access, setAccess]     = React.useState('All');
  const [q, setQ]               = React.useState('');
  const [equipState, setEquip]  = React.useState({});
  const [pendingDelete, setPendingDelete] = React.useState(null);
  const [showFavs, setShowFavs] = React.useState(false);
  const deleteTimer = React.useRef(null);

  const LEVELS     = ['Beginner', 'Intermediate', 'Advanced'];
  const GEAR_TYPES = ['Barbell', 'Dumbbell', 'Cable', 'Machine', 'Bodyweight'];
  const lockedCount = templates.filter(t => t.pro && !entitled).length;

  const equipmentOf = (t) => {
    const gears = new Set();
    (t.exercises || []).forEach(e => { const ex = exById(e.id); if (ex && ex.gear) gears.add(ex.gear); });
    return Array.from(gears);
  };

  const cycleEquip = (gear) => setEquip(s => {
    const cur = s[gear];
    if (!cur)              return { ...s, [gear]: 'require' };
    if (cur === 'require') return { ...s, [gear]: 'exclude' };
    const n = { ...s }; delete n[gear]; return n;
  });

  const hasFilters = tab !== 'All' || access !== 'All' || q.trim() || Object.keys(equipState).length > 0;
  const clearFilters = () => { setTab('All'); setAccess('All'); setQ(''); setEquip({}); };

  const upcomingFor = (pid) => {
    const days = [];
    for (let i = 0; i < 7; i++) {
      const d = new Date(); d.setDate(d.getDate() + i);
      if (schedule[ymd(d)] === pid) days.push(d.toLocaleDateString('en-US', { weekday: 'short' }));
    }
    return days;
  };

  const open = (id) => { setEditingPlanId(id); go('plan-editor'); };

  const handleRemoveTap = (e, p) => {
    e.stopPropagation();
    if (pendingDelete === p.id) {
      clearTimeout(deleteTimer.current);
      setPendingDelete(null);
      deletePlan && deletePlan(p.id);
    } else {
      clearTimeout(deleteTimer.current);
      setPendingDelete(p.id);
      deleteTimer.current = setTimeout(() => setPendingDelete(null), 4000);
    }
  };

  // Custom plans = user-created plans that have no matching catalog template.
  // These are shown at the top of Single Workouts since they won't appear in Browse.
  const templateTitles = React.useMemo(() => new Set(templates.map(t => t.title)), [templates]);
  const customPlans = React.useMemo(
    () => plans.filter(p => !p.templateId && !templateTitles.has(p.title)),
    [plans, templateTitles]
  );

  const planCard = (p) => {
    const favorited = p.fav !== false;
    const up = upcomingFor(p.id);
    const isToday = todayPid === p.id;
    const isPending = pendingDelete === p.id;
    return (
      <Card key={p.id} pad={0} onClick={() => !isPending && open(p.id)} style={{ overflow: 'hidden' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14, padding: 16 }}>
          <div style={{ width: 46, height: 46, borderRadius: 'var(--radius-sm)',
            background: isToday ? c.accent : 'var(--surface-2)', color: isToday ? c.accentInk : 'var(--muted)',
            display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
            <Icon name={planIconFor(p)} size={24} />
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <div style={{ flex: 1, minWidth: 0, fontFamily: 'var(--font-display)', fontSize: 21, textTransform: 'uppercase',
                letterSpacing: 0.3, color: 'var(--text)', lineHeight: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{p.title}</div>
              {isToday && <span style={{ fontFamily: 'var(--font-body)', fontSize: 9, fontWeight: 700, letterSpacing: 0.5,
                textTransform: 'uppercase', color: c.accentInk, background: c.accent, padding: '2px 6px', borderRadius: 5, flexShrink: 0 }}>Today</span>}
            </div>
            <div style={{ fontFamily: 'var(--font-body)', fontSize: 12.5, color: 'var(--muted)', marginTop: 2 }}>
              {p.exercises.length} {p.exercises.length === 1 ? 'exercise' : 'exercises'} · {p.subtitle}
            </div>
            {up.length > 0 && (
              <div style={{ fontFamily: 'var(--font-body)', fontSize: 11.5, fontWeight: 600, color: c.accent, marginTop: 5 }}>
                Scheduled · {up.join(', ')}
              </div>
            )}
          </div>
          <button onClick={(e) => { e.stopPropagation(); haptic('light'); toggleFavPlan && toggleFavPlan(p.id); }}
            title={favorited ? 'Remove from favorites' : 'Add to favorites'}
            style={{ width: 34, height: 34, borderRadius: 999, border: 'none', cursor: 'pointer', flexShrink: 0,
              background: favorited ? c.accent + '1f' : 'var(--surface-2)', color: favorited ? c.accent : 'var(--dim)',
              display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'all 0.18s' }}>
            <Icon name="star" size={17} fill={favorited ? 'currentColor' : 'none'} />
          </button>
          <button onClick={(e) => handleRemoveTap(e, p)} title="Delete workout"
            style={{ width: 32, height: 32, borderRadius: 8, border: 'none', cursor: 'pointer', flexShrink: 0,
              background: isPending ? c.danger + '18' : 'var(--surface-2)', color: isPending ? c.danger : 'var(--dim)',
              display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'all 0.18s' }}>
            <Icon name="trash" size={15} />
          </button>
          {!isPending && <span style={{ color: 'var(--dim)', flexShrink: 0 }}><Icon name="chevR" size={18} /></span>}
        </div>
        {isPending && (
          <div style={{ padding: '10px 16px 13px', borderTop: '1px solid var(--border)' }}>
            <div style={{ fontFamily: 'var(--font-body)', fontSize: 13, fontWeight: 600, color: c.danger }}>Tap 🗑 again to permanently delete</div>
            <div style={{ fontFamily: 'var(--font-body)', fontSize: 11.5, color: 'var(--dim)', marginTop: 3 }}>This workout can't be recovered once deleted.</div>
          </div>
        )}
      </Card>
    );
  };

  // When Favorites is active, only show templates that are added + starred.
  const filtered = React.useMemo(() => {
    let ts = templates;
    if (showFavs) ts = ts.filter(t => {
      const added = plans.find(p => p.templateId === t.id || (!p.templateId && p.title === t.title));
      return added && added.fav !== false;
    });
    if (tab !== 'All') ts = ts.filter(t => t.level === tab);
    if (access !== 'All') ts = ts.filter(t => access === 'Pro' ? t.pro : !t.pro);
    if (q.trim()) {
      const lq = q.toLowerCase();
      ts = ts.filter(t => t.title.toLowerCase().includes(lq) || t.subtitle.toLowerCase().includes(lq) || (t.level || '').toLowerCase().includes(lq));
    }
    const required = Object.keys(equipState).filter(g => equipState[g] === 'require');
    const excluded  = Object.keys(equipState).filter(g => equipState[g] === 'exclude');
    if (required.length || excluded.length) {
      ts = ts.filter(t => {
        const eq = equipmentOf(t);
        if (excluded.some(g => eq.includes(g))) return false;
        if (required.length && !required.some(g => eq.includes(g))) return false;
        return true;
      });
    }
    return ts;
  }, [templates, tab, access, q, equipState, showFavs, plans]);

  const showGrouped = !showFavs && tab === 'All' && access === 'All' && !q.trim() && !Object.keys(equipState).length;
  const groups = React.useMemo(() => {
    if (!showGrouped) return null;
    const g = {}; LEVELS.forEach(l => { g[l] = []; });
    filtered.forEach(t => { if (g[t.level]) g[t.level].push(t); });
    return g;
  }, [filtered, showGrouped]);

  const renderTemplateCard = (t) => {
    const added  = plans.find(p => p.templateId === t.id || (!p.templateId && p.title === t.title));
    const locked = t.pro && !entitled;
    const eq     = equipmentOf(t);
    const onClick = () => {
      if (locked)      { haptic('warn'); openPaywall && openPaywall('plans'); }
      else if (added)  { setEditingPlanId(added.id); go('plan-editor'); }
      else             { haptic('success'); addTemplate && addTemplate(t); }
    };
    const onQuickAdd = (e) => {
      e.stopPropagation();
      if (locked) { haptic('warn'); openPaywall && openPaywall('plans'); return; }
      haptic('success'); addTemplate && addTemplate(t, false);
    };
    const onStarToggle = (e) => {
      e.stopPropagation();
      if (!added) { haptic('success'); addTemplate && addTemplate(t, false); return; }
      haptic('light'); toggleFavPlan && toggleFavPlan(added.id);
    };
    return (
      <Card key={t.id} pad={0} onClick={onClick} style={{ overflow: 'hidden' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14, padding: 16 }}>
          <div style={{ width: 46, height: 46, borderRadius: 'var(--radius-sm)', flexShrink: 0,
            background: locked ? 'var(--surface-2)' : c.accent, color: locked ? 'var(--muted)' : c.accentInk,
            display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <Icon name={locked ? 'lock' : (t.icon || planIconFor(t))} size={22} />
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <div style={{ flex: 1, minWidth: 0, fontFamily: 'var(--font-display)', fontSize: 20, textTransform: 'uppercase',
                letterSpacing: 0.3, color: 'var(--text)', lineHeight: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{t.title}</div>
              {t.pro && <span style={{ fontFamily: 'var(--font-body)', fontSize: 9, fontWeight: 800, letterSpacing: 0.6,
                textTransform: 'uppercase', flexShrink: 0, color: c.accentInk, background: c.accent, padding: '2px 6px', borderRadius: 5 }}>Pro</span>}
            </div>
            <div style={{ fontFamily: 'var(--font-body)', fontSize: 12.5, color: 'var(--muted)', marginTop: 3 }}>
              {t.subtitle} · {t.exercises.length} exercises · {t.durationMin} min
            </div>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, marginTop: 6 }}>
              {eq.map(g => {
                const st = equipState[g];
                return (
                  <span key={g} style={{ fontFamily: 'var(--font-body)', fontSize: 10, fontWeight: 600, padding: '2px 7px', borderRadius: 5,
                    background: st === 'exclude' ? c.danger + '18' : st === 'require' ? c.accent + '22' : 'var(--surface-3)',
                    color: st === 'exclude' ? c.danger : st === 'require' ? c.accent : 'var(--dim)' }}>{g}</span>
                );
              })}
            </div>
          </div>
          {locked ? (
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, flexShrink: 0, padding: '8px 12px', borderRadius: 999,
              border: '1px solid ' + c.accent, color: c.accent, fontFamily: 'var(--font-body)', fontSize: 12, fontWeight: 700 }}>
              <Icon name="lock" size={14} /> Unlock
            </span>
          ) : (
            <button onClick={onStarToggle}
              title={added ? (added.fav !== false ? 'Remove from favorites' : 'Add to favorites') : 'Add to favorites'}
              style={{ width: 34, height: 34, borderRadius: 999, border: 'none', cursor: 'pointer', flexShrink: 0,
                background: (added && added.fav !== false) ? c.accent + '1f' : 'var(--surface-2)',
                color: (added && added.fav !== false) ? c.accent : 'var(--dim)',
                display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'all 0.18s' }}>
              <Icon name="star" size={17} fill={(added && added.fav !== false) ? 'currentColor' : 'none'} />
            </button>
          )}
        </div>
      </Card>
    );
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>

      {activeProgram && (
        <ActiveProgramBanner activeProgram={activeProgram} todayKey={todayKey}
          onView={() => { if (viewProgram) viewProgram(activeProgram.id); }} />
      )}

      <div style={{ display: 'flex', gap: 6, padding: 4, background: 'var(--surface-2)', border: '1px solid var(--border)',
        borderRadius: 15, marginBottom: 20 }}>
        {[{ k: 'programs', label: 'Weekly Programs' }, { k: 'workouts', label: 'Daily Workouts' }].map(t => {
          const on = browseTab === t.k;
          return (
            <button key={t.k} onClick={() => setBrowseTab(t.k)} style={{ flex: 1, padding: '11px 8px', borderRadius: 11,
              cursor: 'pointer', border: 'none', background: on ? c.accent : 'transparent', color: on ? c.accentInk : 'var(--muted)',
              fontFamily: 'var(--font-display)', fontSize: 15.5, letterSpacing: 0.5, textTransform: 'uppercase', whiteSpace: 'nowrap',
              boxShadow: on ? `0 6px 16px -9px ${c.accent}` : 'none' }}>{t.label}</button>
          );
        })}
      </div>

      {/* ── PROGRAMS ── */}
      {browseTab === 'programs' && (
        <ProgramsBrowse programs={programs} activeProgram={activeProgram} entitled={entitled}
          viewProgram={viewProgram} openPaywall={openPaywall} />
      )}

      {/* ── SINGLE WORKOUTS TAB ── */}
      {browseTab === 'workouts' && (
        <>
          {/* Lead: description + actions — mirrors the Programs screen */}
          <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12 }}>
            <div style={{ fontFamily: 'var(--font-body)', fontSize: 12.5, color: 'var(--muted)' }}>
              Single sessions you can run any day or drop onto your calendar.
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexShrink: 0 }}>
              {hasFilters && !showFavs && (
                <button onClick={clearFilters} style={{ background: 'none', border: 'none', cursor: 'pointer',
                  fontFamily: 'var(--font-body)', fontSize: 12, fontWeight: 700, color: 'var(--muted)' }}>Clear</button>
              )}
              <button onClick={() => { haptic('tick'); setShowFavs(f => !f); if (showFavs) clearFilters(); }}
                style={{ display: 'inline-flex', alignItems: 'center', gap: 5, padding: '6px 12px', borderRadius: 999, cursor: 'pointer',
                  fontFamily: 'var(--font-body)', fontSize: 12, fontWeight: 700, transition: 'all .15s',
                  background: showFavs ? c.accent + '1f' : 'var(--surface-2)',
                  color: showFavs ? c.accent : 'var(--dim)',
                  border: '1px solid ' + (showFavs ? 'transparent' : 'var(--border)') }}>
                <Icon name="star" size={13} fill={showFavs ? 'currentColor' : 'none'} /> Favorites
              </button>
            </div>
          </div>

          {/* Your workouts — the user's own custom plans */}
          {customPlans.length > 0 && !showFavs && (
            <div>
              <Eyebrow style={{ marginBottom: 8 }}>Your Workouts</Eyebrow>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                {customPlans.map(p => planCard(p))}
              </div>
            </div>
          )}

          {/* Browse catalog */}
          <div>
            {/* Filters — hidden when Favorites active */}
            {!showFavs && (
              <>
                <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '0 14px', height: 44,
                  background: 'var(--surface-2)', border: '1px solid var(--border)', borderRadius: 999, marginBottom: 14 }}>
                  <span style={{ color: 'var(--muted)', display: 'flex' }}><Icon name="search" size={18} /></span>
                  <input value={q} onChange={e => setQ(e.target.value)} placeholder="Search workouts…"
                    style={{ flex: 1, background: 'none', border: 'none', outline: 'none', color: 'var(--text)', fontFamily: 'var(--font-body)', fontSize: 15 }} />
                  {q && <button onClick={() => setQ('')} style={{ background: 'none', border: 'none', color: 'var(--dim)', cursor: 'pointer', display: 'flex' }}><Icon name="close" size={16} /></button>}
                </div>

                <Eyebrow style={{ marginBottom: 8 }}>Difficulty</Eyebrow>
                <div style={{ display: 'flex', gap: 8, marginBottom: 14, flexWrap: 'wrap' }}>
                  {['All', ...LEVELS].map(f => <Chip key={f} active={tab === f} onClick={() => setTab(f)}>{f}</Chip>)}
                </div>

                <Eyebrow style={{ marginBottom: 8 }}>Plan</Eyebrow>
                <div style={{ display: 'flex', gap: 8, marginBottom: 14, flexWrap: 'wrap' }}>
                  {['All', 'Free', 'Pro'].map(f => <Chip key={f} active={access === f} onClick={() => setAccess(f)}>{f}</Chip>)}
                </div>

                <div style={{ marginBottom: 8 }}>
                  <Eyebrow>Equipment</Eyebrow>
                  <div style={{ fontFamily: 'var(--font-body)', fontSize: 11, color: 'var(--dim)', marginTop: 3 }}>Tap to require · tap again to exclude</div>
                </div>
                <div style={{ display: 'flex', gap: 7, marginBottom: 16, flexWrap: 'wrap' }}>
                  {GEAR_TYPES.map(gear => {
                    const st = equipState[gear];
                    return (
                      <button key={gear} onClick={() => cycleEquip(gear)} style={{
                        display: 'inline-flex', alignItems: 'center', gap: 5, padding: '7px 13px', borderRadius: 999,
                        cursor: 'pointer', border: 'none', outline: 'none', transition: 'all 0.15s',
                        fontFamily: 'var(--font-body)', fontSize: 13, fontWeight: 600,
                        background: st === 'require' ? c.accent : st === 'exclude' ? c.danger : 'var(--surface-2)',
                        color: st === 'require' ? c.accentInk : st === 'exclude' ? '#fff' : 'var(--muted)' }}>
                        {st === 'require' && <Icon name="check" size={13} />}
                        {st === 'exclude' && <Icon name="close" size={13} />}
                        {gear}
                      </button>
                    );
                  })}
                </div>
              </>
            )}

            {hasFilters && !showFavs && (
              <div style={{ fontFamily: 'var(--font-body)', fontSize: 12.5, color: 'var(--dim)', marginBottom: 12 }}>
                {filtered.length} workout{filtered.length !== 1 ? 's' : ''} match{filtered.length === 1 ? 'es' : ''} your filters
              </div>
            )}

            {filtered.length === 0 ? (
              <Card pad={24} style={{ textAlign: 'center', color: 'var(--muted)', fontFamily: 'var(--font-body)', fontSize: 13.5 }}>
                {showFavs ? 'No favorites yet — star any workout to pin it here.' : 'No workouts match your filters.'}
              </Card>
            ) : showGrouped ? (
              LEVELS.map(level => groups[level] && groups[level].length > 0 && (
                <div key={level} style={{ marginBottom: 22 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10 }}>
                    <span style={{ fontFamily: 'var(--font-display)', fontSize: 17, textTransform: 'uppercase',
                      letterSpacing: 0.5, color: 'var(--text)', whiteSpace: 'nowrap' }}>{level}</span>
                    <div style={{ flex: 1, height: 1, background: 'var(--border)' }} />
                    <span style={{ fontFamily: 'var(--font-body)', fontSize: 11.5, color: 'var(--dim)', whiteSpace: 'nowrap' }}>
                      {groups[level].length}
                    </span>
                  </div>
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                    {groups[level].map(renderTemplateCard)}
                  </div>
                </div>
              ))
            ) : (
              <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                {filtered.map(renderTemplateCard)}
              </div>
            )}
          </div>

          {/* Custom Workout button */}
          <button onClick={createPlan} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
            fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: 14, color: 'var(--text)', cursor: 'pointer',
            background: 'var(--surface)', border: '1px dashed var(--border)', borderRadius: 'var(--radius-sm)', padding: '15px 20px' }}>
            <Icon name="plus" size={18} /> Custom Workout
          </button>
        </>
      )}
    </div>
  );
}
// ── ADD-EXERCISE PICKER (inline overlay for the editor) ──────
function ExercisePicker({ library, exclude, onPick, onClose }) {
  const c = useTheme();
  const [q, setQ] = React.useState('');
  const [facets, setFacets] = React.useState({ muscle: 'All', equip: 'All', level: 'All' });
  const filtered = React.useMemo(
    () => filterLibrary(library, { q, ...facets }).filter(e => !exclude.includes(e.id)),
    [library, q, facets, exclude]);
  const CAP = 60;
  const shown = filtered.slice(0, CAP);

  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 45, display: 'flex', flexDirection: 'column', justifyContent: 'flex-end' }}>
      <div onClick={onClose} style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.55)', animation: 'psyfade .2s ease' }} />
      <div style={{ position: 'relative', background: 'var(--surface)', borderTopLeftRadius: 28, borderTopRightRadius: 28,
        borderTop: '1px solid var(--border)', padding: '14px 20px 24px', maxHeight: '78%', display: 'flex', flexDirection: 'column',
        animation: 'psyslide .28s cubic-bezier(.2,.8,.2,1)' }}>
        <div style={{ width: 40, height: 5, borderRadius: 999, background: 'var(--surface-3)', margin: '0 auto 16px', flexShrink: 0 }} />
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14, flexShrink: 0 }}>
          <Display size={24}>Add Exercise</Display>
          <button onClick={onClose} style={{ background: 'var(--surface-2)', border: 'none', borderRadius: 999, width: 34, height: 34, color: 'var(--text)', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><Icon name="close" size={18} /></button>
        </div>

        <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '0 14px', height: 44, flexShrink: 0,
          background: 'var(--surface-2)', border: '1px solid var(--border)', borderRadius: 999, marginBottom: 12 }}>
          <span style={{ color: 'var(--muted)' }}><Icon name="search" size={18} /></span>
          <input value={q} onChange={e => setQ(e.target.value)} placeholder="Search exercises"
            style={{ flex: 1, background: 'none', border: 'none', outline: 'none', color: 'var(--text)', fontFamily: 'var(--font-body)', fontSize: 15 }} />
        </div>
        <div style={{ flexShrink: 0 }}>
          <ExerciseFacets value={facets} onChange={setFacets} />
        </div>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 10, flexShrink: 0 }}>
          <Eyebrow>{filtered.length} result{filtered.length === 1 ? '' : 's'}</Eyebrow>
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 8, overflowY: 'auto', marginTop: 12 }}>
          {shown.map(e => (
            <div key={e.id} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <ExerciseThumb id={e.id} size={46} />
              <button onClick={() => onPick(e.id)} style={{ flex: 1, minWidth: 0, display: 'flex', alignItems: 'center', gap: 13, padding: 12, textAlign: 'left',
                background: 'var(--surface-2)', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)', cursor: 'pointer' }}>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: 15, color: 'var(--text)' }}>{e.name}</div>
                  <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--muted)' }}>{e.muscle} · {e.gear}</div>
                </div>
                <span style={{ color: c.accent, flexShrink: 0, display: 'flex', alignItems: 'center', gap: 4, fontFamily: 'var(--font-body)', fontSize: 12, fontWeight: 700 }}>Add <Icon name="plus" size={17} /></span>
              </button>
            </div>
          ))}
          {filtered.length === 0 && <div style={{ textAlign: 'center', color: 'var(--dim)', fontFamily: 'var(--font-body)', padding: 24 }}>Nothing to add.</div>}
          {filtered.length > CAP && (
            <div style={{ textAlign: 'center', color: 'var(--dim)', fontFamily: 'var(--font-body)', fontSize: 12, padding: '10px 0 4px' }}>
              Showing first {CAP} of {filtered.length} — search or filter to narrow down.
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

// ── PLAN EDITOR ──────────────────────────────────────────────
function PlanEditor({ plan, library, go, updatePlan, deletePlan, addExerciseToPlan, removeExerciseFromPlan, setPlanExerciseSets }) {
  const c = useTheme();
  const [picking, setPicking] = React.useState(false);
  const [confirmDel, setConfirmDel] = React.useState(false);

  if (!plan) {
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        <ScreenHeader eyebrow="Workout" title="Not found" />
        <Card pad={20} style={{ textAlign: 'center', color: 'var(--muted)', fontFamily: 'var(--font-body)' }}>This workout no longer exists.</Card>
        <AccentButton onClick={() => go('plan')} icon={<Icon name="chevL" size={18} />}>Back to workouts</AccentButton>
      </div>
    );
  }

  const inputStyle = {
    width: '100%', boxSizing: 'border-box', padding: '12px 14px', borderRadius: 'var(--radius-sm)',
    background: 'var(--surface-2)', border: '1px solid var(--border)', color: 'var(--text)',
    fontFamily: 'var(--font-body)', fontSize: 16, outline: 'none',
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
      <ScreenHeader eyebrow="Editing workout" title="Edit Workout" />

      {/* name + focus */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
        <div>
          <Eyebrow style={{ marginBottom: 8 }}>Workout name</Eyebrow>
          <input value={plan.title} onChange={e => updatePlan(plan.id, { title: e.target.value })}
            placeholder="e.g. Push Day" style={{ ...inputStyle, fontFamily: 'var(--font-display)', fontSize: 22, textTransform: 'uppercase', letterSpacing: 0.3 }} />
        </div>
        <div>
          <Eyebrow style={{ marginBottom: 8 }}>Focus / muscles</Eyebrow>
          <input value={plan.subtitle} onChange={e => updatePlan(plan.id, { subtitle: e.target.value })}
            placeholder="e.g. Chest · Shoulders · Triceps" style={inputStyle} />
        </div>
      </div>

      {/* exercises */}
      <div>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
          <Eyebrow>Exercises · {plan.exercises.length}</Eyebrow>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 9 }}>
          {plan.exercises.map((e, i) => {
            const ex = exById(e.id);
            return (
              <div key={e.id} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: 13,
                background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)' }}>
                <span style={{ fontFamily: 'var(--font-display)', fontSize: 18, color: 'var(--dim)', width: 22, flexShrink: 0 }}>{String(i + 1).padStart(2, '0')}</span>
                <ExerciseThumb id={e.id} size={40} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: 15, color: 'var(--text)' }}>{ex.name}</div>
                  <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--muted)' }}>{ex.muscle} · {ex.gear}</div>
                </div>
                {/* sets stepper */}
                <div style={{ display: 'flex', alignItems: 'center', gap: 7, flexShrink: 0 }}>
                  <button onClick={() => setPlanExerciseSets(plan.id, e.id, e.sets.length - 1)} style={stepBtn}><Icon name="minus" size={15} /></button>
                  <div style={{ textAlign: 'center', minWidth: 34 }}>
                    <div style={{ fontFamily: 'var(--font-display)', fontSize: 18, color: 'var(--text)', lineHeight: 1 }}>{e.sets.length}</div>
                    <div style={{ fontFamily: 'var(--font-body)', fontSize: 8.5, fontWeight: 700, letterSpacing: 0.4, textTransform: 'uppercase', color: 'var(--dim)' }}>sets</div>
                  </div>
                  <button onClick={() => setPlanExerciseSets(plan.id, e.id, e.sets.length + 1)} style={stepBtn}><Icon name="plus" size={15} /></button>
                </div>
                <button onClick={() => removeExerciseFromPlan(plan.id, e.id)} style={{ background: 'none', border: 'none', color: 'var(--dim)', cursor: 'pointer', display: 'flex', padding: 2, flexShrink: 0 }}><Icon name="trash" size={17} /></button>
              </div>
            );
          })}
          {plan.exercises.length === 0 && (
            <Card pad={20} style={{ textAlign: 'center', color: 'var(--muted)', fontFamily: 'var(--font-body)', fontSize: 13 }}>
              No exercises yet — add some below.
            </Card>
          )}
        </div>
        <button onClick={() => setPicking(true)} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, marginTop: 10,
          fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: 14, color: 'var(--text)', cursor: 'pointer', width: '100%',
          background: 'var(--surface)', border: '1px dashed var(--border)', borderRadius: 'var(--radius-sm)', padding: '13px 20px' }}>
          <Icon name="plus" size={18} /> Add exercise
        </button>
      </div>

      <AccentButton onClick={() => go('plan')} icon={<Icon name="check" size={18} />}>Done</AccentButton>

      {/* delete */}
      {confirmDel ? (
        <Card pad={16} style={{ display: 'flex', flexDirection: 'column', gap: 12, borderColor: c.danger }}>
          <div style={{ fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: 15, color: 'var(--text)' }}>Delete “{plan.title}”?</div>
          <div style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--muted)', lineHeight: 1.4 }}>This removes the workout and any calendar days assigned to it. This can't be undone.</div>
          <div style={{ display: 'flex', gap: 10 }}>
            <button onClick={() => setConfirmDel(false)} style={{ flex: 1, padding: '12px', borderRadius: 'var(--radius-sm)', background: 'var(--surface-2)', border: '1px solid var(--border)', color: 'var(--text)', fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: 14, cursor: 'pointer' }}>Cancel</button>
            <button onClick={() => deletePlan(plan.id)} style={{ flex: 1, padding: '12px', borderRadius: 'var(--radius-sm)', background: c.danger, border: 'none', color: '#fff', fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: 14, cursor: 'pointer' }}>Delete</button>
          </div>
        </Card>
      ) : (
        <button onClick={() => setConfirmDel(true)} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
          fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: 14, color: c.danger, cursor: 'pointer',
          background: 'none', border: 'none', padding: '4px 0 8px' }}>
          <Icon name="trash" size={16} /> Delete workout
        </button>
      )}

      {picking && (
        <ExercisePicker library={library} exclude={plan.exercises.map(e => e.id)}
          onPick={(id) => { addExerciseToPlan(plan.id, id); setPicking(false); }} onClose={() => setPicking(false)} />
      )}
    </div>
  );
}

const stepBtn = {
  width: 30, height: 30, borderRadius: 9, border: '1px solid var(--border)', background: 'var(--surface-2)',
  color: 'var(--text)', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
};

Object.assign(window, { PlansScreen, PlanEditor, ExercisePicker, planIconFor });
