// app/screen-plan.jsx — AI-driven weekly dinner planner.
// Pick a day → AI pick + cyclable alternatives. Cook this / show another /
// don't plan this day. Inputs rail shows what the AI is weighing.

const RAIL_PATHS = {
  leaf: 'M11 20A7 7 0 019.8 6.1C15.5 5 17 4.5 19 2c1 2 2 4.2 2 8 0 5.5-4.8 10-10 10zM2 21c0-3 1.85-5.4 5.08-6',
  cloud: 'M16 13v6M8 13v5M12 16v5M20 16.6A5 5 0 0018 7h-1.26A8 8 0 104 15.25',
  calendar: 'M8 2v4M16 2v4M3 9h18M5 4h14a2 2 0 012 2v13a2 2 0 01-2 2H5a2 2 0 01-2-2V6a2 2 0 012-2z',
  box: 'M3 7l9-4 9 4v10l-9 4-9-4V7zM3 7l9 4 9-4M12 11v10',
  rotate: 'M3 12a9 9 0 109-9 9 9 0 00-6.36 2.64L3 8M3 3v5h5',
  heart: 'M20.8 4.6a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 10-7.78 7.78L12 21.2l8.84-8.83a5.5 5.5 0 000-7.78z',
};
const RailIcon = ({ name, size = 16 }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
    strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d={RAIL_PATHS[name]} /></svg>
);

function PlanThumb({ recipe, src, style }) {
  if (src) return <img src={src} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block', ...style }} />;
  return <div style={{ width: '100%', height: '100%', background: recipe?.bg || '#1a1610',
    backgroundImage: `repeating-linear-gradient(${recipe?.angle || 35}deg, rgba(255,255,255,0.06) 0 12px, transparent 12px 24px)`, ...style }} />;
}

function dayWeight(label) {
  const w = { Calendar: 'high', Pantry: 'high' };
  return w[label] || (label === 'Favourites' ? 'low' : 'medium');
}

// ── dated carousel helpers ──
const PLAN_DOW = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
const PLAN_MON = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
const planPad = (n) => String(n).padStart(2, '0');
const planIso = (d) => `${d.getFullYear()}-${planPad(d.getMonth() + 1)}-${planPad(d.getDate())}`;
const planDayMeta = (d) => ({ key: planIso(d), day: PLAN_DOW[d.getDay()], date: String(d.getDate()), month: PLAN_MON[d.getMonth()], year: d.getFullYear() });
const planParseKey = (k) => { const [y, m, dd] = (k || '').split('-').map(Number); return new Date(y, (m || 1) - 1, dd || 1); };
const CAROUSEL_PAST = 14;    // days shown before today
const CAROUSEL_FUTURE = 120; // days shown after today

const planNavArrow = { display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
  width: 36, height: 36, borderRadius: 999, cursor: 'pointer', background: 'rgba(255,255,255,0.04)',
  border: '1px solid var(--hairline)', color: 'var(--ink-2)', flexShrink: 0 };
const planTodayBtn = { display: 'inline-flex', alignItems: 'center', gap: 7, height: 36, padding: '0 14px',
  borderRadius: 999, cursor: 'pointer', background: 'rgba(240,168,80,0.10)', border: '1px solid rgba(240,168,80,0.40)',
  color: 'var(--olive)', fontFamily: 'Bricolage Grotesque', fontSize: 12.5, fontWeight: 600,
  letterSpacing: '0.02em', whiteSpace: 'nowrap', flexShrink: 0, boxSizing: 'border-box' };

const AUTO_RANGES = [3, 5, 7, 14];

function AutoScheduleDialog({ isMobile, selObj, range, setRange, override, setOverride, preview, onClose, onConfirm }) {
  const startLabel = selObj ? `${selObj.day} ${selObj.date} ${selObj.month}` : 'the selected day';
  const chip = (on) => ({
    flex: 1, padding: '11px 0', borderRadius: 11, cursor: 'pointer', textAlign: 'center',
    fontFamily: 'Bricolage Grotesque', fontSize: 14, fontWeight: 600, letterSpacing: '0.01em',
    background: on ? 'rgba(240,168,80,0.12)' : 'rgba(255,255,255,0.03)',
    border: on ? '1px solid rgba(240,168,80,0.45)' : '1px solid var(--hairline)',
    color: on ? 'var(--olive)' : 'var(--ink-2)' });
  return (
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 300,
      background: 'rgba(6,6,8,0.62)', backdropFilter: 'blur(6px)', display: 'flex',
      alignItems: isMobile ? 'flex-end' : 'center', justifyContent: 'center',
      padding: isMobile ? 0 : 32 }}>
      <div onClick={(e) => e.stopPropagation()} style={{ width: '100%', maxWidth: isMobile ? '100%' : 440,
        background: 'rgba(20,20,24,0.98)', border: '1px solid var(--hairline)',
        borderRadius: isMobile ? '22px 22px 0 0' : 20, boxShadow: '0 40px 100px rgba(0,0,0,0.7)',
        padding: isMobile ? '24px 20px 28px' : 28, maxHeight: '100%', overflowY: 'auto', boxSizing: 'border-box' }}>

        <div style={{ display: 'flex', alignItems: 'flex-start', gap: 12 }}>
          <div style={{ flex: 1 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 7, fontFamily: 'Bricolage Grotesque',
              fontSize: 10, fontWeight: 600, letterSpacing: '0.24em', textTransform: 'uppercase',
              color: 'var(--olive)' }}>
              <Icon.sparkle size={13} />Auto schedule
            </div>
            <h2 style={{ fontFamily: 'Bricolage Grotesque', fontWeight: 700, fontSize: 25,
              letterSpacing: '-0.03em', color: 'var(--ink)', margin: '10px 0 0', lineHeight: 1.05 }}>
              Fill the plan from
              <span style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontWeight: 400,
                color: 'var(--olive)' }}> {startLabel}.</span>
            </h2>
          </div>
          <button onClick={onClose} style={{ background: 'rgba(255,255,255,0.04)', border: '1px solid var(--hairline)',
            borderRadius: 999, width: 32, height: 32, cursor: 'pointer', color: 'var(--ink-2)', flexShrink: 0,
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }}><Icon.x size={15} /></button>
        </div>

        {/* day range */}
        <div style={{ marginTop: 22 }}>
          <div style={{ fontFamily: 'Bricolage Grotesque', fontSize: 11, fontWeight: 600,
            letterSpacing: '0.16em', textTransform: 'uppercase', color: 'var(--ink-3)', marginBottom: 10 }}>How many days</div>
          <div style={{ display: 'flex', gap: 8 }}>
            {AUTO_RANGES.map((n) => (
              <button key={n} onClick={() => setRange(n)} style={chip(range === n)}>{n} days</button>
            ))}
          </div>
        </div>

        {/* override toggle */}
        <button onClick={() => setOverride(!override)} style={{ marginTop: 16, width: '100%', textAlign: 'left',
          display: 'flex', alignItems: 'flex-start', gap: 12, padding: '14px 15px', borderRadius: 13, cursor: 'pointer',
          background: override ? 'rgba(240,168,80,0.07)' : 'rgba(255,255,255,0.025)',
          border: override ? '1px solid rgba(240,168,80,0.35)' : '1px solid var(--hairline)' }}>
          <span style={{ width: 22, height: 22, borderRadius: 6, marginTop: 1, flexShrink: 0,
            border: override ? 'none' : '1.5px solid var(--ink-3)',
            background: override ? 'linear-gradient(135deg, #f0a850, #c97818)' : 'transparent',
            color: '#1a1208', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            {override && <Icon.check size={13} stroke={3} />}</span>
          <span>
            <span style={{ display: 'block', fontFamily: 'Bricolage Grotesque', fontSize: 14.5, fontWeight: 600,
              color: 'var(--ink)' }}>Replace days that already have a meal</span>
            <span style={{ display: 'block', fontFamily: 'Spectral', fontSize: 13.5, color: 'var(--ink-3)',
              marginTop: 3, lineHeight: 1.4 }}>Off keeps your existing picks; on overwrites them with fresh suggestions.</span>
          </span>
        </button>

        {/* note */}
        <div style={{ marginTop: 12, display: 'flex', alignItems: 'flex-start', gap: 9, padding: '0 2px' }}>
          <span style={{ color: 'var(--ink-4)', marginTop: 1, flexShrink: 0, display: 'flex' }}>
            <RailIcon name="calendar" size={14} /></span>
          <span style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontSize: 13.5, color: 'var(--ink-3)',
            lineHeight: 1.45 }}>Days you've marked “don't plan” are always left untouched.</span>
        </div>

        {/* summary */}
        <div style={{ marginTop: 18, padding: '13px 15px', borderRadius: 12, background: 'rgba(255,255,255,0.025)',
          border: '1px solid var(--hairline)', fontFamily: 'Bricolage Grotesque', fontSize: 13.5, color: 'var(--ink-2)',
          display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
          <span style={{ color: 'var(--ink)', fontWeight: 600 }}>{preview.fill} {preview.fill === 1 ? 'day' : 'days'}</span>
          will be filled
          {preview.kept > 0 && <span style={{ color: 'var(--ink-4)' }}>· {preview.kept} kept</span>}
          {preview.skipped > 0 && <span style={{ color: 'var(--ink-4)' }}>· {preview.skipped} skipped</span>}
        </div>

        {/* actions */}
        <div style={{ marginTop: 22, display: 'flex', gap: 10 }}>
          <FButton size="m" variant="ghost" onClick={onClose} style={{ flex: isMobile ? 1 : 'none' }}>Cancel</FButton>
          <span style={{ flex: 1 }} />
          <FButton size="m" onClick={onConfirm} style={preview.fill ? { flex: isMobile ? 1.6 : 'none' }
            : { flex: isMobile ? 1.6 : 'none', opacity: 0.5, pointerEvents: 'none' }}>
            <Icon.sparkle size={15} />Schedule
          </FButton>
        </div>
      </div>
    </div>
  );
}

function SkipDayCard({ selKey, selLabel, skipReason, onReason, onPlan }) {
  const [reason, setReason] = React.useState(skipReason || '');
  React.useEffect(() => { setReason(skipReason || ''); }, [selKey]);
  return (
    <div style={{ padding: '40px 28px 32px', borderRadius: 18, border: '1px dashed var(--hairline)',
      textAlign: 'center', background: 'rgba(255,255,255,0.015)' }}>
      <div style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontSize: 20, color: 'var(--ink-2)' }}>
        Not cooking {selLabel}.
      </div>
      <div style={{ maxWidth: 360, margin: '16px auto 0' }}>
        <input className="lc-skip-input" value={reason}
          onChange={(e) => { setReason(e.target.value); onReason(e.target.value); }}
          placeholder="Enter a reason (optional)"
          style={{ width: '100%', textAlign: 'center', padding: '8px 10px', background: 'transparent',
            border: 'none', borderBottom: '1px solid var(--hairline)', borderRadius: 0, color: 'var(--ink)',
            fontFamily: 'Spectral', fontSize: 17, outline: 'none', boxSizing: 'border-box' }} />
      </div>
      <button onClick={onPlan} style={{ marginTop: 18, background: 'transparent', border: 'none',
        cursor: 'pointer', color: 'var(--olive)', fontFamily: 'Bricolage Grotesque', fontSize: 14, fontWeight: 500 }}>
        + plan this day instead
      </button>
    </div>
  );
}

function PlanScreen() {
  const { layout, state, getRecipe, photoFor, setPlanDay, openRecipe, go, WEEK_DAYS,
    AI_INPUTS, PLAN_ALTERNATIVES, regeneratePlan, autoSchedule, set,
    settings, setPlanServings, costForServings, money } = useApp();
  const isMobile = layout === 'mobile';
  const isTablet = layout === 'tablet';
  const defaultServes = (settings && settings.defaultPlanningServings) || 2;
  const entryServes = (e) => (e && e.plannedServings) || defaultServes;

  const [selDay, setSelDay] = React.useState(null);
  const [altIdx, setAltIdx] = React.useState(0);
  const [toast, setToast] = React.useState(null);
  const stripRef = React.useRef(null);
  const [visibleMonth, setVisibleMonth] = React.useState('');

  const plan = state.plan;
  const todayKey = (WEEK_DAYS[0] && WEEK_DAYS[0].key) || null;
  // The continuous carousel: many dated days centred on today.
  const days = React.useMemo(() => {
    if (!todayKey) return [];
    const anchor = planParseKey(todayKey);
    const out = [];
    for (let i = -CAROUSEL_PAST; i <= CAROUSEL_FUTURE; i++) {
      const d = new Date(anchor); d.setDate(d.getDate() + i);
      out.push({ ...planDayMeta(d), isToday: i === 0 });
    }
    return out;
  }, [todayKey]);
  const selKey = selDay || todayKey;
  const selObj = days.find((d) => d.key === selKey) || WEEK_DAYS.find((d) => d.key === selKey) || null;
  const selLabel = selObj ? selObj.day : '';

  const entry = (selKey && plan[selKey]) || {};
  const alts = PLAN_ALTERNATIVES;
  const shownId = entry.skip ? null : (entry.recipeId || alts[altIdx % alts.length]);
  const shown = shownId ? getRecipe(shownId) : null;

  // Summary spans from today to the furthest planned day — you can plan well
  // beyond the current week. Cost reflects each meal's planned servings.
  const upcomingPlanned = Object.entries(plan)
    .filter(([k, e]) => e && !e.skip && e.recipeId && k >= todayKey)
    .sort((a, b) => (a[0] < b[0] ? -1 : 1));
  const cooked = upcomingPlanned;
  const total = upcomingPlanned.reduce((s, [, e]) => s + (costForServings(getRecipe(e.recipeId), entryServes(e)) || 0), 0);
  const lastPlannedKey = upcomingPlanned.length ? upcomingPlanned[upcomingPlanned.length - 1][0] : todayKey;
  const planRangeLabel = (() => {
    if (!todayKey) return '';
    const s = planParseKey(todayKey), e = planParseKey(lastPlannedKey);
    if (todayKey === lastPlannedKey) return `from ${s.getDate()} ${PLAN_MON[s.getMonth()]}`;
    if (s.getMonth() === e.getMonth()) return `${s.getDate()}–${e.getDate()} ${PLAN_MON[e.getMonth()]}`;
    return `${s.getDate()} ${PLAN_MON[s.getMonth()]} – ${e.getDate()} ${PLAN_MON[e.getMonth()]}`;
  })();
  const planSummary = cooked.length === 0 ? 'Nothing planned yet'
    : `${planRangeLabel} · ${cooked.length} ${cooked.length === 1 ? 'meal' : 'meals'} · $${total.toFixed(2)}`;

  // planned-servings for the selected day (local, syncs to the entry on commit)
  const [planServes, setPlanServesLocal] = React.useState(defaultServes);
  React.useEffect(() => { setPlanServesLocal(entryServes(plan[selKey] || {})); },
    [selKey, entry.recipeId, entry.plannedServings]);
  const changeServes = (n) => {
    const v = Math.max(1, n);
    setPlanServesLocal(v);
    if (entry.recipeId) setPlanServings(selKey, v);
  };
  const shownTotal = shown ? costForServings(shown, planServes) : null;

  const cookThis = () => {
    if (!shown) return;
    setPlanDay(selKey, { recipeId: shown.id, why: 'you picked this for the night', tag: 'your pick', plannedServings: planServes });
  };
  const showAnother = () => { setPlanDay(selKey, {}); setAltIdx((i) => i + 1); };
  const dontPlan = () => { setPlanDay(selKey, { skip: true }); };

  // ── auto-schedule dialog ──
  const [autoOpen, setAutoOpen] = React.useState(false);
  const [autoRange, setAutoRange] = React.useState(7);
  const [autoOverride, setAutoOverride] = React.useState(false);
  // Live preview of how the run will land on the days from the selected one.
  const autoPreview = React.useMemo(() => {
    let fill = 0, kept = 0, skipped = 0;
    if (selKey) {
      const anchor = planParseKey(selKey);
      for (let i = 0; i < autoRange; i++) {
        const d = new Date(anchor); d.setDate(d.getDate() + i);
        const e = plan[planIso(d)];
        if (e && e.skip) { skipped++; continue; }
        if (e && e.recipeId && !autoOverride) { kept++; continue; }
        fill++;
      }
    }
    return { fill, kept, skipped };
  }, [selKey, autoRange, autoOverride, plan]);
  const runAutoSchedule = async () => {
    const res = await autoSchedule({ start: selKey, days: autoRange, override: autoOverride });
    setAutoOpen(false);
    const n = res && res.filled ? res.filled.length : autoPreview.fill;
    setToast(n ? `Auto-scheduled ${n} ${n === 1 ? 'day' : 'days'}` : 'Nothing to fill — all days are set');
  };

  // ── carousel scroll helpers ──
  const leftPad = isMobile ? 18 : (isTablet ? 32 : 48);
  const updateVisibleMonth = () => {
    const c = stripRef.current; if (!c) return;
    const cLeft = c.getBoundingClientRect().left;
    const kids = c.children;
    for (let i = 0; i < kids.length; i++) {
      const r = kids[i].getBoundingClientRect();
      if (r.right > cLeft + leftPad + 4) { const d = days[i]; if (d) setVisibleMonth(`${d.month} ${d.year}`); break; }
    }
  };
  const scrollStrip = (dir) => {
    const c = stripRef.current; if (!c) return;
    c.scrollBy({ left: dir * c.clientWidth * 0.82, behavior: 'smooth' });
  };
  const goToday = () => {
    setSelDay(todayKey);
    const c = stripRef.current; if (!c) return;
    const el = c.querySelector('[data-today="1"]');
    if (el) c.scrollTo({ left: Math.max(0, el.offsetLeft - leftPad), behavior: 'smooth' });
  };
  // Centre today on first mount (and when layout/data changes) + seed the month
  // label. Two passes (0ms + 140ms) so it outlasts the carousel's fixed-width
  // card layout; offsetLeft is measured against the position:relative strip.
  React.useEffect(() => {
    if (!todayKey) return;
    const c = stripRef.current; if (!c) return;
    const center = () => {
      const el = c.querySelector('[data-today="1"]');
      if (el) c.scrollLeft = Math.max(0, el.offsetLeft - leftPad);
      updateVisibleMonth();
    };
    const t1 = setTimeout(center, 0);
    const t2 = setTimeout(center, 140);
    return () => { clearTimeout(t1); clearTimeout(t2); };
  }, [todayKey, isMobile, isTablet, days.length]);

  // ── day card (one box in the carousel) ──
  const DayCard = ({ d }) => {
    const e = plan[d.key] || {};
    const r = e.recipeId ? getRecipe(e.recipeId) : null;
    const active = selKey === d.key;
    const out = e.skip;
    const today = d.isToday;
    const dayColor = active || today ? 'var(--olive)' : 'var(--ink-3)';

    // ── Mobile: clean uniform pill with a status dot ──
    if (isMobile) {
      const dotColor = out ? 'transparent'
        : r ? (e.tag === 'your pick' ? 'var(--olive)' : 'var(--ink-2)')
        : 'var(--ink-4)';
      return (
        <button data-today={today ? '1' : undefined} onClick={() => { setSelDay(d.key); setAltIdx(0); }} style={{
          flexShrink: 0, width: 60, minHeight: 78, cursor: 'pointer', padding: '10px 8px',
          display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'space-between',
          background: active ? 'linear-gradient(180deg, rgba(240,168,80,0.12), rgba(240,168,80,0.04))' : 'rgba(255,255,255,0.03)',
          border: out ? (active ? '1px dashed rgba(240,168,80,0.6)' : '1px dashed var(--hairline)')
            : active ? '1px solid rgba(240,168,80,0.45)'
            : today ? '1px solid rgba(240,168,80,0.30)' : '1px solid var(--hairline)',
          borderRadius: 14 }}>
          <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 9, fontWeight: 600,
            letterSpacing: '0.16em', textTransform: 'uppercase', color: dayColor }}>{d.day}</span>
          <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 22, fontWeight: 700,
            color: out ? 'var(--ink-4)' : 'var(--ink)', letterSpacing: '-0.03em', lineHeight: 1 }}>{d.date}</span>
          {out
            ? <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 7.5, fontWeight: 600,
                letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--ink-4)' }}>skip</span>
            : <span style={{ width: 6, height: 6, borderRadius: 999, background: dotColor,
                border: r ? 'none' : '1px solid var(--ink-4)' }} />}
        </button>
      );
    }
    return (
      <button data-today={today ? '1' : undefined} onClick={() => { setSelDay(d.key); setAltIdx(0); }} style={{
        textAlign: 'left', cursor: 'pointer', padding: '16px 14px',
        width: isTablet ? 150 : 162, flexShrink: 0,
        background: active ? 'linear-gradient(180deg, rgba(240,168,80,0.10), rgba(240,168,80,0.04))'
          : out ? 'rgba(255,255,255,0.015)' : 'rgba(255,255,255,0.03)',
        border: out ? (active ? '1px dashed rgba(240,168,80,0.6)' : '1px dashed var(--hairline)')
          : active ? '1px solid rgba(240,168,80,0.40)'
          : today ? '1px solid rgba(240,168,80,0.28)' : '1px solid var(--hairline)',
        borderRadius: 14, position: 'relative', display: 'flex', flexDirection: 'column', gap: 8 }}>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
          <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 10, fontWeight: 600,
            letterSpacing: '0.22em', textTransform: 'uppercase', color: dayColor }}>{d.day}</span>
          <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 22, fontWeight: 700,
            color: out ? 'var(--ink-3)' : 'var(--ink)', letterSpacing: '-0.03em' }}>{d.date}</span>
          {today && <span style={{ marginLeft: 'auto', fontFamily: 'Bricolage Grotesque', fontSize: 8,
            fontWeight: 700, letterSpacing: '0.16em', textTransform: 'uppercase', color: 'var(--olive)' }}>today</span>}
        </div>
        {out ? (
          <div style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontSize: 12, color: 'var(--ink-4)',
            minHeight: 36 }}>{e.skipReason || 'not cooking'}</div>
        ) : (
          <React.Fragment>
            <div style={{ fontFamily: 'Spectral', fontSize: 14, color: 'var(--ink)', lineHeight: 1.25,
              minHeight: 36, fontStyle: r ? 'normal' : 'italic' }}>{r ? r.name.split(' with ')[0] : 'tap to pick'}</div>
            {r && (
              <div style={{ display: 'flex', alignItems: 'center', gap: 6, paddingTop: 8,
                borderTop: '1px solid var(--hairline-2)' }}>
                <span style={{ fontFamily: 'var(--mono)', fontSize: 10, color: 'var(--ink-3)' }}>
                  {money(costForServings(r, entryServes(e))) }</span>
                <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 9, color: 'var(--ink-4)',
                  letterSpacing: '0.04em' }}>· {entryServes(e)}p</span>
              </div>
            )}
          </React.Fragment>
        )}
        {e.tag && !out && (
          <span style={{ position: 'absolute', top: -7, right: 10, padding: '2px 8px', borderRadius: 999,
            whiteSpace: 'nowrap', fontFamily: 'Bricolage Grotesque', fontSize: 8, fontWeight: 600,
            letterSpacing: '0.14em', textTransform: 'uppercase',
            background: e.tag === 'your pick' ? 'rgba(240,168,80,0.16)' : 'rgba(255,255,255,0.06)',
            color: e.tag === 'your pick' ? 'var(--olive)' : 'var(--ink-2)' }}>{e.tag}</span>
        )}
      </button>
    );
  };

  // ── pick card ──
  const PickCard = shown && (
    <div style={{ borderRadius: 18, overflow: 'hidden', background: 'var(--paper-2)',
      border: '1px solid rgba(240,168,80,0.30)', boxShadow: '0 24px 60px rgba(0,0,0,0.5)' }}>
      <div onClick={() => openRecipe(shown.id)} style={{ position: 'relative', cursor: 'pointer',
        aspectRatio: isMobile ? '4 / 4.2' : '16 / 9' }}>
        <PlanThumb recipe={shown} src={photoFor(shown.id)} />
        <div style={{ position: 'absolute', inset: 0,
          background: 'linear-gradient(180deg, rgba(0,0,0,0.2) 0%, transparent 35%, rgba(0,0,0,0.7) 100%)' }} />
        <div style={{ position: 'absolute', top: 16, left: 16 }}>
          <FPill accent style={{ background: 'rgba(240,168,80,0.95)', color: '#1a1208', border: 'none',
            fontWeight: 700, letterSpacing: '0.18em' }}>
            ✦ {entry.recipeId ? 'YOUR PICK' : `AI PICK · ${(altIdx % alts.length) + 1}/${alts.length}`}
          </FPill>
        </div>
        <div style={{ position: 'absolute', top: 16, right: 16, display: 'flex', gap: 8 }}>
          {[`★ ${shown.rating || 4}`, money(shownTotal)].map((m, i) => (
            <FPill key={i} style={{ background: 'rgba(12,12,14,0.65)', backdropFilter: 'blur(8px)',
              color: i === 0 ? 'var(--star)' : 'var(--ink)' }}>{m}</FPill>
          ))}
        </div>
        <div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, padding: '22px 24px 20px' }}>
          <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 10, fontWeight: 600,
            letterSpacing: '0.28em', textTransform: 'uppercase', color: 'var(--olive)' }}>
            {(shown.meals || []).slice(0, 3).join(' · ')}
          </span>
          <h2 style={{ fontFamily: 'Bricolage Grotesque', fontWeight: 700, fontSize: isMobile ? 28 : 44,
            lineHeight: 0.95, letterSpacing: '-0.045em', color: '#fff', margin: '8px 0 0',
            textShadow: '0 4px 30px rgba(0,0,0,0.5)' }}>{shown.name}</h2>
        </div>
      </div>
      <div style={{ padding: '18px 24px 16px', display: 'flex', alignItems: 'flex-start', gap: 14,
        background: 'rgba(240,168,80,0.04)', borderTop: '1px solid rgba(240,168,80,0.18)' }}>
        <Icon.sparkle size={16} style={{ color: 'var(--olive)', flexShrink: 0, marginTop: 3 }} />
        <div>
          <div style={{ fontFamily: 'Bricolage Grotesque', fontSize: 10, fontWeight: 600,
            letterSpacing: '0.24em', textTransform: 'uppercase', color: 'var(--olive)' }}>Why this for {selLabel}</div>
          <p style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontSize: isMobile ? 14 : 16,
            lineHeight: 1.5, color: 'var(--ink-2)', margin: '6px 0 0',
            minHeight: isMobile ? 42 : 48,
            display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>
            {entry.why || shown.description || 'A good fit for the night ahead.'}
          </p>
        </div>
      </div>
    </div>
  );

  const DecisionBtns = (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 18, flexWrap: 'wrap' }}>
      <button onClick={cookThis} style={{ flex: isMobile ? 1 : 'none', fontFamily: 'Bricolage Grotesque',
        fontSize: isMobile ? 15 : 16, fontWeight: 600, letterSpacing: '-0.01em', background: 'var(--ink)',
        color: 'var(--paper)', border: 'none', borderRadius: 999, padding: '14px 24px', cursor: 'pointer',
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 9 }}>
        <Icon.check size={17} stroke={2} />Cook this{isMobile ? '' : ` ${selLabel}`}
      </button>
      <button onClick={showAnother} style={{ flex: isMobile ? 1 : 'none', fontFamily: 'Bricolage Grotesque',
        fontSize: 15, fontWeight: 500, background: 'transparent', border: '1px solid var(--hairline)',
        borderRadius: 999, padding: '13px 22px', cursor: 'pointer', color: 'var(--ink-2)', whiteSpace: 'nowrap',
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8 }}>
        {isMobile ? 'Next' : 'Show another'}<Icon.arrow size={15} />
      </button>
      {!isMobile && <span style={{ flex: 1 }} />}
      <button onClick={dontPlan} style={{ fontFamily: 'Bricolage Grotesque', fontSize: 13, fontWeight: 500,
        background: 'transparent', border: '1px solid var(--hairline)', borderRadius: 999,
        padding: '11px 18px', cursor: 'pointer', color: 'var(--ink-3)', width: isMobile ? '100%' : 'auto' }}>
        Don't plan this day
      </button>
    </div>
  );

  const InputsRail = (
    <aside style={{ display: 'flex', flexDirection: 'column', gap: isMobile ? 8 : 14 }}>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 10 }}>
        <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 10, fontWeight: 600,
          letterSpacing: '0.28em', textTransform: 'uppercase', color: 'var(--olive)' }}>What the AI's weighing</span>
        <span style={{ flex: 1, height: 1, background: 'var(--hairline-2)' }} />
      </div>
      {AI_INPUTS.map((i) => (
        <div key={i.label} style={{ padding: '14px 16px', borderRadius: 12, background: 'rgba(255,255,255,0.03)',
          border: '1px solid var(--hairline)' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <span style={{ color: 'var(--olive)', display: 'inline-flex' }}><RailIcon name={i.icon} /></span>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontFamily: 'Bricolage Grotesque', fontSize: 9, fontWeight: 600,
                letterSpacing: '0.24em', textTransform: 'uppercase', color: 'var(--ink-3)' }}>{i.label}</div>
              <div style={{ fontFamily: 'Bricolage Grotesque', fontSize: 14, fontWeight: 500,
                color: 'var(--ink)', letterSpacing: '-0.01em', marginTop: 2 }}>{i.value}</div>
            </div>
            <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 9, fontWeight: 600,
              letterSpacing: '0.18em', padding: '2px 8px', borderRadius: 999, textTransform: 'uppercase',
              background: i.weight === 'high' ? 'rgba(240,168,80,0.15)' : 'rgba(255,255,255,0.06)',
              color: i.weight === 'high' ? 'var(--olive)' : 'var(--ink-3)' }}>{i.weight}</span>
          </div>
          {!isMobile && <div style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontSize: 13,
            color: 'var(--ink-3)', marginTop: 8, paddingTop: 8, borderTop: '1px solid var(--hairline-2)',
            lineHeight: 1.4 }}>{i.detail}</div>}
        </div>
      ))}
    </aside>
  );

  const Header = (
    <div className="lc-planhead" style={{ padding: isMobile ? '20px 18px 14px' : (isTablet ? '32px 32px 12px' : '36px 48px 12px'),
      display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 24, flexWrap: 'wrap' }}>
      <div>
        <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: isMobile ? 10 : 11, fontWeight: 600,
          letterSpacing: '0.28em', textTransform: 'uppercase', color: 'var(--olive)' }}>
          {planSummary}
        </span>
        <h1 style={{ fontFamily: 'Bricolage Grotesque', fontWeight: 700, fontSize: isMobile ? 36 : (isTablet ? 60 : 76),
          lineHeight: 0.92, letterSpacing: '-0.045em', color: 'var(--ink)', margin: '8px 0 0' }}>
          Your <span className="lc-plan-mid">upcoming </span>
          <span style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontWeight: 400, color: 'var(--olive)' }}>meal plan.</span>
        </h1>
      </div>
      {!isMobile && (
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <button onClick={() => scrollStrip(-1)} style={planNavArrow} aria-label="Earlier days">
            <Icon.chevR size={16} style={{ transform: 'rotate(180deg)' }} />
          </button>
          <button onClick={() => scrollStrip(1)} style={planNavArrow} aria-label="Later days">
            <Icon.chevR size={16} />
          </button>
          <button onClick={goToday} style={planTodayBtn}>
            <span style={{ width: 6, height: 6, borderRadius: 999, background: 'var(--olive)' }} />Today
          </button>
          <span style={{ width: 1, height: 26, background: 'var(--hairline)', margin: '0 2px' }} />
          <FButton size="m" variant="ghost" onClick={() => setAutoOpen(true)}
            style={{ height: 36, padding: '0 18px', fontSize: 13 }}>
            <Icon.sparkle size={14} />Auto schedule
          </FButton>
        </div>
      )}
    </div>
  );

  return (
    <Shell tab="plan">
      <div style={{ position: 'relative', minHeight: '100%' }}>
        {Header}
        {/* day carousel — continuous, scrollable across many days */}
        <div style={{ paddingTop: isMobile ? 4 : (isTablet ? 16 : 20) }}>
          <div style={{ padding: isMobile ? '0 18px 10px' : (isTablet ? '0 32px 12px' : '0 48px 12px'),
            display: 'flex', alignItems: 'center', gap: 10 }}>
            <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: isMobile ? 11 : 12, fontWeight: 600,
              letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--ink-2)', minWidth: 92 }}>{visibleMonth}</span>
            <span style={{ flex: 1 }} />
            {isMobile && (
              <button onClick={goToday} style={planTodayBtn}>
                <span style={{ width: 6, height: 6, borderRadius: 999, background: 'var(--olive)' }} />Today
              </button>
            )}
          </div>
          <div ref={stripRef} onScroll={updateVisibleMonth} className="no-scrollbar"
            style={{ display: 'flex', gap: isMobile ? 8 : 10, overflowX: 'auto', position: 'relative',
              padding: isMobile ? '14px 18px 4px' : (isTablet ? '14px 32px 4px' : '14px 48px 4px'),
              WebkitOverflowScrolling: 'touch' }}>
            {days.map((d) => <DayCard key={d.key} d={d} />)}
          </div>
        </div>

        {/* body */}
        <div style={{ padding: isMobile ? '16px 18px 28px' : (isTablet ? '36px 32px 64px' : '40px 48px 80px'),
          display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1.5fr 1fr', gap: isMobile ? 24 : 36 }}>
          <section>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 12, marginBottom: 16 }}>
              <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 10, fontWeight: 600,
                letterSpacing: '0.28em', textTransform: 'uppercase', color: 'var(--olive)' }}>
                {selObj ? `${selObj.day} · ${selObj.date} ${selObj.month}` : ''}
              </span>
              <span style={{ flex: 1, height: 1, background: 'var(--hairline-2)' }} />
            </div>
            {entry.skip ? (
              <SkipDayCard selKey={selKey} selLabel={selLabel} skipReason={entry.skipReason}
                onReason={(t) => setPlanDay(selKey, { skip: true, skipReason: t })}
                onPlan={() => { setPlanDay(selKey, {}); setAltIdx(0); }} />
            ) : (
              <>
                {PickCard}
                {shown && (
                  <div style={{ display: 'flex', alignItems: 'center', gap: 12, rowGap: 10, marginTop: 16, flexWrap: 'wrap',
                    padding: '12px 16px', borderRadius: 14, background: 'rgba(255,255,255,0.03)',
                    border: '1px solid var(--hairline)' }}>
                    <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 11, fontWeight: 600,
                      letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--ink-3)' }}>Cooking for</span>
                    <ServeStepper value={planServes} onChange={changeServes} />
                    {shownTotal != null && (
                      <span style={{ marginLeft: 'auto', fontFamily: 'Bricolage Grotesque', fontWeight: 700,
                        fontSize: 18, color: 'var(--ink)', letterSpacing: '-0.02em' }}>{money(shownTotal)}</span>
                    )}
                  </div>
                )}
                {DecisionBtns}
              </>
            )}
          </section>
          {InputsRail}
        </div>

        {isMobile && (
          <div style={{ padding: '0 18px 28px' }}>
            <FButton size="l" variant="ghost" onClick={() => setAutoOpen(true)} style={{ width: '100%', minHeight: 54 }}>
              <Icon.sparkle size={16} />Auto schedule
            </FButton>
          </div>
        )}

        {autoOpen && (
          <AutoScheduleDialog
            isMobile={isMobile} selObj={selObj}
            range={autoRange} setRange={setAutoRange}
            override={autoOverride} setOverride={setAutoOverride}
            preview={autoPreview}
            onClose={() => setAutoOpen(false)} onConfirm={runAutoSchedule} />
        )}

        {toast && <Toast msg={toast} onClose={() => setToast(null)} />}
      </div>
    </Shell>
  );
}

Object.assign(window, { PlanScreen });
