// FOOD-рулетка — Telegram Mini App redesign
// All screens + roulette in one file to keep scope clean.

const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ─── Data ───────────────────────────────────────────────────────────
const SLOT_LABEL = {
  breakfast: "Завтрак",
  lunch: "Обед",
  snack: "Полдник",
  dinner: "Ужин",
  late: "Поздник",
  extra_snack: "Перекус",
};
const SLOTS = ["breakfast", "lunch", "snack", "dinner", "late"];
const SLOT_EMOJI = {
  breakfast: "🍳",
  lunch: "🥩",
  snack: "🧀",
  dinner: "🐟",
  late: "🥛",
  extra_snack: "🍩",
};

const INITIAL_LIBRARY = {
  breakfast: [
    { id: 1, name: "Омлет с авокадо", carbs_g: 4 },
    { id: 2, name: "Греческий йогурт с орехами", carbs_g: 8 },
    { id: 3, name: "Творог с малиной", carbs_g: 6 },
    { id: 4, name: "Яйца пашот + бекон", carbs_g: 2 },
  ],
  lunch: [
    { id: 10, name: "Стейк рибай + спаржа", carbs_g: 5 },
    { id: 11, name: "Куриная грудка + цуккини", carbs_g: 7 },
    { id: 12, name: "Лосось на гриле + брокколи", carbs_g: 6 },
    { id: 13, name: "Тёплый салат с тунцом", carbs_g: 9 },
  ],
  snack: [
    { id: 20, name: "Сыр чеддер 40г", carbs_g: 1 },
    { id: 21, name: "Миндаль 30г", carbs_g: 6 },
    { id: 22, name: "Оливки + пармезан", carbs_g: 3 },
  ],
  dinner: [
    { id: 30, name: "Креветки в чесночном масле", carbs_g: 4 },
    { id: 31, name: "Индейка карри + цветная капуста", carbs_g: 9 },
    { id: 32, name: "Свинина + квашеная капуста", carbs_g: 6 },
  ],
  late: [
    { id: 40, name: "Кефир 200мл", carbs_g: 5 },
    { id: 41, name: "Ряженка 150мл", carbs_g: 6 },
  ],
};

const INITIAL_MENU = {
  breakfast: { id: 2, name: "Греческий йогурт с орехами", carbs_g: 8 },
  lunch:     { id: 10, name: "Стейк рибай + спаржа", carbs_g: 5 },
  snack:     { id: 20, name: "Сыр чеддер 40г", carbs_g: 1 },
  dinner:    { id: 30, name: "Креветки в чесночном масле", carbs_g: 4 },
  late:      { id: 40, name: "Кефир 200мл", carbs_g: 5 },
};

// ─── Rarity helpers ────────────────────────────────────────────────
function rarityOf(carbs) {
  if (carbs <= 5)  return "legend";
  if (carbs <= 10) return "epic";
  if (carbs <= 18) return "rare";
  return "common";
}
const RARITY_NAME = {
  legend: "Легендарка",
  epic:   "Эпик",
  rare:   "Редкое",
  common: "Обычное",
};
function rarityClass(carbs) { return `r-${rarityOf(carbs)}`; }

// ─── Format helpers ────────────────────────────────────────────────
const TODAY_PRETTY = () => {
  const d = new Date(2026, 4, 15); // pinned for screenshot consistency
  return d.toLocaleDateString("ru-RU", { weekday: "long", day: "numeric", month: "long" });
};

// ─── Tiny svg icons ────────────────────────────────────────────────
const Icon = {
  back: (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
      <path d="M15 6l-6 6 6 6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  ),
  check: (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
      <path d="M5 12l5 5 9-10" strokeWidth="2.6" />
    </svg>
  ),
  case: (
    <svg width="22" height="22" viewBox="0 0 24 24" fill="none">
      <rect x="3" y="8" width="18" height="12" rx="2" stroke="currentColor" strokeWidth="1.8"/>
      <path d="M3 12h18" stroke="currentColor" strokeWidth="1.8"/>
      <path d="M9 8V6a3 3 0 016 0v2" stroke="currentColor" strokeWidth="1.8"/>
      <circle cx="12" cy="14" r="1.2" fill="currentColor"/>
    </svg>
  ),
  report: (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
      <rect x="5" y="3" width="14" height="18" rx="2" stroke="currentColor" strokeWidth="1.8"/>
      <path d="M9 9l1.5 1.5L14 7" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
      <path d="M9 14h6M9 17h4" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
    </svg>
  ),
  menu: (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
      <path d="M4 7h16M4 12h16M4 17h10" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
    </svg>
  ),
  stats: (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
      <path d="M4 19V5M4 19h16" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
      <rect x="8"  y="12" width="3" height="5" rx="0.5" fill="currentColor"/>
      <rect x="13" y="8"  width="3" height="9" rx="0.5" fill="currentColor"/>
      <rect x="18" y="14" width="3" height="3" rx="0.5" fill="currentColor"/>
    </svg>
  ),
  reroll: (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
      <path d="M4 8a8 8 0 0114-3.5M20 4v4h-4" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
      <path d="M20 16a8 8 0 01-14 3.5M4 20v-4h4" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  ),
  flame: (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor">
      <path d="M13.5 2c.5 2.5 3.5 4 3.5 7.5a5 5 0 11-9.6 1.9c0-1.6 1-2.9 1.5-4.4.3 1 .8 1.6 1.6 2 .2-2 .8-4.5 3-7z"/>
    </svg>
  ),
  diamond: (
    <svg width="12" height="12" viewBox="0 0 24 24" fill="none">
      <path d="M6 9l6-6 6 6-6 12L6 9z" fill="currentColor"/>
      <path d="M6 9h12M12 3v18" stroke="rgba(0,0,0,0.2)" strokeWidth="1"/>
    </svg>
  ),
  trash: (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
      <path d="M5 7h14M10 11v6M14 11v6M6 7l1 12a2 2 0 002 2h6a2 2 0 002-2l1-12M9 7V5a2 2 0 012-2h2a2 2 0 012 2v2" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  ),
  plus: (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
      <path d="M12 5v14M5 12h14" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
    </svg>
  ),
  warn: (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
      <path d="M12 3l10 18H2L12 3z" stroke="currentColor" strokeWidth="1.8" strokeLinejoin="round"/>
      <path d="M12 10v5M12 18v.5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
    </svg>
  ),
};

// ─── Reusable bits ─────────────────────────────────────────────────
function AppBar({ title, onBack, right }) {
  return (
    <div className="appbar">
      {onBack ? (
        <button className="appbar-back" onClick={onBack}>
          {Icon.back}<span>Назад</span>
        </button>
      ) : <div style={{ width: 70 }} />}
      <div className="appbar-title">{title}</div>
      <div style={{ minWidth: 70, display: 'flex', justifyContent: 'flex-end' }}>{right}</div>
    </div>
  );
}

function CreditChip({ value }) {
  return (
    <span className="chip chip-credit mono">
      <span className="dot" />
      {value}
    </span>
  );
}

function StreakChip({ value }) {
  return (
    <span className="chip" style={{ color: '#ffb480', borderColor: 'rgba(255,180,128,0.25)', background: 'rgba(255,180,128,0.10)' }}>
      <span style={{ color: '#ffb480' }}>{Icon.flame}</span>
      <span className="mono">{value}</span>
    </span>
  );
}

// Section wrapper
function Section({ children, style }) {
  return (
    <div style={{ padding: '0 20px', ...style }}>{children}</div>
  );
}

// ─── HOME ──────────────────────────────────────────────────────────
function Home({ go, state }) {
  const { credits, streak, menu, reportsCount } = state;
  const reportedToday = reportsCount > 0;
  return (
    <div className="tg-app no-appbar">
      {/* Brand row */}
      <Section>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', paddingTop: 4 }}>
          <div>
            <div className="section-eyebrow" style={{ marginBottom: 2 }}>{TODAY_PRETTY()}</div>
            <div style={{ fontSize: 26, fontWeight: 800, letterSpacing: '-0.02em', lineHeight: 1.05 }}>
              FOOD<span style={{ color: 'var(--acc)' }}>•</span>рулетка
            </div>
          </div>
          <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
            <StreakChip value={streak} />
            <CreditChip value={credits} />
          </div>
        </div>
      </Section>

      <div style={{ height: 22 }} />

      {/* Hero CTA — Case of the day */}
      <Section>
        <button className="case-cta" onClick={() => go("case")}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', position: 'relative', zIndex: 1 }}>
            <div>
              <div className="section-eyebrow" style={{ color: 'rgba(200,255,46,0.85)' }}>
                Кейс дня
              </div>
              <div style={{ fontSize: 22, fontWeight: 700, letterSpacing: '-0.015em', marginTop: 6, maxWidth: 230 }}>
                Открой меню на сегодня
              </div>
              <div style={{ color: 'var(--fg-2)', fontSize: 13, marginTop: 8, maxWidth: 220 }}>
                5 приёмов пищи · крутка бесплатно · перекрут 1 💎
              </div>
            </div>
            {/* Mini case visual */}
            <div style={{
              position: 'relative', width: 78, height: 78, borderRadius: 18,
              background: 'linear-gradient(160deg, rgba(255,255,255,0.06), rgba(0,0,0,0.4))',
              border: '1px solid rgba(200,255,46,0.30)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              boxShadow: '0 12px 28px -10px rgba(200,255,46,0.4)',
              color: 'var(--acc)',
              flexShrink: 0,
            }}>
              {Icon.case}
              <div style={{
                position: 'absolute', top: -6, right: -6,
                background: 'var(--acc)', color: 'var(--acc-ink)',
                fontSize: 10, fontWeight: 700, padding: '2px 7px',
                borderRadius: 999,
              }}>NEW</div>
            </div>
          </div>
          <div style={{ height: 18 }} />
          <div style={{ display: 'flex', gap: 4, position: 'relative', zIndex: 1 }}>
            {SLOTS.map(s => {
              const d = menu[s];
              const cls = d ? rarityClass(d.carbs_g) : 'r-common';
              return (
                <div key={s} className={cls} style={{
                  flex: 1, height: 28, borderRadius: 6,
                  background: 'var(--rarity-soft)',
                  border: '1px solid var(--rarity-color)',
                  borderColor: 'var(--rarity-color)',
                  opacity: 0.85,
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontSize: 14,
                }}>{SLOT_EMOJI[s]}</div>
              );
            })}
          </div>
        </button>
      </Section>

      <div style={{ height: 16 }} />

      {/* 2×2 tile grid */}
      <Section>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
          <button className="tile" onClick={() => go("report")}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <div className="tile-icon" style={reportedToday ? { background: 'var(--acc-soft)', color: 'var(--acc)' } : {}}>{Icon.report}</div>
              {reportedToday && <span className="chip" style={{ height: 22, padding: '0 8px', fontSize: 11 }}>
                <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--ok)' }} />активно
              </span>}
            </div>
            <div style={{ flex: 1 }} />
            <div>
              <div className="tile-title">Отчёт</div>
              <div className="tile-sub">{reportsCount}/5 отмечено</div>
            </div>
          </button>

          <button className="tile" onClick={() => go("menu")}>
            <div className="tile-icon">{Icon.menu}</div>
            <div style={{ flex: 1 }} />
            <div>
              <div className="tile-title">Меню</div>
              <div className="tile-sub">17 блюд в библиотеке</div>
            </div>
          </button>

          <button className="tile" onClick={() => go("stats")} style={{ gridColumn: 'span 2' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%' }}>
              <div className="tile-icon">{Icon.stats}</div>
              <div style={{ display: 'flex', gap: 16, alignItems: 'baseline' }}>
                <div>
                  <div className="tile-sub">Средне</div>
                  <div className="mono" style={{ fontSize: 16, fontWeight: 700 }}>9.2<span style={{ color: 'var(--muted)', fontSize: 11 }}>г/день</span></div>
                </div>
                <div>
                  <div className="tile-sub">Чистых</div>
                  <div className="mono" style={{ fontSize: 16, fontWeight: 700 }}>5<span style={{ color: 'var(--muted)', fontSize: 11 }}>/6</span></div>
                </div>
              </div>
            </div>
            <div style={{ flex: 1 }} />
            <div>
              <div className="tile-title">Сводка за неделю</div>
              <div className="tile-sub">советы + статистика углей</div>
            </div>
          </button>
        </div>
      </Section>

      <div style={{ height: 20 }} />

      {/* Today's plan preview */}
      <Section>
        <div className="section-eyebrow" style={{ marginBottom: 10, paddingLeft: 4 }}>
          План на сегодня
        </div>
        <div className="surface" style={{ padding: 4 }}>
          {SLOTS.map((s, i) => {
            const d = menu[s];
            const cls = d ? rarityClass(d.carbs_g) : '';
            return (
              <div key={s} className={cls} style={{
                display: 'flex', alignItems: 'center', gap: 12,
                padding: '10px 12px',
                borderBottom: i < SLOTS.length - 1 ? '1px solid var(--line)' : 'none',
              }}>
                <div style={{
                  width: 32, height: 32, borderRadius: 8,
                  background: 'var(--rarity-soft, var(--surface-3))',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontSize: 15,
                  border: '1px solid var(--rarity-soft, transparent)',
                }}>{SLOT_EMOJI[s]}</div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.12em', color: 'var(--muted)', fontWeight: 600 }}>
                    {SLOT_LABEL[s]}
                  </div>
                  <div style={{ fontSize: 14, fontWeight: 500, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                    {d ? d.name : 'не назначено'}
                  </div>
                </div>
                {d && <span className="mono" style={{
                  fontSize: 12, fontWeight: 600, color: 'var(--rarity-color)',
                  background: 'var(--rarity-soft)',
                  padding: '3px 8px', borderRadius: 6,
                }}>{d.carbs_g}г</span>}
              </div>
            );
          })}
        </div>
      </Section>

      <div style={{ height: 20 }} />

      {/* Reset link */}
      <Section>
        <button onClick={() => {
          if (confirm("Сбросить профиль полностью?")) alert("(демо) Профиль сброшен");
        }} style={{
          background: 'none', border: 'none', color: 'var(--muted)',
          fontSize: 12, cursor: 'pointer', width: '100%', padding: 8,
        }}>
          Сбросить профиль
        </button>
      </Section>
    </div>
  );
}

// ─── ROULETTE ──────────────────────────────────────────────────────
function Roulette({ pool, target, onDone }) {
  const [offset, setOffset] = useState(0);
  const [spinning, setSpinning] = useState(false);
  const stripRef = useRef(null);
  const wrapRef = useRef(null);

  const strip = useRef([]);
  if (strip.current.length === 0) {
    const items = [];
    for (let i = 0; i < 38; i++) {
      items.push(pool[Math.floor(Math.random() * pool.length)] || target);
    }
    items.push(target);
    for (let i = 0; i < 6; i++) {
      items.push(pool[Math.floor(Math.random() * pool.length)] || target);
    }
    strip.current = items;
  }
  const targetIndex = 38;
  const cardWidth = 130; // 120 + 10 gap

  useEffect(() => {
    const wrap = wrapRef.current;
    if (!wrap) return;
    const center = wrap.clientWidth / 2;
    const jitter = (Math.random() - 0.5) * (cardWidth - 40);
    const finalOffset = targetIndex * cardWidth + cardWidth / 2 - center + jitter;
    requestAnimationFrame(() => {
      setSpinning(true);
      setOffset(-finalOffset);
    });
    const t = setTimeout(onDone, 5300);
    return () => clearTimeout(t);
  }, []);

  return (
    <div className="roulette" ref={wrapRef}>
      <div className="roulette-pointer-top" />
      <div className="roulette-pointer-bottom" />
      <div className="roulette-center-line" />
      <div
        ref={stripRef}
        className={`roulette-strip ${spinning ? "spinning" : ""}`}
        style={{ transform: `translateX(${offset}px)` }}
      >
        {strip.current.map((d, i) => (
          <div key={i} className={`case-card ${rarityClass(d.carbs_g)}`}>
            <div>
              <div className="cc-slot">{SLOT_EMOJI[d.meal_slot] || ''} {SLOT_LABEL[d.meal_slot] || ''}</div>
              <div className="cc-name" style={{ marginTop: 6 }}>{d.name}</div>
            </div>
            <div>
              <div className="cc-carbs mono">{d.carbs_g} г углей</div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ─── CASE OPEN ─────────────────────────────────────────────────────
function CaseOpen({ onBack, state, setState }) {
  const { credits, menu } = state;
  const [phase, setPhase] = useState("intro"); // intro | spinning | revealed
  const [spinSlot, setSpinSlot] = useState(null); // null = full | slot

  const pool = useMemo(() => {
    const flat = [];
    for (const s of SLOTS) for (const d of INITIAL_LIBRARY[s] || []) flat.push({ ...d, meal_slot: s });
    return flat;
  }, []);

  function startFull() {
    setSpinSlot("__full__");
    setPhase("spinning");
  }
  function startReroll(slot) {
    if (credits < 1) return;
    setSpinSlot(slot);
    setPhase("spinning");
    // pick a new dish for that slot
    const choices = INITIAL_LIBRARY[slot].filter(d => d.id !== menu[slot]?.id);
    const next = choices[Math.floor(Math.random() * choices.length)] || INITIAL_LIBRARY[slot][0];
    setState(s => ({ ...s, credits: s.credits - 1, menu: { ...s.menu, [slot]: next } }));
  }

  const targetForRoulette =
    spinSlot === "__full__"
      ? { ...Object.values(menu)[0], meal_slot: SLOTS[0] }
      : spinSlot
        ? { ...menu[spinSlot], meal_slot: spinSlot }
        : null;

  return (
    <div className="tg-app has-appbar">
      <AppBar
        title="Кейс дня"
        onBack={onBack}
        right={<CreditChip value={credits} />}
      />

      {phase === "intro" && (
        <>
          <div style={{ height: 20 }} />
          <Section>
            <div style={{ textAlign: 'center', padding: '20px 0' }}>
              <div style={{
                width: 140, height: 140, margin: '0 auto',
                borderRadius: 28,
                background: `
                  radial-gradient(closest-side at 50% 30%, rgba(200,255,46,0.35), transparent 70%),
                  linear-gradient(180deg, #1d2210 0%, #0f1208 100%)`,
                border: '1px solid rgba(200,255,46,0.40)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                boxShadow: '0 20px 60px -20px rgba(200,255,46,0.5), inset 0 1px 0 rgba(255,255,255,0.06)',
                color: 'var(--acc)',
                position: 'relative',
              }}>
                <div style={{ transform: 'scale(2.6)' }}>{Icon.case}</div>
                <div style={{
                  position: 'absolute', top: 10, right: 10,
                  fontSize: 9, letterSpacing: '0.16em', fontWeight: 700,
                  color: 'var(--acc)', textTransform: 'uppercase',
                }}>15 мая</div>
              </div>
              <div style={{ fontSize: 22, fontWeight: 700, letterSpacing: '-0.015em', marginTop: 22 }}>
                Кейс готов к открытию
              </div>
              <div style={{ color: 'var(--fg-2)', fontSize: 14, marginTop: 6, maxWidth: 280, marginInline: 'auto' }}>
                Внутри — случайные блюда из твоей библиотеки.<br/>Можно перекрутить любое за 1 💎.
              </div>
            </div>
          </Section>
          <div style={{ height: 14 }} />
          <Section>
            <button className="btn btn-primary" onClick={startFull} style={{ height: 54, fontSize: 16 }}>
              <span style={{ marginRight: 4 }}>{Icon.case}</span>
              Открыть кейс
            </button>
            <div style={{ height: 12 }} />
            <div className="surface" style={{ padding: 14, display: 'flex', alignItems: 'center', gap: 12 }}>
              <div style={{ fontSize: 11, color: 'var(--muted)', textTransform: 'uppercase', letterSpacing: '0.1em', fontWeight: 600 }}>Шансы выпадения</div>
              <div style={{ flex: 1, display: 'flex', gap: 6 }}>
                {['legend','epic','rare','common'].map(r => (
                  <div key={r} className={`r-${r}`} style={{
                    flex: r === 'legend' ? 1 : r === 'epic' ? 2 : r === 'rare' ? 2 : 1,
                    height: 6, borderRadius: 3, background: 'var(--rarity-color)', opacity: 0.85,
                  }} />
                ))}
              </div>
            </div>
          </Section>
        </>
      )}

      {phase === "spinning" && targetForRoulette && (
        <>
          <div style={{ height: 16 }} />
          <Section>
            <div className="section-eyebrow" style={{ marginBottom: 10, paddingLeft: 4 }}>
              {spinSlot === "__full__" ? 'Открытие кейса…' : `Перекрут · ${SLOT_LABEL[spinSlot]}`}
            </div>
            <Roulette
              key={spinSlot + Math.random()}
              pool={pool}
              target={targetForRoulette}
              onDone={() => setPhase("revealed")}
            />
          </Section>
          <div style={{ height: 16 }} />
          <Section>
            <div style={{ textAlign: 'center', color: 'var(--muted)', fontSize: 13 }}>
              <span className="pulse" style={{ display: 'inline-block', width: 6, height: 6, borderRadius: '50%', background: 'var(--acc)', marginRight: 6, verticalAlign: 'middle' }}/>
              крутим…
            </div>
          </Section>
        </>
      )}

      {phase === "revealed" && (
        <>
          <div style={{ height: 12 }} />
          <Section>
            <div className="section-eyebrow" style={{ marginBottom: 10, paddingLeft: 4 }}>
              Меню на сегодня
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              {SLOTS.map((s, idx) => {
                const d = menu[s];
                if (!d) return null;
                const rcls = rarityClass(d.carbs_g);
                return (
                  <div key={s} className={`slot-card reveal-anim ${rcls}`} style={{ animationDelay: `${idx * 70}ms` }}>
                    <div className="glow" />
                    <div className="slot-icon">{SLOT_EMOJI[s]}</div>
                    <div className="slot-meta">
                      <div className="slot-eyebrow">
                        <span className="rarity-dot" />
                        {SLOT_LABEL[s]} · {RARITY_NAME[rarityOf(d.carbs_g)]}
                      </div>
                      <div className="slot-name">{d.name}</div>
                      <div className="slot-carbs mono">
                        <b>{d.carbs_g} г</b> углеводов
                      </div>
                    </div>
                    <button
                      className="btn btn-sm btn-ghost"
                      disabled={credits < 1}
                      onClick={() => startReroll(s)}
                      title="Перекрутить за 1💎"
                      style={{ width: 'auto', flexShrink: 0 }}
                    >
                      {Icon.reroll}<span className="mono" style={{ marginLeft: 4 }}>1</span>
                    </button>
                  </div>
                );
              })}
            </div>
            <div style={{ height: 14 }} />
            <button className="btn btn-primary" disabled={credits < 1} onClick={() => startReroll(SLOTS[0])}>
              {Icon.reroll}<span style={{ marginLeft: 6 }}>Перекрутить всё · −1 💎</span>
            </button>
          </Section>
        </>
      )}
    </div>
  );
}

// ─── REPORT ────────────────────────────────────────────────────────
function Report({ onBack, state, setState }) {
  const { menu, credits, reports } = state;
  const [extraOpen, setExtraOpen] = useState(false);
  const [extraName, setExtraName] = useState("");
  const [extraCarbs, setExtraCarbs] = useState("");

  const planned = SLOTS.filter(s => menu[s]);
  const eatenCount = planned.filter(s => reports[s]?.eaten).length;
  const cleanCount = planned.filter(s => reports[s]?.eaten === true).length;
  const totalCarbs = planned.reduce((sum, s) => reports[s]?.eaten ? sum + menu[s].carbs_g : sum, 0)
    + Object.values(reports).reduce((sum, r) => sum + (r.extra_carbs || 0), 0);

  function toggle(slot) {
    setState(s => ({
      ...s,
      reports: { ...s.reports, [slot]: { eaten: !s.reports[slot]?.eaten } },
    }));
  }
  function saveExtra() {
    const c = parseFloat(extraCarbs);
    if (!extraName.trim() || isNaN(c)) return;
    setState(s => ({
      ...s,
      reports: { ...s.reports, ['extra_' + Date.now()]: { extra_name: extraName, extra_carbs: c, eaten: true } },
    }));
    setExtraOpen(false); setExtraName(""); setExtraCarbs("");
  }

  const extras = Object.entries(reports).filter(([k]) => k.startsWith('extra_')).map(([_, r]) => r);

  return (
    <div className="tg-app has-appbar">
      <AppBar
        title="Отчёт за день"
        onBack={onBack}
        right={<CreditChip value={credits} />}
      />

      {/* Progress hero */}
      <Section>
        <div className="surface" style={{ padding: 18 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 10 }}>
            <div>
              <div className="section-eyebrow">прогресс дня</div>
              <div style={{ marginTop: 4, display: 'flex', alignItems: 'baseline', gap: 6 }}>
                <span className="mono" style={{ fontSize: 30, fontWeight: 700, letterSpacing: '-0.02em' }}>{eatenCount}</span>
                <span style={{ color: 'var(--muted)', fontSize: 15 }}>/ {planned.length} приёмов</span>
              </div>
            </div>
            <div style={{ textAlign: 'right' }}>
              <div className="section-eyebrow">всего углей</div>
              <div className="mono" style={{ fontSize: 22, fontWeight: 700, marginTop: 2, color: totalCarbs > 30 ? 'var(--warn)' : 'var(--acc)' }}>
                {totalCarbs}<span style={{ color: 'var(--muted)', fontSize: 12, fontWeight: 500 }}>г</span>
              </div>
            </div>
          </div>
          <div className="progress-bar">
            <div className="fill" style={{ width: `${(eatenCount / Math.max(1, planned.length)) * 100}%` }} />
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 10, fontSize: 11, color: 'var(--muted)' }}>
            <span>Отмечай съеденное — копи кредиты</span>
            {eatenCount === planned.length && planned.length > 0 && (
              <span style={{ color: 'var(--ok)', fontWeight: 600 }}>✓ День закрыт</span>
            )}
          </div>
        </div>
      </Section>

      <div style={{ height: 16 }} />

      {/* Slot list with checks */}
      <Section>
        <div className="section-eyebrow" style={{ marginBottom: 10, paddingLeft: 4 }}>план</div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {planned.map(s => {
            const d = menu[s];
            const eaten = !!reports[s]?.eaten;
            const rcls = rarityClass(d.carbs_g);
            return (
              <div key={s} className={`slot-card ${rcls}`} style={{ opacity: eaten ? 0.7 : 1 }}>
                <div className="glow" />
                <div className="slot-icon">{SLOT_EMOJI[s]}</div>
                <div className="slot-meta">
                  <div className="slot-eyebrow">
                    <span className="rarity-dot" />
                    {SLOT_LABEL[s]}
                  </div>
                  <div className="slot-name" style={{ textDecoration: eaten ? 'line-through' : 'none', textDecorationColor: 'var(--muted)' }}>
                    {d.name}
                  </div>
                  <div className="slot-carbs mono"><b>{d.carbs_g} г</b> углей</div>
                </div>
                <div className={`report-check ${eaten ? 'on' : ''}`} onClick={() => toggle(s)}>
                  <svg viewBox="0 0 24 24"><path d="M5 12l5 5 9-10" /></svg>
                </div>
              </div>
            );
          })}
        </div>
      </Section>

      <div style={{ height: 18 }} />

      {/* Extras */}
      <Section>
        {!extraOpen ? (
          <button className="danger-cta" onClick={() => setExtraOpen(true)}>
            {Icon.warn}<span>Сорвался — записать перекус</span>
          </button>
        ) : (
          <div className="surface" style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 12 }}>
            <div className="section-eyebrow" style={{ color: 'var(--danger)' }}>Внеплановый перекус</div>
            <div className="input-field">
              <label>Что съел</label>
              <input className="input" placeholder="напр. шоколадка" value={extraName} onChange={e => setExtraName(e.target.value)} />
            </div>
            <div className="input-field">
              <label>Углеводы, г</label>
              <input className="input mono" placeholder="0" inputMode="decimal" value={extraCarbs} onChange={e => setExtraCarbs(e.target.value)} />
            </div>
            <div style={{ display: 'flex', gap: 8 }}>
              <button className="btn btn-ghost" onClick={() => setExtraOpen(false)}>Отмена</button>
              <button className="btn btn-primary" onClick={saveExtra}>Записать</button>
            </div>
          </div>
        )}

        {extras.length > 0 && (
          <>
            <div style={{ height: 16 }} />
            <div className="section-eyebrow" style={{ marginBottom: 10, paddingLeft: 4 }}>Сверх плана</div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              {extras.map((r, i) => (
                <div key={i} className="dish-row" style={{ borderColor: 'rgba(255,84,102,0.20)', background: 'rgba(255,84,102,0.05)' }}>
                  <div style={{ width: 28, height: 28, borderRadius: 8, background: 'rgba(255,84,102,0.12)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 14 }}>🍩</div>
                  <div className="name">{r.extra_name}</div>
                  <span className="mono" style={{ color: 'var(--danger)', fontWeight: 600, fontSize: 13 }}>+{r.extra_carbs}г</span>
                </div>
              ))}
            </div>
          </>
        )}
      </Section>
    </div>
  );
}

// ─── MENU EDITOR ───────────────────────────────────────────────────
function MenuEditor({ onBack, library, setLibrary }) {
  const [slot, setSlot] = useState(SLOTS[0]);
  const [name, setName] = useState("");
  const [carbs, setCarbs] = useState("");

  function add() {
    if (!name.trim()) return;
    const c = parseFloat(carbs);
    if (isNaN(c) || c < 0) return;
    setLibrary(prev => ({
      ...prev,
      [slot]: [...(prev[slot] || []), { id: Date.now(), name: name.trim(), carbs_g: c }],
    }));
    setName(""); setCarbs("");
  }
  function del(id) {
    setLibrary(prev => ({
      ...prev,
      [slot]: prev[slot].filter(d => d.id !== id),
    }));
  }

  const list = library[slot] || [];
  const totalDishes = Object.values(library).reduce((sum, arr) => sum + arr.length, 0);

  return (
    <div className="tg-app has-appbar">
      <AppBar
        title="Меню"
        onBack={onBack}
        right={<span className="chip mono" style={{ fontSize: 12 }}>{totalDishes} блюд</span>}
      />

      <Section>
        <div className="tabs">
          {SLOTS.map(s => (
            <button
              key={s}
              className={`tab ${s === slot ? "active" : ""}`}
              onClick={() => setSlot(s)}
            >
              <span>{SLOT_EMOJI[s]}</span>
              <span>{SLOT_LABEL[s]}</span>
              {library[s]?.length > 0 && <span className="count mono">{library[s].length}</span>}
            </button>
          ))}
        </div>
      </Section>

      <div style={{ height: 12 }} />

      <Section>
        <div className="surface" style={{ padding: 14, display: 'flex', flexDirection: 'column', gap: 12 }}>
          <div className="section-eyebrow">Добавить в «{SLOT_LABEL[slot]}»</div>
          <div className="input-field">
            <label>Название</label>
            <input className="input" placeholder="напр. салат Цезарь с курицей" value={name} onChange={e => setName(e.target.value)} />
          </div>
          <div className="input-field">
            <label>Углеводы, г</label>
            <div style={{ position: 'relative' }}>
              <input className="input mono" placeholder="0" inputMode="decimal" type="number" value={carbs} onChange={e => setCarbs(e.target.value)} />
              {carbs !== "" && !isNaN(parseFloat(carbs)) && (
                <div className={`mono ${rarityClass(parseFloat(carbs))}`} style={{
                  position: 'absolute', right: 12, top: '50%', transform: 'translateY(-50%)',
                  fontSize: 11, fontWeight: 600, padding: '3px 8px', borderRadius: 6,
                  background: 'var(--rarity-soft)', color: 'var(--rarity-color)',
                  border: '1px solid var(--rarity-color)',
                  textTransform: 'uppercase', letterSpacing: '0.06em',
                  pointerEvents: 'none',
                }}>
                  {RARITY_NAME[rarityOf(parseFloat(carbs))]}
                </div>
              )}
            </div>
          </div>
          <button className="btn btn-primary" onClick={add} disabled={!name.trim() || !carbs}>
            {Icon.plus}<span style={{ marginLeft: 4 }}>Добавить блюдо</span>
          </button>
        </div>
      </Section>

      <div style={{ height: 18 }} />

      <Section>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10, paddingLeft: 4 }}>
          <div className="section-eyebrow">В библиотеке</div>
          <div className="section-eyebrow mono">{list.length}</div>
        </div>
        {list.length === 0 ? (
          <div className="empty">
            <div className="icon">{SLOT_EMOJI[slot]}</div>
            <div>Пока пусто.<br/>Добавь первое блюдо.</div>
          </div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            {list.map(d => (
              <div key={d.id} className={`dish-row ${rarityClass(d.carbs_g)}`}>
                <div className="name">{d.name}</div>
                <span className="carbs-chip mono">{d.carbs_g} г</span>
                <button className="delete" onClick={() => del(d.id)}>{Icon.trash}</button>
              </div>
            ))}
          </div>
        )}
      </Section>
    </div>
  );
}

// ─── WEEK STATS ────────────────────────────────────────────────────
function WeekStats({ onBack, state }) {
  const { credits, streak } = state;
  // mocked week data
  const days = [
    { d: 'Пн', carbs: 8,  clean: true },
    { d: 'Вт', carbs: 12, clean: true },
    { d: 'Ср', carbs: 32, clean: false },
    { d: 'Чт', carbs: 9,  clean: true },
    { d: 'Пт', carbs: 6,  clean: true },
    { d: 'Сб', carbs: 14, clean: true },
    { d: 'Вс', carbs: 5,  clean: true, today: true },
  ];
  const maxCarb = 40;
  const avg = (days.reduce((s, d) => s + d.carbs, 0) / days.length).toFixed(1);
  const cleanCount = days.filter(d => d.clean).length;

  return (
    <div className="tg-app has-appbar">
      <AppBar
        title="Неделя"
        onBack={onBack}
        right={<CreditChip value={credits} />}
      />

      {/* Top stat tiles */}
      <Section>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
          <div className="stat-tile">
            <div className="label">Средне углей/день</div>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 4 }}>
              <span className="value">{avg}</span>
              <span className="unit">г</span>
            </div>
            <div className="delta">↓ −2.4г к прошлой</div>
          </div>
          <div className="stat-tile">
            <div className="label">Чистых дней</div>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 4 }}>
              <span className="value">{cleanCount}</span>
              <span className="unit">/ 7</span>
            </div>
            <div className="delta">86% выполнение</div>
          </div>
          <div className="stat-tile" style={{ gridColumn: 'span 2', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' }}>
            <div>
              <div className="label">Текущий стрик</div>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 6, marginTop: 6 }}>
                <span style={{ color: '#ffb480', fontSize: 22 }}>🔥</span>
                <span className="value" style={{ fontSize: 32 }}>{streak}</span>
                <span className="unit">дней подряд</span>
              </div>
            </div>
            <div style={{ display: 'flex', gap: 3 }}>
              {[1,2,3,4,5,6,7].map(i => (
                <div key={i} style={{
                  width: 8, height: 24, borderRadius: 3,
                  background: i <= streak ? '#ffb480' : 'var(--surface-3)',
                  opacity: i <= streak ? 1 - (streak - i) * 0.1 : 1,
                }}/>
              ))}
            </div>
          </div>
        </div>
      </Section>

      <div style={{ height: 16 }} />

      {/* Day bar chart */}
      <Section>
        <div className="surface" style={{ padding: 18 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 14 }}>
            <div className="section-eyebrow">углеводы по дням</div>
            <div className="mono" style={{ fontSize: 11, color: 'var(--muted)' }}>лимит 30г</div>
          </div>
          <div className="daybar">
            {days.map((day, i) => {
              const rcls = rarityClass(day.carbs);
              const heightPct = (day.carbs / maxCarb) * 100;
              return (
                <div key={i} className={`col ${rcls}`}>
                  <div style={{ flex: 1, width: '100%', display: 'flex', justifyContent: 'center', alignItems: 'flex-end' }}>
                    <div className="bar" style={{ height: '100%' }}>
                      <div className="fill" style={{ height: `${heightPct}%`, background: 'var(--rarity-color)', opacity: 0.85 }} />
                    </div>
                  </div>
                  <div className="day" style={{ color: day.today ? 'var(--acc)' : 'var(--muted)' }}>
                    {day.d}
                  </div>
                </div>
              );
            })}
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 12, fontSize: 11, color: 'var(--muted)' }}>
            <span style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
              <span className="r-legend" style={{ width: 8, height: 8, borderRadius: 2, background: 'var(--rarity-color)' }}/>0–5г
            </span>
            <span style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
              <span className="r-epic" style={{ width: 8, height: 8, borderRadius: 2, background: 'var(--rarity-color)' }}/>6–10г
            </span>
            <span style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
              <span className="r-rare" style={{ width: 8, height: 8, borderRadius: 2, background: 'var(--rarity-color)' }}/>11–18г
            </span>
            <span style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
              <span className="r-common" style={{ width: 8, height: 8, borderRadius: 2, background: 'var(--rarity-color)' }}/>19+г
            </span>
          </div>
        </div>
      </Section>

      <div style={{ height: 16 }} />

      {/* Advice */}
      <Section>
        <div className="surface" style={{ padding: 18, borderColor: 'rgba(200,255,46,0.20)', background: 'linear-gradient(180deg, rgba(200,255,46,0.05), rgba(200,255,46,0.01))' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 8 }}>
            <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--acc)', boxShadow: '0 0 8px var(--acc-glow)' }} />
            <div className="section-eyebrow" style={{ color: 'var(--acc)' }}>Совет на неделю</div>
          </div>
          <div style={{ fontSize: 15, lineHeight: 1.5 }}>
            Среда выбилась из ритма — 32г углей. Попробуй заранее назначить ужин на «трудные» дни,
            чтобы не сваливаться в перекус. Пятница и воскресенье — образцовые,
            держи там же.
          </div>
        </div>
      </Section>
    </div>
  );
}

// ─── ROOT APP ──────────────────────────────────────────────────────
function FoodRouletteApp() {
  const [screen, setScreen] = useState("home");
  const [library, setLibrary] = useState(INITIAL_LIBRARY);
  const [state, setState] = useState({
    credits: 7,
    streak: 4,
    menu: INITIAL_MENU,
    reports: {
      breakfast: { eaten: true },
      lunch: { eaten: true },
    },
  });

  const reportsCount = SLOTS.filter(s => state.reports[s]?.eaten).length;
  const homeState = { ...state, reportsCount };

  if (screen === "case")   return <CaseOpen onBack={() => setScreen("home")} state={state} setState={setState} />;
  if (screen === "report") return <Report   onBack={() => setScreen("home")} state={state} setState={setState} />;
  if (screen === "menu")   return <MenuEditor onBack={() => setScreen("home")} library={library} setLibrary={setLibrary} />;
  if (screen === "stats")  return <WeekStats onBack={() => setScreen("home")} state={state} />;

  return <Home go={setScreen} state={homeState} />;
}

window.FoodRouletteApp = FoodRouletteApp;
