import React, { useState, useEffect, useMemo, useCallback, useRef } from "https://esm.sh/react@18.2.0";
import { createRoot } from "https://esm.sh/react-dom@18.2.0/client";
import {
  Dumbbell,
  Utensils,
  Scale,
  Check,
  Plus,
  ChevronLeft,
  Award,
  X,
  ArrowLeftRight,
  Flame,
  TrendingDown,
  TrendingUp,
  Minus,
  Camera,
  Sparkles,
  BookOpen,
  AlertTriangle,
  Loader2,
  Trash2,
  ShoppingCart,
  LogOut,
} from "https://esm.sh/lucide-react@0.383.0?deps=react@18.2.0";
import {
  ResponsiveContainer,
  LineChart,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
} from "https://esm.sh/recharts@2.12.7?deps=react@18.2.0,react-dom@18.2.0";

/* ------------------------------------------------------------------ */
/* נתוני תוכנית האימונים - קליסטניקס לפי שלבים                        */
/* ------------------------------------------------------------------ */

const LEVELS = [
  {
    id: 1,
    name: "יסודות",
    subtitle: "בונים בסיס",
    sessionsToAdvance: 12,
    workouts: [
      {
        id: "1a",
        name: "אימון A",
        exercises: [
          { name: "שכיבות סמיכה משופעות / על הברכיים", target: "3x8-12" },
          { name: "חתירה אוסטרלית (שולחן / TRX)", target: "3x8-12" },
          { name: "סקוואט משקל גוף", target: "3x12-15" },
          { name: "פלאנק", target: "3x20-30 שנ׳" },
        ],
      },
      {
        id: "1b",
        name: "אימון B",
        exercises: [
          { name: "שכיבות סמיכה משופעות / על הברכיים", target: "3x8-12" },
          { name: "חתירה אוסטרלית (שולחן / TRX)", target: "3x8-12" },
          { name: "לאנג׳ סטטי", target: "3x10 לרגל" },
          { name: "דד באג", target: "3x10 לצד" },
        ],
      },
    ],
  },
  {
    id: 2,
    name: "התקדמות",
    subtitle: "בונים כוח בסיסי",
    sessionsToAdvance: 12,
    workouts: [
      {
        id: "2a",
        name: "אימון A",
        exercises: [
          { name: "שכיבות סמיכה רגילות", target: "3x8-12" },
          { name: "חתירה בגומייה / טבעות", target: "3x8-10" },
          { name: "לאנג׳ הליכה", target: "3x12 צעדים" },
          { name: "הרמות ברכיים תלויות", target: "3x10" },
        ],
      },
      {
        id: "2b",
        name: "אימון B",
        exercises: [
          { name: "שכיבות סמיכה פייק", target: "3x6-10" },
          { name: "נגטיב פול-אפ (ירידה מבוקרת)", target: "3x3-5" },
          { name: "סקוואט בולגרי", target: "3x8 לרגל" },
          { name: "פלאנק צידי", target: "3x20 שנ׳ לצד" },
        ],
      },
    ],
  },
  {
    id: 3,
    name: "כוח",
    subtitle: "תרגילים מלאים",
    sessionsToAdvance: 16,
    workouts: [
      {
        id: "3a",
        name: "אימון A",
        exercises: [
          { name: "שכיבות סמיכה יהלום", target: "3x6-10" },
          { name: "מתח אחיזה תחתונה (צ׳ין-אפ)", target: "3x5-8" },
          { name: "פיסטול סקוואט (עם תמיכה)", target: "3x5 לרגל" },
          { name: "L-sit (תלוי / על מקבילים)", target: "3x10-15 שנ׳" },
        ],
      },
      {
        id: "3b",
        name: "אימון B",
        exercises: [
          { name: "מקבילים (דיפס)", target: "3x6-10" },
          { name: "מתח אחיזה עליונה (פול-אפ)", target: "3x5-8" },
          { name: "קפיצות סקוואט", target: "3x10" },
          { name: "הולו בודי הולד", target: "3x20-30 שנ׳" },
        ],
      },
    ],
  },
  {
    id: 4,
    name: "עילית",
    subtitle: "אלמנטים מתקדמים",
    sessionsToAdvance: 999,
    workouts: [
      {
        id: "4a",
        name: "אימון A",
        exercises: [
          { name: "שכיבות עמידת ידיים (עם קיר)", target: "3x3-6" },
          { name: "עלייה לשרירים (Muscle-up)", target: "3x2-5" },
          { name: "פיסטול סקוואט מלא", target: "3x5 לרגל" },
          { name: "פרונט לוור (Tuck)", target: "3x10-15 שנ׳" },
        ],
      },
      {
        id: "4b",
        name: "אימון B",
        exercises: [
          { name: "דיפס בטמפו איטי", target: "3x6-10" },
          { name: "מתח עם עומס נוסף", target: "3x4-6" },
          { name: "קפיצות פיסטול", target: "3x6 לרגל" },
          { name: "דגל אנושי (פרוגרסיה)", target: "3x5-10 שנ׳ לצד" },
        ],
      },
    ],
  },
];

/* סוגי אימונים נוספים - לא לפי שלבים, בחירה חופשית */
const CATEGORY_WORKOUTS = {
  cardio: [
    {
      id: "cardio1",
      name: "HIIT מהיר · 12 דק׳",
      exercises: [
        { name: "ברפיז", target: "3x10" },
        { name: "ריצה במקום בקצב גבוה", target: "3x30 שנ׳" },
        { name: "קפיצות פתיחה (Star Jump)", target: "3x20" },
        { name: "הר-קליימברס", target: "3x20" },
      ],
    },
    {
      id: "cardio2",
      name: "קרדיו סירקיט",
      exercises: [
        { name: "קפיצות חבל (או דמה)", target: "3x40 שנ׳" },
        { name: "סקוואט קפיצה", target: "3x15" },
        { name: "מאונטיין קליימברס", target: "3x20" },
        { name: "ברפיז", target: "3x8" },
      ],
    },
  ],
  mobility: [
    {
      id: "mob1",
      name: "מוביליות בוקר",
      exercises: [
        { name: "מעגלי כתפיים", target: "2x10" },
        { name: "מתיחת מפשעה", target: "2x30 שנ׳ לצד" },
        { name: "פתיחת ירך (90/90)", target: "2x30 שנ׳ לצד" },
        { name: "חתול-פרה", target: "2x10" },
      ],
    },
    {
      id: "mob2",
      name: "שחרור אחרי אימון",
      exercises: [
        { name: "מתיחת האמסטרינג", target: "2x30 שנ׳ לרגל" },
        { name: "מתיחת חזה בפתח דלת", target: "2x30 שנ׳" },
        { name: "מתיחת גב עליון", target: "2x30 שנ׳" },
        { name: "נשימות עמוקות", target: "2 דק׳" },
      ],
    },
  ],
  core: [
    {
      id: "core1",
      name: "ליבה קלאסית",
      exercises: [
        { name: "כפיפות בטן", target: "3x15" },
        { name: "פלאנק", target: "3x30 שנ׳" },
        { name: "הרמות רגליים שכיבה", target: "3x12" },
        { name: "רוסיאן טוויסט", target: "3x20" },
      ],
    },
    {
      id: "core2",
      name: "ליבה מתקדמת",
      exercises: [
        { name: "הולו בודי הולד", target: "3x20 שנ׳" },
        { name: "V-ups", target: "3x12" },
        { name: "פלאנק עם נגיעת כתף", target: "3x20" },
        { name: "דד באג", target: "3x10 לצד" },
      ],
    },
  ],
  gym: [
    {
      id: "gym1",
      name: "יום כוח · חדר כושר",
      exercises: [
        { name: "סקוואט עם מוט", target: "3x6-8" },
        { name: "דדליפט רומני", target: "3x8" },
        { name: "לחיצת חזה בשכיבה", target: "3x8" },
        { name: "חתירה בכבל בישיבה", target: "3x10" },
        { name: "כפיפת מרפק עם מוט EZ", target: "2x10" },
      ],
    },
    {
      id: "gym2",
      name: "יום עומס כבד · חדר כושר",
      exercises: [
        { name: "דדליפט קלאסי", target: "3x5" },
        { name: "לג פרס (Leg Press)", target: "3x10" },
        { name: "לחיצת כתפיים בישיבה", target: "3x8" },
        { name: "פולי עליון / פול-דאון", target: "3x10" },
        { name: "אחיזת חוזק (Farmer Carry)", target: "3x20 מ׳" },
      ],
    },
  ],
};

const TRAINING_CATEGORIES = [
  { id: "calisthenics", label: "קליסטניקס" },
  { id: "gym", label: "חדר כושר" },
  { id: "cardio", label: "קרדיו / HIIT" },
  { id: "mobility", label: "גמישות ומוביליות" },
  { id: "core", label: "ליבה ובטן" },
];

/* ------------------------------------------------------------------ */
/* נתוני תזונה - עקרונות קיטו / פליאו                                 */
/* ------------------------------------------------------------------ */

const DIETS = {
  keto: {
    label: "קיטו",
    color: "var(--ember)",
    principles: [
      "הימנעתי מסוכר וממתוקים",
      "הימנעתי מדגנים וקמח (לחם, אורז, פסטה)",
      "הימנעתי מקטניות",
      "אכלתי שומן איכותי בכל ארוחה",
      "הפחמימות שלי היו בעיקר מירקות עליים",
      "שתיתי מספיק מים ומלחים",
    ],
  },
  paleo: {
    label: "פליאו",
    color: "var(--sage)",
    principles: [
      "אכלתי מזון מלא ולא מעובד",
      "הימנעתי מדגנים",
      "הימנעתי מקטניות",
      "הימנעתי ממוצרי חלב",
      "הימנעתי מסוכר מעובד וממתוקים",
      "כללתי חלבון, ירקות ושומנים טבעיים",
    ],
  },
};

const TRANSITION_TEXT =
  "במעבר מקיטו לפליאו אפשר להוסיף בהדרגה פירות טריים, ירקות עמילניים כמו בטטה ודלעת, ודבש טבעי במידה. נשארים בלי דגנים, קטניות, סוכר מעובד ומוצרי חלב.";

const FOOD_GUIDE = {
  keto: {
    allowed: [
      "בשר, עוף, ביצים ודגים",
      "גבינות שומניות וחמאה",
      "שמן זית, שמן קוקוס ואבוקדו",
      "ירקות עליים ולא עמילניים (חסה, תרד, ברוקולי, כרובית, קישוא)",
      "אגוזים וזרעים במידה",
    ],
    avoid: [
      "סוכר וממתקים",
      "דגנים ומוצריהם (לחם, אורז, פסטה, קמח)",
      "קטניות",
      "תפוחי אדמה ועמילנים",
      "פירות מתוקים (מלבד פירות יער במידה)",
    ],
  },
  paleo: {
    allowed: [
      "בשר, עוף ודגים",
      "ביצים",
      "ירקות ופירות טריים",
      "אגוזים וזרעים",
      "שמנים טבעיים (זית, קוקוס)",
    ],
    avoid: [
      "דגנים",
      "קטניות",
      "מוצרי חלב",
      "סוכר מעובד וממתקים",
      "מזון מעובד ותעשייתי",
    ],
  },
};

/* ------------------------------------------------------------------ */
/* מתכוני קיטו - ללא חזיר וללא פירות ים                                */
/* ------------------------------------------------------------------ */

const RECIPES = [
  {
    id: "r1",
    title: "אומלט גבינות ותרד",
    diet: "keto",
    time: "10 דק׳",
    ingredients: ["3 ביצים", "תרד טרי", "גבינה צהובה מגוררת", "שמן זית", "מלח ופלפל"],
    steps: [
      "מטגנים תרד קלות בשמן זית עד שנובל",
      "טורפים ביצים עם מלח ופלפל ומוסיפים למחבת",
      "מפזרים גבינה, מקפלים ומגישים",
    ],
  },
  {
    id: "r2",
    title: "עוף בחמאת שום ולימון",
    diet: "keto",
    time: "25 דק׳",
    ingredients: ["חזה עוף", "חמאה", "3 שיני שום כתושות", "לימון סחוט", "פטרוזיליה"],
    steps: [
      "צולים את חזה העוף במחבת חמה עם קצת שמן עד להשחמה",
      "מוסיפים חמאה ושום ומטגנים דקה על אש נמוכה",
      "מוסיפים לימון ופטרוזיליה ומגישים",
    ],
  },
  {
    id: "r3",
    title: "סלט עוף קיסר ללא קרוטונים",
    diet: "keto",
    time: "15 דק׳",
    ingredients: ["חסה", "חזה עוף צלוי פרוס", "פרמזן מגורר", "מיונז", "לימון", "שום כתוש"],
    steps: [
      "מערבבים מיונז, לימון ושום לרוטב",
      "קורעים חסה לקערה ומוסיפים עוף פרוס",
      "מוסיפים רוטב ופרמזן ומערבבים",
    ],
  },
  {
    id: "r4",
    title: "קציצות בקר עם אבוקדו",
    diet: "keto",
    time: "20 דק׳",
    ingredients: ["בקר טחון", "ביצה", "שום כתוש", "מלח ופלפל", "אבוקדו פרוס"],
    steps: [
      "מערבבים בקר טחון עם ביצה, שום, מלח ופלפל",
      "מעצבים קציצות ומטגנים במחבת עד להשחמה משני הצדדים",
      "מגישים עם פלחי אבוקדו",
    ],
  },
  {
    id: "r5",
    title: "פטריות ממולאות גבינת שמנת",
    diet: "keto",
    time: "20 דק׳",
    ingredients: ["פטריות גדולות", "גבינת שמנת", "שום כתוש", "פטרוזיליה קצוצה"],
    steps: [
      "מוציאים את הרגל מהפטריות ומערבבים אותה קצוצה עם הגבינה והשום",
      "ממלאים את הפטריות בתערובת",
      "אופים 15 דקות ב-200 מעלות עד להזהבה",
    ],
  },
  {
    id: "r6",
    title: "מרק כרובית קרם",
    diet: "keto",
    time: "30 דק׳",
    ingredients: ["כרובית", "שמנת מתוקה", "חמאה", "שום", "מרק עוף (ציר)"],
    steps: [
      "מבשלים כרובית בציר עד שמתרככת",
      "טוחנים בבלנדר עם שום מוקפץ בחמאה",
      "מוסיפים שמנת ומחממים בלי לבשל",
    ],
  },
  {
    id: "r7",
    title: "קבב עוף על שיפודים",
    diet: "keto",
    time: "25 דק׳",
    ingredients: ["עוף טחון", "בצל מגורר", "כמון", "פטרוזיליה קצוצה", "מלח ופלפל"],
    steps: [
      "מערבבים את כל המרכיבים היטב",
      "מעצבים על שיפודים או ככדורים",
      "צולים על גריל או במחבת עד להשחמה",
    ],
  },
  {
    id: "r8",
    title: "סלט אבוקדו, ביצה וגבינה בולגרית",
    diet: "keto",
    time: "10 דק׳",
    ingredients: ["אבוקדו", "ביצים קשות", "גבינה בולגרית מפוררת", "שמן זית", "לימון"],
    steps: [
      "קוצצים אבוקדו וביצים קשות לקוביות",
      "מוסיפים גבינה בולגרית מפוררת",
      "מתבלים בשמן זית, לימון, מלח ופלפל",
    ],
  },
  {
    id: "r9",
    title: "סלמון אפוי עם ירקות שורש",
    diet: "paleo",
    time: "30 דק׳",
    ingredients: ["פילה סלמון", "בטטה קוביות", "גזר", "שמן זית", "עשבי תיבול"],
    steps: [
      "מניחים ירקות שורש בתבנית עם שמן זית ואופים 15 דקות ב-200 מעלות",
      "מוסיפים את הסלמון לתבנית וממשיכים לאפות 12-15 דקות נוספות",
      "מפזרים עשבי תיבול טריים לפני ההגשה",
    ],
  },
  {
    id: "r10",
    title: "סלט עוף עם פירות יער ואגוזי מלך",
    diet: "paleo",
    time: "15 דק׳",
    ingredients: ["חזה עוף צלוי", "עלים ירוקים", "פירות יער טריים", "אגוזי מלך", "שמן זית ובלסמי"],
    steps: [
      "פורסים את חזה העוף הצלוי לרצועות",
      "מניחים על מצע עלים ירוקים",
      "מפזרים פירות יער ואגוזי מלך ומתבלים בשמן זית ובלסמי",
    ],
  },
];

/* ------------------------------------------------------------------ */
/* עזרים                                                              */
/* ------------------------------------------------------------------ */

const todayStr = () => new Date().toISOString().slice(0, 10);

const formatHe = (iso) =>
  new Date(iso + "T00:00:00").toLocaleDateString("he-IL", {
    day: "numeric",
    month: "short",
  });

const STORAGE_KEY = "cnapp-data-v2";

const DEFAULT_DATA = {
  profile: {
    levelId: 1,
    dietMode: "keto",
    goalWeight: null,
    transitions: [],
    createdAt: todayStr(),
    ketoStartDate: todayStr(),
  },
  trainingLog: [],
  nutritionLog: {},
  weightLog: [],
  mealLog: [],
  shoppingList: [],
  ketoLog: [],
};

function resizeImageToBase64(file, maxDim = 900) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onerror = () => reject(new Error("read failed"));
    reader.onload = () => {
      const img = new window.Image();
      img.onerror = () => reject(new Error("image load failed"));
      img.onload = () => {
        let { width, height } = img;
        if (width > height && width > maxDim) {
          height = Math.round(height * (maxDim / width));
          width = maxDim;
        } else if (height > maxDim) {
          width = Math.round(width * (maxDim / height));
          height = maxDim;
        }
        const canvas = document.createElement("canvas");
        canvas.width = width;
        canvas.height = height;
        const ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0, width, height);
        const dataUrl = canvas.toDataURL("image/jpeg", 0.82);
        resolve(dataUrl.split(",")[1]);
      };
      img.src = reader.result;
    };
    reader.readAsDataURL(file);
  });
}

async function analyzeMealImage(base64) {
  const response = await fetch("/api/analyze-meal", {
    method: "POST",
    credentials: "include",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ imageBase64: base64 }),
  });
  if (!response.ok) {
    const err = await response.json().catch(() => ({}));
    throw new Error(err.error || "analyze failed");
  }
  return response.json();
}

async function apiGetData() {
  const res = await fetch("/api/data", { credentials: "include" });
  if (!res.ok) throw new Error("no data");
  return res.json();
}

async function apiSetData(payload) {
  const res = await fetch("/api/data", {
    method: "POST",
    credentials: "include",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(payload),
  });
  return res.ok;
}

/* ------------------------------------------------------------------ */
/* אפליקציה ראשית                                                     */
/* ------------------------------------------------------------------ */

function App({ onLogout }) {
  const [data, setData] = useState(null);
  const [tab, setTab] = useState("training");
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    (async () => {
      try {
        const parsed = await apiGetData();
        setData({
          ...DEFAULT_DATA,
          ...parsed,
          profile: { ...DEFAULT_DATA.profile, ...(parsed.profile || {}) },
          mealLog: parsed.mealLog || [],
          shoppingList: parsed.shoppingList || [],
          ketoLog: parsed.ketoLog || [],
        });
      } catch {
        setData(DEFAULT_DATA);
      }
    })();
  }, []);

  const persist = useCallback(async (next) => {
    setData(next);
    setSaving(true);
    try {
      await apiSetData(next);
    } catch {
      /* ignore transient storage errors */
    } finally {
      setSaving(false);
    }
  }, []);

  if (!data) {
    return (
      <div className="app-shell center-loader">
        <FontStyle />
        <div className="loader-dot" />
      </div>
    );
  }

  return (
    <div className="app-shell" dir="rtl">
      <FontStyle />
      <header className="app-header">
        <div>
          <div className="app-title">שגרה</div>
          <div className="app-subtitle">
            {saving ? "שומר..." : "כושר · תזונה · משקל"}
          </div>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
          <StreakChip data={data} />
          <button className="icon-btn" onClick={onLogout} title="התנתק">
            <LogOut size={16} />
          </button>
        </div>
      </header>

      <main className="app-main">
        {tab === "training" && <TrainingTab data={data} persist={persist} />}
        {tab === "nutrition" && <NutritionTab data={data} persist={persist} />}
        {tab === "weight" && <WeightTab data={data} persist={persist} />}
      </main>

      <nav className="bottom-nav">
        <NavButton
          active={tab === "training"}
          onClick={() => setTab("training")}
          icon={<Dumbbell size={22} />}
          label="אימונים"
        />
        <NavButton
          active={tab === "nutrition"}
          onClick={() => setTab("nutrition")}
          icon={<Utensils size={22} />}
          label="תזונה"
        />
        <NavButton
          active={tab === "weight"}
          onClick={() => setTab("weight")}
          icon={<Scale size={22} />}
          label="משקל"
        />
      </nav>
    </div>
  );
}

function NavButton({ active, onClick, icon, label }) {
  return (
    <button
      onClick={onClick}
      className="nav-btn"
      style={{ color: active ? "var(--text)" : "var(--text-dim)" }}
    >
      <div
        className="nav-icon-wrap"
        style={{ background: active ? "var(--surface-2)" : "transparent" }}
      >
        {icon}
      </div>
      <span style={{ fontSize: 11, fontWeight: active ? 700 : 500 }}>{label}</span>
    </button>
  );
}

function StreakChip({ data }) {
  const streak = useMemo(() => computeStreak(data.nutritionLog), [data.nutritionLog]);
  if (streak < 1) return null;
  return (
    <div className="streak-chip">
      <Flame size={14} color="var(--gold)" />
      <span>{streak}</span>
    </div>
  );
}

/* ------------------------------------------------------------------ */
/* לשונית אימונים                                                     */
/* ------------------------------------------------------------------ */

function TrainingTab({ data, persist }) {
  const [category, setCategory] = useState("calisthenics");
  const [activeWorkout, setActiveWorkout] = useState(null);
  const [checkedIdx, setCheckedIdx] = useState([]);

  const level = LEVELS.find((l) => l.id === data.profile.levelId) || LEVELS[0];
  const calSessions = data.trainingLog.filter(
    (s) => (s.category || "calisthenics") === "calisthenics" && s.levelId === level.id
  ).length;
  const progressPct = Math.min(100, Math.round((calSessions / level.sessionsToAdvance) * 100));
  const canAdvance =
    calSessions >= level.sessionsToAdvance && level.id < LEVELS[LEVELS.length - 1].id;

  const recentSessions = [...data.trainingLog].slice(-5).reverse();

  const workoutsToShow =
    category === "calisthenics" ? level.workouts : CATEGORY_WORKOUTS[category];

  function openWorkout(w) {
    setActiveWorkout(w);
    setCheckedIdx([]);
  }

  function toggleExercise(i) {
    setCheckedIdx((prev) => (prev.includes(i) ? prev.filter((x) => x !== i) : [...prev, i]));
  }

  async function completeWorkout() {
    const entry = {
      date: todayStr(),
      category,
      levelId: category === "calisthenics" ? level.id : null,
      workoutId: activeWorkout.id,
      workoutName: activeWorkout.name,
      exercisesDone: checkedIdx.length,
      exercisesTotal: activeWorkout.exercises.length,
    };
    await persist({ ...data, trainingLog: [...data.trainingLog, entry] });
    setActiveWorkout(null);
  }

  async function advanceLevel() {
    await persist({ ...data, profile: { ...data.profile, levelId: level.id + 1 } });
  }

  return (
    <div className="tab-pad">
      <div className="chip-row">
        {TRAINING_CATEGORIES.map((c) => (
          <button
            key={c.id}
            className={"chip" + (category === c.id ? " active" : "")}
            onClick={() => setCategory(c.id)}
          >
            {c.label}
          </button>
        ))}
      </div>

      {category === "calisthenics" && (
        <>
          <div style={{ marginTop: 14 }}>
            <LevelMedallion level={level} progressPct={progressPct} />
          </div>
          {canAdvance && (
            <div className="banner banner-ember">
              <Award size={18} />
              <div style={{ flex: 1 }}>
                <div className="banner-title">מוכן/ה לשלב הבא</div>
                <div className="banner-sub">השלמת {calSessions} אימונים ב{level.name}</div>
              </div>
              <button className="pill-btn" onClick={advanceLevel}>
                עבור לשלב {level.id + 1}
              </button>
            </div>
          )}
        </>
      )}

      <div className="section-label">
        {category === "calisthenics" ? "אימון היום" : "בחר אימון"}
      </div>
      <div className="workout-grid">
        {workoutsToShow.map((w) => (
          <button key={w.id} className="workout-card" onClick={() => openWorkout(w)}>
            <div className="workout-card-name">{w.name}</div>
            <div className="workout-card-count">{w.exercises.length} תרגילים</div>
            <div className="workout-card-cta">
              התחל <ChevronLeft size={16} />
            </div>
          </button>
        ))}
      </div>

      <div className="section-label">היסטוריה אחרונה</div>
      {recentSessions.length === 0 ? (
        <div className="empty-hint">עוד לא נרשמו אימונים. בואו נתחיל.</div>
      ) : (
        <div className="history-list">
          {recentSessions.map((s, i) => (
            <div key={i} className="history-row">
              <div className="history-dot" />
              <div style={{ flex: 1 }}>
                <div className="history-name">{s.workoutName}</div>
                <div className="history-date">
                  {formatHe(s.date)}
                  {s.category && s.category !== "calisthenics"
                    ? " · " + (TRAINING_CATEGORIES.find((c) => c.id === s.category) || {}).label
                    : ""}
                </div>
              </div>
              <div className="history-count">
                {s.exercisesDone}/{s.exercisesTotal}
              </div>
            </div>
          ))}
        </div>
      )}

      {activeWorkout && (
        <div className="modal-overlay" onClick={() => setActiveWorkout(null)}>
          <div className="modal-sheet" onClick={(e) => e.stopPropagation()}>
            <div className="modal-header">
              <div className="modal-title">{activeWorkout.name}</div>
              <button className="icon-btn" onClick={() => setActiveWorkout(null)}>
                <X size={20} />
              </button>
            </div>
            <div className="exercise-list">
              {activeWorkout.exercises.map((ex, i) => (
                <button key={i} className="exercise-row" onClick={() => toggleExercise(i)}>
                  <div
                    className="checkbox"
                    style={{
                      background: checkedIdx.includes(i) ? "var(--ember)" : "transparent",
                      borderColor: checkedIdx.includes(i) ? "var(--ember)" : "var(--border)",
                    }}
                  >
                    {checkedIdx.includes(i) && <Check size={14} color="#16171A" strokeWidth={3} />}
                  </div>
                  <div style={{ flex: 1, textAlign: "right" }}>
                    <div className="exercise-name">{ex.name}</div>
                    <div className="exercise-target">{ex.target}</div>
                  </div>
                </button>
              ))}
            </div>
            <button className="primary-btn" onClick={completeWorkout}>
              סיימתי אימון ({checkedIdx.length}/{activeWorkout.exercises.length})
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

function LevelMedallion({ level, progressPct }) {
  const segments = 24;
  const filled = Math.round((progressPct / 100) * segments);
  const radius = 52;
  const cx = 60;
  const cy = 60;

  const ticks = Array.from({ length: segments }).map((_, i) => {
    const angle = (i / segments) * Math.PI * 2 - Math.PI / 2;
    const x1 = cx + Math.cos(angle) * (radius - 6);
    const y1 = cy + Math.sin(angle) * (radius - 6);
    const x2 = cx + Math.cos(angle) * radius;
    const y2 = cy + Math.sin(angle) * radius;
    return (
      <line
        key={i}
        x1={x1}
        y1={y1}
        x2={x2}
        y2={y2}
        stroke={i < filled ? "var(--gold)" : "var(--border)"}
        strokeWidth={i < filled ? 3 : 2}
        strokeLinecap="round"
      />
    );
  });

  return (
    <div className="medallion-card">
      <svg width="120" height="120" viewBox="0 0 120 120">
        {ticks}
        <circle cx={cx} cy={cy} r={radius - 14} fill="var(--surface-2)" />
      </svg>
      <svg width="120" height="120" viewBox="0 0 120 120" style={{ position: "absolute", top: 0, left: 0 }}>
        <text
          x="60"
          y="66"
          textAnchor="middle"
          fontFamily="'Roboto Mono', monospace"
          fontSize="30"
          fontWeight="700"
          fill="var(--text)"
        >
          {level.id}
        </text>
      </svg>
      <div style={{ marginRight: 16 }}>
        <div className="medallion-level">שלב {level.id} · {level.name}</div>
        <div className="medallion-sub">{level.subtitle}</div>
        <div className="medallion-pct">{progressPct}% לשלב הבא</div>
      </div>
    </div>
  );
}

/* ------------------------------------------------------------------ */
/* לשונית תזונה                                                       */
/* ------------------------------------------------------------------ */

function computeStreak(nutritionLog) {
  let streak = 0;
  let d = new Date();
  for (;;) {
    const key = d.toISOString().slice(0, 10);
    const entry = nutritionLog[key];
    if (!entry) break;
    const doneCount = entry.checks.filter(Boolean).length;
    if (doneCount < entry.checks.length - 1) break;
    streak += 1;
    d.setDate(d.getDate() - 1);
  }
  return streak;
}

function NutritionTab({ data, persist }) {
  const [view, setView] = useState("today");

  return (
    <div className="tab-pad">
      <div className="segmented">
        <button
          className={"segmented-btn" + (view === "today" ? " active" : "")}
          onClick={() => setView("today")}
        >
          היום
        </button>
        <button
          className={"segmented-btn" + (view === "meals" ? " active" : "")}
          onClick={() => setView("meals")}
        >
          ארוחות
        </button>
        <button
          className={"segmented-btn" + (view === "recipes" ? " active" : "")}
          onClick={() => setView("recipes")}
        >
          מתכונים
        </button>
        <button
          className={"segmented-btn" + (view === "shopping" ? " active" : "")}
          onClick={() => setView("shopping")}
        >
          קניות
        </button>
      </div>

      {view === "today" && <TodayView data={data} persist={persist} />}
      {view === "meals" && <MealsView data={data} persist={persist} />}
      {view === "recipes" && (
        <RecipesView dietMode={data.profile.dietMode} data={data} persist={persist} />
      )}
      {view === "shopping" && <ShoppingView data={data} persist={persist} />}
    </div>
  );
}

function TodayView({ data, persist }) {
  const [switchOpen, setSwitchOpen] = useState(false);
  const mode = data.profile.dietMode;
  const diet = DIETS[mode];
  const today = todayStr();
  const todayEntry =
    data.nutritionLog[today] && data.nutritionLog[today].mode === mode
      ? data.nutritionLog[today]
      : { mode, checks: diet.principles.map(() => false) };

  const streak = computeStreak(data.nutritionLog);

  async function toggleCheck(i) {
    const checks = [...todayEntry.checks];
    checks[i] = !checks[i];
    await persist({
      ...data,
      nutritionLog: { ...data.nutritionLog, [today]: { mode, checks } },
    });
  }

  async function switchDiet(newMode) {
    await persist({
      ...data,
      profile: {
        ...data.profile,
        dietMode: newMode,
        ketoStartDate: newMode === "keto" ? today : data.profile.ketoStartDate,
        transitions: [...data.profile.transitions, { date: today, from: mode, to: newMode }],
      },
    });
    setSwitchOpen(false);
  }

  const last14 = useMemo(() => {
    const arr = [];
    for (let i = 13; i >= 0; i--) {
      const d = new Date();
      d.setDate(d.getDate() - i);
      const key = d.toISOString().slice(0, 10);
      const entry = data.nutritionLog[key];
      const clean = entry && entry.checks.filter(Boolean).length >= entry.checks.length - 1;
      arr.push({ key, clean: !!clean, has: !!entry });
    }
    return arr;
  }, [data.nutritionLog]);

  const doneToday = todayEntry.checks.filter(Boolean).length;

  return (
    <>
      <div className="diet-hero" style={{ borderColor: diet.color }}>
        <div className="diet-hero-top">
          <div>
            <div className="diet-hero-label">מצב תזונה נוכחי</div>
            <div className="diet-hero-name" style={{ color: diet.color }}>
              {diet.label}
            </div>
          </div>
          <button className="ghost-btn" onClick={() => setSwitchOpen(true)}>
            <ArrowLeftRight size={16} />
            החלף
          </button>
        </div>
        <div className="diet-hero-progress-track">
          <div
            className="diet-hero-progress-fill"
            style={{ width: `${(doneToday / diet.principles.length) * 100}%`, background: diet.color }}
          />
        </div>
        <div className="diet-hero-count">
          {doneToday}/{diet.principles.length} עקרונות היום
        </div>
      </div>

      <div className="section-label">מה מותר ומה אסור</div>
      <div className="food-guide-grid">
        <div className="food-guide-col food-guide-good">
          <div className="food-guide-title">✓ מותר</div>
          <ul className="food-guide-list">
            {FOOD_GUIDE[mode].allowed.map((item, i) => (
              <li key={i}>{item}</li>
            ))}
          </ul>
        </div>
        <div className="food-guide-col food-guide-bad">
          <div className="food-guide-title">✕ אסור</div>
          <ul className="food-guide-list">
            {FOOD_GUIDE[mode].avoid.map((item, i) => (
              <li key={i}>{item}</li>
            ))}
          </ul>
        </div>
      </div>

      {mode === "keto" && <KetosisCard data={data} persist={persist} />}

      <div className="section-label">רשימת היום</div>
      <div className="exercise-list">
        {diet.principles.map((p, i) => (
          <button key={i} className="exercise-row" onClick={() => toggleCheck(i)}>
            <div
              className="checkbox"
              style={{
                background: todayEntry.checks[i] ? diet.color : "transparent",
                borderColor: todayEntry.checks[i] ? diet.color : "var(--border)",
              }}
            >
              {todayEntry.checks[i] && <Check size={14} color="#16171A" strokeWidth={3} />}
            </div>
            <div style={{ flex: 1, textAlign: "right" }}>{p}</div>
          </button>
        ))}
      </div>

      <div className="section-label">
        <Flame size={14} color="var(--gold)" style={{ marginLeft: 4 }} />
        רצף ימים נקיים: {streak}
      </div>
      <div className="dots-row">
        {last14.map((d) => (
          <div
            key={d.key}
            className="day-dot"
            style={{ background: !d.has ? "var(--surface-2)" : d.clean ? diet.color : "var(--danger)" }}
            title={formatHe(d.key)}
          />
        ))}
      </div>

      {switchOpen && (
        <div className="modal-overlay" onClick={() => setSwitchOpen(false)}>
          <div className="modal-sheet" onClick={(e) => e.stopPropagation()}>
            <div className="modal-header">
              <div className="modal-title">החלפת מצב תזונה</div>
              <button className="icon-btn" onClick={() => setSwitchOpen(false)}>
                <X size={20} />
              </button>
            </div>
            <p className="modal-text">{TRANSITION_TEXT}</p>
            <div className="switch-options">
              {Object.entries(DIETS).map(([key, d]) => (
                <button
                  key={key}
                  className="switch-option"
                  disabled={key === mode}
                  style={{ borderColor: d.color, opacity: key === mode ? 0.4 : 1 }}
                  onClick={() => switchDiet(key)}
                >
                  <span style={{ color: d.color, fontWeight: 700 }}>{d.label}</span>
                  {key === mode && <span className="tag">נוכחי</span>}
                </button>
              ))}
            </div>
          </div>
        </div>
      )}
    </>
  );
}

function daysSince(dateStr) {
  const start = new Date(dateStr + "T00:00:00");
  const now = new Date();
  const diff = Math.floor((now - start) / (1000 * 60 * 60 * 24));
  return Math.max(0, diff) + 1; // כולל היום הראשון
}

function ketosisPhase(day) {
  if (day <= 1) return "מתחילים להגביל פחמימות";
  if (day <= 3) return "הגוף מתחיל לעבור לשריפת שומן";
  if (day <= 6) return "יתכן שכבר נכנסת לקטוזיס";
  return "סביר שאת/ה בקטוזיס יציב (אם נשמרים העקרונות)";
}

const KETONE_LEVELS = ["אין", "עקבות", "קלה", "בינונית", "גבוהה"];

function KetosisCard({ data, persist }) {
  const [logOpen, setLogOpen] = useState(false);
  const [method, setMethod] = useState("urine");
  const [level, setLevel] = useState("עקבות");
  const [bloodVal, setBloodVal] = useState("");

  const day = daysSince(data.profile.ketoStartDate);
  const phase = ketosisPhase(day);
  const progressPct = Math.min(100, Math.round((day / 7) * 100));

  const sortedLog = [...(data.ketoLog || [])].sort((a, b) => (a.date < b.date ? 1 : -1));

  async function resetCounter() {
    await persist({ ...data, profile: { ...data.profile, ketoStartDate: todayStr() } });
  }

  async function saveKetoneEntry() {
    const entry = {
      id: Date.now().toString(),
      date: todayStr(),
      method,
      value: method === "blood" ? bloodVal || "0" : level,
    };
    await persist({ ...data, ketoLog: [...(data.ketoLog || []), entry] });
    setLogOpen(false);
    setBloodVal("");
  }

  return (
    <>
      <div className="section-label">מד קטוזיס</div>
      <div className="keto-card">
        <div className="keto-card-top">
          <div>
            <div className="keto-day">יום {day}</div>
            <div className="keto-phase">{phase}</div>
          </div>
          <button className="ghost-btn" onClick={resetCounter}>
            אתחל ספירה
          </button>
        </div>
        <div className="diet-hero-progress-track">
          <div
            className="diet-hero-progress-fill"
            style={{ width: `${progressPct}%`, background: "var(--ember)" }}
          />
        </div>
        <div className="modal-text" style={{ marginTop: 10, marginBottom: 0 }}>
          זהו אומדן גס בלבד. הדרך היחידה לדעת בוודאות אם את/ה בקטוזיס היא בדיקת קטונים.
        </div>
        <button className="primary-btn" onClick={() => setLogOpen(true)}>
          עדכן תוצאת בדיקת קטונים
        </button>

        {sortedLog.length > 0 && (
          <div className="history-list" style={{ marginTop: 12 }}>
            {sortedLog.slice(0, 4).map((e) => (
              <div key={e.id} className="history-row">
                <div className="history-dot" style={{ background: "var(--ember)" }} />
                <div style={{ flex: 1 }}>
                  <div className="history-name">
                    {e.method === "blood" ? `${e.value} mmol/L` : e.value}
                  </div>
                  <div className="history-date">
                    {formatHe(e.date)} ·{" "}
                    {e.method === "blood" ? "בדיקת דם" : e.method === "urine" ? "רצועת שתן" : "תחושה"}
                  </div>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      {logOpen && (
        <div className="modal-overlay" onClick={() => setLogOpen(false)}>
          <div className="modal-sheet" onClick={(e) => e.stopPropagation()}>
            <div className="modal-header">
              <div className="modal-title">תוצאת בדיקת קטונים</div>
              <button className="icon-btn" onClick={() => setLogOpen(false)}>
                <X size={20} />
              </button>
            </div>
            <div className="chip-row" style={{ marginBottom: 12 }}>
              <button
                className={"chip" + (method === "urine" ? " active" : "")}
                onClick={() => setMethod("urine")}
              >
                רצועת שתן
              </button>
              <button
                className={"chip" + (method === "blood" ? " active" : "")}
                onClick={() => setMethod("blood")}
              >
                בדיקת דם
              </button>
              <button
                className={"chip" + (method === "feel" ? " active" : "")}
                onClick={() => setMethod("feel")}
              >
                תחושה בלבד
              </button>
            </div>

            {method === "blood" ? (
              <input
                autoFocus
                type="number"
                inputMode="decimal"
                placeholder="mmol/L, לדוגמה 1.2"
                className="text-input"
                value={bloodVal}
                onChange={(e) => setBloodVal(e.target.value)}
              />
            ) : (
              <div className="chip-row">
                {KETONE_LEVELS.map((l) => (
                  <button
                    key={l}
                    className={"chip" + (level === l ? " active" : "")}
                    onClick={() => setLevel(l)}
                  >
                    {l}
                  </button>
                ))}
              </div>
            )}

            <button className="primary-btn" onClick={saveKetoneEntry}>
              שמור
            </button>
          </div>
        </div>
      )}
    </>
  );
}

function MealsView({ data, persist }) {
  const fileInputRef = useRef(null);
  const [status, setStatus] = useState("idle");
  const [result, setResult] = useState(null);
  const [errorMsg, setErrorMsg] = useState("");

  async function handleFile(e) {
    const file = e.target.files && e.target.files[0];
    e.target.value = "";
    if (!file) return;
    setStatus("loading");
    setErrorMsg("");
    try {
      const base64 = await resizeImageToBase64(file);
      const analysis = await analyzeMealImage(base64);
      setResult(analysis);
      setStatus("preview");
    } catch (err) {
      setErrorMsg("לא הצלחתי לנתח את התמונה. אפשר לנסות שוב.");
      setStatus("error");
    }
  }

  async function saveMeal() {
    const mode = data.profile.dietMode;
    const compliant = mode === "keto" ? result.ketoFriendly : result.paleoFriendly;
    const entry = {
      id: Date.now().toString(),
      date: todayStr(),
      time: new Date().toLocaleTimeString("he-IL", { hour: "2-digit", minute: "2-digit" }),
      title: result.title,
      ingredients: result.ingredients || [],
      containsPork: !!result.containsPork,
      containsShellfish: !!result.containsShellfish,
      compliant: !!compliant,
      mode,
      notes: result.notes || "",
    };
    await persist({ ...data, mealLog: [...data.mealLog, entry] });
    setResult(null);
    setStatus("idle");
  }

  async function deleteMeal(id) {
    await persist({ ...data, mealLog: data.mealLog.filter((m) => m.id !== id) });
  }

  const sortedMeals = [...data.mealLog].sort((a, b) => (a.date + a.time < b.date + b.time ? 1 : -1));

  return (
    <>
      <input
        ref={fileInputRef}
        type="file"
        accept="image/*"
        capture="environment"
        style={{ display: "none" }}
        onChange={handleFile}
      />
      <button
        className="primary-btn"
        style={{ marginTop: 4 }}
        onClick={() => fileInputRef.current && fileInputRef.current.click()}
        disabled={status === "loading"}
      >
        {status === "loading" ? (
          <>
            <Loader2 size={18} className="spin" /> מנתח את התמונה...
          </>
        ) : (
          <>
            <Camera size={18} /> צלם / העלה ארוחה
          </>
        )}
      </button>

      {status === "error" && (
        <div className="banner banner-danger" style={{ marginTop: 12 }}>
          <AlertTriangle size={18} />
          <div className="banner-sub" style={{ color: "var(--text)" }}>
            {errorMsg}
          </div>
        </div>
      )}

      {status === "preview" && result && (
        <div
          className="modal-overlay"
          onClick={() => {
            setStatus("idle");
            setResult(null);
          }}
        >
          <div className="modal-sheet" onClick={(e) => e.stopPropagation()}>
            <div className="modal-header">
              <div className="modal-title">
                <Sparkles size={16} style={{ marginLeft: 6 }} color="var(--gold)" />
                {result.title}
              </div>
              <button
                className="icon-btn"
                onClick={() => {
                  setStatus("idle");
                  setResult(null);
                }}
              >
                <X size={20} />
              </button>
            </div>
            {(result.containsPork || result.containsShellfish) && (
              <div className="banner banner-danger">
                <AlertTriangle size={18} />
                <div className="banner-sub" style={{ color: "var(--text)" }}>
                  {result.containsPork && "מזוהה חזיר. "}
                  {result.containsShellfish && "מזוהים פירות ים."}
                </div>
              </div>
            )}
            <div className="modal-text" style={{ marginTop: 10 }}>
              רכיבים שזוהו: {(result.ingredients || []).join(", ")}
            </div>
            {result.notes && <div className="modal-text">{result.notes}</div>}
            <div className="dots-row" style={{ marginTop: 6, marginBottom: 6 }}>
              <span className="tag" style={{ color: result.ketoFriendly ? "var(--sage)" : "var(--danger)" }}>
                קיטו: {result.ketoFriendly ? "מתאים" : "לא מתאים"}
              </span>
              <span className="tag" style={{ color: result.paleoFriendly ? "var(--sage)" : "var(--danger)" }}>
                פליאו: {result.paleoFriendly ? "מתאים" : "לא מתאים"}
              </span>
            </div>
            <button className="primary-btn" onClick={saveMeal}>
              שמור ליומן הארוחות
            </button>
          </div>
        </div>
      )}

      <div className="section-label">יומן ארוחות</div>
      {sortedMeals.length === 0 ? (
        <div className="empty-hint">עוד לא נוספו ארוחות. צלמו את הארוחה הבאה שלכם.</div>
      ) : (
        <div className="history-list">
          {sortedMeals.map((m) => (
            <div key={m.id} className="history-row">
              <div
                className="history-dot"
                style={{ background: m.compliant ? "var(--sage)" : "var(--danger)" }}
              />
              <div style={{ flex: 1 }}>
                <div className="history-name">{m.title}</div>
                <div className="history-date">
                  {formatHe(m.date)} · {m.time}
                  {(m.containsPork || m.containsShellfish) && " · ⚠ לא כשר"}
                </div>
              </div>
              <button className="icon-btn" onClick={() => deleteMeal(m.id)}>
                <Trash2 size={16} />
              </button>
            </div>
          ))}
        </div>
      )}
    </>
  );
}

function RecipesView({ dietMode, data, persist }) {
  const [filter, setFilter] = useState(dietMode);
  const [added, setAdded] = useState(null);

  const filtered = RECIPES.filter((r) => filter === "all" || r.diet === filter);

  async function addToShoppingList(recipe) {
    const existingTexts = new Set(data.shoppingList.map((i) => i.text));
    const newItems = recipe.ingredients
      .filter((ing) => !existingTexts.has(ing))
      .map((ing) => ({ id: Date.now().toString() + Math.random(), text: ing, checked: false }));
    await persist({ ...data, shoppingList: [...data.shoppingList, ...newItems] });
    setAdded(recipe.id);
    setTimeout(() => setAdded(null), 1500);
  }

  return (
    <>
      <div className="chip-row" style={{ marginTop: 4 }}>
        <button className={"chip" + (filter === "all" ? " active" : "")} onClick={() => setFilter("all")}>
          הכל
        </button>
        <button className={"chip" + (filter === "keto" ? " active" : "")} onClick={() => setFilter("keto")}>
          קיטו
        </button>
        <button className={"chip" + (filter === "paleo" ? " active" : "")} onClick={() => setFilter("paleo")}>
          פליאו
        </button>
      </div>

      <div className="section-label">
        <BookOpen size={14} style={{ marginLeft: 4 }} color="var(--gold)" />
        מתכונים ללא חזיר וללא פירות ים
      </div>

      {filtered.map((r) => (
        <RecipeCard
          key={r.id}
          recipe={r}
          onAddToList={() => addToShoppingList(r)}
          justAdded={added === r.id}
        />
      ))}
    </>
  );
}

function RecipeCard({ recipe, onAddToList, justAdded }) {
  const [open, setOpen] = useState(false);
  const color = recipe.diet === "keto" ? "var(--ember)" : "var(--sage)";
  return (
    <div className="recipe-card">
      <button className="recipe-title-row" onClick={() => setOpen(!open)}>
        <div>
          <div className="recipe-title">{recipe.title}</div>
          <div className="recipe-meta">{recipe.time}</div>
        </div>
        <span className="recipe-badge" style={{ color }}>
          {recipe.diet === "keto" ? "קיטו" : "פליאו"}
        </span>
      </button>
      {open && (
        <div className="recipe-body">
          <div className="recipe-sub">רכיבים</div>
          <ul className="recipe-list">
            {recipe.ingredients.map((ing, i) => (
              <li key={i}>{ing}</li>
            ))}
          </ul>
          <div className="recipe-sub">הכנה</div>
          <ol className="recipe-list numbered">
            {recipe.steps.map((s, i) => (
              <li key={i}>{s}</li>
            ))}
          </ol>
          <button className="ghost-btn" style={{ width: "100%", justifyContent: "center" }} onClick={onAddToList}>
            <ShoppingCart size={16} />
            {justAdded ? "נוסף לרשימה ✓" : "הוסף מצרכים לרשימת קניות"}
          </button>
        </div>
      )}
    </div>
  );
}

function ShoppingView({ data, persist }) {
  const [text, setText] = useState("");

  async function toggleItem(id) {
    await persist({
      ...data,
      shoppingList: data.shoppingList.map((i) => (i.id === id ? { ...i, checked: !i.checked } : i)),
    });
  }

  async function addManual() {
    if (!text.trim()) return;
    await persist({
      ...data,
      shoppingList: [...data.shoppingList, { id: Date.now().toString(), text: text.trim(), checked: false }],
    });
    setText("");
  }

  async function removeItem(id) {
    await persist({ ...data, shoppingList: data.shoppingList.filter((i) => i.id !== id) });
  }

  async function clearChecked() {
    await persist({ ...data, shoppingList: data.shoppingList.filter((i) => !i.checked) });
  }

  const uncheckedCount = data.shoppingList.filter((i) => !i.checked).length;

  return (
    <>
      <div className="section-label">
        <ShoppingCart size={14} style={{ marginLeft: 4 }} color="var(--gold)" />
        רשימת קניות · {uncheckedCount} פריטים
      </div>

      <div style={{ display: "flex", gap: 8, marginBottom: 12 }}>
        <input
          className="text-input"
          style={{ fontFamily: "Heebo", fontSize: 14, textAlign: "right" }}
          placeholder="הוסיפו פריט..."
          value={text}
          onChange={(e) => setText(e.target.value)}
          onKeyDown={(e) => e.key === "Enter" && addManual()}
        />
        <button className="icon-btn" style={{ width: 48, borderRadius: 12 }} onClick={addManual}>
          <Plus size={18} />
        </button>
      </div>

      {data.shoppingList.length === 0 ? (
        <div className="empty-hint">
          הרשימה ריקה. הוסיפו פריטים ידנית, או לחצו "הוסף מצרכים" במתכון שאהבתם.
        </div>
      ) : (
        <div className="exercise-list">
          {data.shoppingList.map((item) => (
            <div key={item.id} className="exercise-row" style={{ cursor: "default" }}>
              <button
                className="checkbox"
                onClick={() => toggleItem(item.id)}
                style={{
                  background: item.checked ? "var(--sage)" : "transparent",
                  borderColor: item.checked ? "var(--sage)" : "var(--border)",
                }}
              >
                {item.checked && <Check size={14} color="#16171A" strokeWidth={3} />}
              </button>
              <div
                style={{
                  flex: 1,
                  textAlign: "right",
                  textDecoration: item.checked ? "line-through" : "none",
                  color: item.checked ? "var(--text-dim)" : "var(--text)",
                }}
              >
                {item.text}
              </div>
              <button className="icon-btn" onClick={() => removeItem(item.id)}>
                <X size={14} />
              </button>
            </div>
          ))}
        </div>
      )}

      {data.shoppingList.some((i) => i.checked) && (
        <button className="ghost-btn" style={{ width: "100%", justifyContent: "center", marginTop: 12 }} onClick={clearChecked}>
          <Trash2 size={16} /> נקה פריטים שסומנו
        </button>
      )}
    </>
  );
}

/* ------------------------------------------------------------------ */
/* לשונית משקל                                                        */
/* ------------------------------------------------------------------ */

function WeightTab({ data, persist }) {
  const [addOpen, setAddOpen] = useState(false);
  const [val, setVal] = useState("");
  const [goalOpen, setGoalOpen] = useState(false);
  const [goalVal, setGoalVal] = useState(data.profile.goalWeight || "");

  const sorted = [...data.weightLog].sort((a, b) => (a.date < b.date ? -1 : 1));
  const current = sorted.length ? sorted[sorted.length - 1].weight : null;
  const start = sorted.length ? sorted[0].weight : null;
  const change = current !== null && start !== null ? current - start : 0;

  const chartData = sorted.map((e) => ({ date: formatHe(e.date), weight: e.weight }));

  async function addEntry() {
    const w = parseFloat(val);
    if (!w || w <= 0) return;
    const today = todayStr();
    const withoutToday = data.weightLog.filter((e) => e.date !== today);
    await persist({ ...data, weightLog: [...withoutToday, { date: today, weight: w }] });
    setVal("");
    setAddOpen(false);
  }

  async function saveGoal() {
    const g = parseFloat(goalVal);
    await persist({ ...data, profile: { ...data.profile, goalWeight: g > 0 ? g : null } });
    setGoalOpen(false);
  }

  const TrendIcon = change < 0 ? TrendingDown : change > 0 ? TrendingUp : Minus;

  return (
    <div className="tab-pad">
      <div className="stat-grid">
        <div className="stat-card">
          <div className="stat-label">נוכחי</div>
          <div className="stat-value">
            {current !== null ? current : "—"}
            <span className="stat-unit">ק״ג</span>
          </div>
        </div>
        <div className="stat-card">
          <div className="stat-label">שינוי</div>
          <div
            className="stat-value"
            style={{ color: change < 0 ? "var(--sage)" : change > 0 ? "var(--danger)" : "var(--text)" }}
          >
            <TrendIcon size={18} style={{ marginLeft: 4 }} />
            {Math.abs(change).toFixed(1)}
          </div>
        </div>
        <div className="stat-card" onClick={() => setGoalOpen(true)}>
          <div className="stat-label">יעד</div>
          <div className="stat-value">
            {data.profile.goalWeight || "הגדר"}
            {data.profile.goalWeight && <span className="stat-unit">ק״ג</span>}
          </div>
        </div>
      </div>

      <div className="chart-card">
        {chartData.length >= 2 ? (
          <ResponsiveContainer width="100%" height={200}>
            <LineChart data={chartData}>
              <CartesianGrid stroke="var(--border)" strokeDasharray="3 3" />
              <XAxis dataKey="date" stroke="var(--text-dim)" fontSize={11} tickLine={false} />
              <YAxis
                stroke="var(--text-dim)"
                fontSize={11}
                domain={["dataMin - 2", "dataMax + 2"]}
                tickLine={false}
                width={32}
              />
              <Tooltip
                contentStyle={{
                  background: "var(--surface-2)",
                  border: "1px solid var(--border)",
                  borderRadius: 8,
                  fontFamily: "Heebo",
                }}
              />
              <Line type="monotone" dataKey="weight" stroke="var(--steel)" strokeWidth={2.5} dot={{ r: 3, fill: "var(--steel)" }} />
            </LineChart>
          </ResponsiveContainer>
        ) : (
          <div className="empty-hint">הוסיפו לפחות שתי מדידות כדי לראות גרף מגמה</div>
        )}
      </div>

      <button className="primary-btn" onClick={() => setAddOpen(true)}>
        <Plus size={18} /> הוסף מדידת משקל
      </button>

      <div className="section-label">היסטוריה</div>
      <div className="history-list">
        {[...sorted].reverse().slice(0, 8).map((e) => (
          <div key={e.date} className="history-row">
            <div className="history-dot" style={{ background: "var(--steel)" }} />
            <div style={{ flex: 1 }}>
              <div className="history-name">{e.weight} ק״ג</div>
              <div className="history-date">{formatHe(e.date)}</div>
            </div>
          </div>
        ))}
        {sorted.length === 0 && <div className="empty-hint">עדיין אין מדידות</div>}
      </div>

      {addOpen && (
        <div className="modal-overlay" onClick={() => setAddOpen(false)}>
          <div className="modal-sheet" onClick={(e) => e.stopPropagation()}>
            <div className="modal-header">
              <div className="modal-title">מדידת משקל להיום</div>
              <button className="icon-btn" onClick={() => setAddOpen(false)}>
                <X size={20} />
              </button>
            </div>
            <input
              autoFocus
              type="number"
              inputMode="decimal"
              placeholder="לדוגמה 78.4"
              className="text-input"
              value={val}
              onChange={(e) => setVal(e.target.value)}
            />
            <button className="primary-btn" onClick={addEntry}>
              שמור
            </button>
          </div>
        </div>
      )}

      {goalOpen && (
        <div className="modal-overlay" onClick={() => setGoalOpen(false)}>
          <div className="modal-sheet" onClick={(e) => e.stopPropagation()}>
            <div className="modal-header">
              <div className="modal-title">יעד משקל</div>
              <button className="icon-btn" onClick={() => setGoalOpen(false)}>
                <X size={20} />
              </button>
            </div>
            <input
              autoFocus
              type="number"
              inputMode="decimal"
              placeholder="ק״ג"
              className="text-input"
              value={goalVal}
              onChange={(e) => setGoalVal(e.target.value)}
            />
            <button className="primary-btn" onClick={saveGoal}>
              שמור יעד
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

/* ------------------------------------------------------------------ */
/* עיצוב                                                              */
/* ------------------------------------------------------------------ */

function FontStyle() {
  return (
    <style>{`
      @import url('https://fonts.googleapis.com/css2?family=Heebo:wght@400;500;700;800;900&family=Roboto+Mono:wght@500;700&display=swap');

      :root {
        --bg: #16171A;
        --surface: #1E1D1A;
        --surface-2: #29281F;
        --border: #38362C;
        --text: #F2EEE6;
        --text-dim: #A9A399;
        --ember: #C8481F;
        --sage: #6E9B6B;
        --steel: #7C93A8;
        --gold: #D9A441;
        --danger: #B0483F;
      }

      * { box-sizing: border-box; }

      .app-shell {
        font-family: 'Heebo', sans-serif;
        background: var(--bg);
        color: var(--text);
        min-height: 100vh;
        max-width: 480px;
        margin: 0 auto;
        display: flex;
        flex-direction: column;
        position: relative;
      }
      .center-loader { align-items: center; justify-content: center; }
      .login-card {
        width: 88%; max-width: 340px; background: var(--surface); border: 1px solid var(--border);
        border-radius: 18px; padding: 26px 22px;
      }
      .loader-dot {
        width: 12px; height: 12px; border-radius: 50%;
        background: var(--ember); animation: pulse 1s infinite ease-in-out;
      }
      @keyframes pulse { 0%,100%{opacity:.3} 50%{opacity:1} }
      .spin { animation: spin 1s linear infinite; }
      @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

      .app-header {
        display: flex; align-items: center; justify-content: space-between;
        padding: 20px 20px 14px 20px;
        border-bottom: 1px solid var(--border);
      }
      .app-title { font-size: 22px; font-weight: 900; letter-spacing: 0.5px; }
      .app-subtitle { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
      .streak-chip {
        display: flex; align-items: center; gap: 4px;
        background: var(--surface-2); border-radius: 999px;
        padding: 6px 10px; font-family: 'Roboto Mono', monospace;
        font-size: 13px; font-weight: 700;
      }

      .app-main { flex: 1; overflow-y: auto; padding-bottom: 90px; }
      .tab-pad { padding: 18px 20px; }

      .section-label {
        font-size: 13px; font-weight: 700; color: var(--text-dim);
        margin: 22px 0 10px 0; display: flex; align-items: center;
      }

      .chip-row { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; }
      .chip {
        padding: 8px 14px; border-radius: 999px; border: 1px solid var(--border);
        background: var(--surface); font-size: 13px; font-weight: 700;
        white-space: nowrap; color: var(--text-dim); font-family: 'Heebo';
      }
      .chip.active { background: var(--ember); color: #16171A; border-color: var(--ember); }

      .segmented { display: flex; background: var(--surface-2); border-radius: 12px; padding: 4px; gap: 4px; }
      .segmented-btn {
        flex: 1; text-align: center; padding: 9px; border-radius: 9px; font-size: 13px;
        font-weight: 700; background: transparent; border: none; color: var(--text-dim);
        font-family: 'Heebo';
      }
      .segmented-btn.active { background: var(--surface); color: var(--text); }

      .medallion-card {
        display: flex; align-items: center; gap: 4px;
        background: var(--surface); border: 1px solid var(--border);
        border-radius: 18px; padding: 16px; position: relative;
      }
      .medallion-level { font-size: 16px; font-weight: 800; }
      .medallion-sub { font-size: 13px; color: var(--text-dim); margin-top: 2px; }
      .medallion-pct { font-family: 'Roboto Mono', monospace; font-size: 12px; color: var(--gold); margin-top: 6px; font-weight: 700; }

      .banner {
        display: flex; align-items: center; gap: 10px;
        border-radius: 14px; padding: 12px 14px; margin-top: 16px;
        border: 1px solid var(--ember); background: rgba(200,72,31,0.1);
        color: var(--ember);
      }
      .banner-danger { border-color: var(--danger); background: rgba(176,72,63,0.14); color: var(--danger); }
      .banner-title { font-size: 13px; font-weight: 800; color: var(--text); }
      .banner-sub { font-size: 12px; color: var(--text-dim); }
      .pill-btn {
        background: var(--ember); color: #16171A; border: none;
        border-radius: 999px; padding: 8px 14px; font-size: 12px;
        font-weight: 800; font-family: 'Heebo'; white-space: nowrap;
      }

      .workout-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
      .workout-card {
        background: var(--surface); border: 1px solid var(--border);
        border-radius: 14px; padding: 14px; text-align: right;
        color: var(--text); font-family: 'Heebo';
      }
      .workout-card-name { font-size: 15px; font-weight: 800; }
      .workout-card-count { font-size: 12px; color: var(--text-dim); margin-top: 4px; }
      .workout-card-cta {
        margin-top: 14px; font-size: 12px; font-weight: 700; color: var(--ember);
        display: flex; align-items: center; justify-content: flex-start; gap: 2px;
      }

      .history-list { display: flex; flex-direction: column; gap: 8px; }
      .history-row {
        display: flex; align-items: center; gap: 12px;
        background: var(--surface); border: 1px solid var(--border);
        border-radius: 12px; padding: 10px 14px;
      }
      .history-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--gold); flex-shrink: 0; }
      .history-name { font-size: 14px; font-weight: 700; }
      .history-date { font-size: 12px; color: var(--text-dim); }
      .history-count { font-family: 'Roboto Mono', monospace; font-size: 13px; color: var(--text-dim); }

      .empty-hint {
        color: var(--text-dim); font-size: 13px; background: var(--surface);
        border: 1px dashed var(--border); border-radius: 12px; padding: 18px;
        text-align: center;
      }

      .modal-overlay {
        position: fixed; inset: 0; background: rgba(0,0,0,0.55);
        display: flex; align-items: flex-end; justify-content: center; z-index: 50;
      }
      .modal-sheet {
        background: var(--surface); width: 100%; max-width: 480px;
        border-radius: 20px 20px 0 0; padding: 20px; border-top: 1px solid var(--border);
        max-height: 85vh; overflow-y: auto;
      }
      .modal-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
      .modal-title { font-size: 17px; font-weight: 800; display: flex; align-items: center; }
      .modal-text { font-size: 13px; color: var(--text-dim); line-height: 1.6; margin-bottom: 10px; }
      .icon-btn { background: var(--surface-2); border: none; border-radius: 50%; width: 32px; height: 32px; display:flex; align-items:center; justify-content:center; color: var(--text); flex-shrink: 0; }

      .exercise-list { display: flex; flex-direction: column; gap: 8px; }
      .exercise-row {
        display: flex; align-items: center; gap: 12px; background: var(--surface);
        border: 1px solid var(--border); border-radius: 12px; padding: 12px 14px;
        color: var(--text); font-family: 'Heebo'; text-align: right;
      }
      .exercise-name { font-size: 14px; font-weight: 700; }
      .exercise-target { font-size: 12px; color: var(--text-dim); margin-top: 2px; font-family: 'Roboto Mono', monospace; }
      .checkbox {
        width: 24px; height: 24px; border-radius: 7px; border: 2px solid var(--border);
        display: flex; align-items: center; justify-content: center; flex-shrink: 0;
      }

      .primary-btn {
        width: 100%; background: var(--ember); color: #16171A; border: none;
        border-radius: 14px; padding: 15px; font-size: 15px; font-weight: 800;
        margin-top: 16px; display: flex; align-items: center; justify-content: center; gap: 6px;
        font-family: 'Heebo';
      }
      .primary-btn:disabled { opacity: 0.6; }
      .ghost-btn {
        background: transparent; border: 1px solid var(--border); color: var(--text);
        border-radius: 999px; padding: 7px 12px; font-size: 12px; font-weight: 700;
        display: flex; align-items: center; gap: 6px; font-family: 'Heebo';
      }

      .diet-hero {
        background: var(--surface); border: 1px solid var(--border); border-right: 3px solid;
        border-radius: 16px; padding: 16px; margin-top: 14px;
      }
      .diet-hero-top { display: flex; align-items: flex-start; justify-content: space-between; }
      .diet-hero-label { font-size: 12px; color: var(--text-dim); }
      .diet-hero-name { font-size: 24px; font-weight: 900; margin-top: 2px; }
      .diet-hero-progress-track { height: 6px; background: var(--surface-2); border-radius: 999px; margin-top: 14px; overflow: hidden; }
      .diet-hero-progress-fill { height: 100%; border-radius: 999px; transition: width .3s; }
      .diet-hero-count { font-size: 12px; color: var(--text-dim); margin-top: 6px; font-family: 'Roboto Mono', monospace; }

      .dots-row { display: flex; gap: 6px; flex-wrap: wrap; }
      .day-dot { width: 18px; height: 18px; border-radius: 6px; }

      .food-guide-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
      .food-guide-col {
        background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
        padding: 12px;
      }
      .food-guide-good { border-right: 3px solid var(--sage); }
      .food-guide-bad { border-right: 3px solid var(--danger); }
      .food-guide-title { font-size: 13px; font-weight: 800; margin-bottom: 8px; }
      .food-guide-good .food-guide-title { color: var(--sage); }
      .food-guide-bad .food-guide-title { color: var(--danger); }
      .food-guide-list { margin: 0; padding-right: 16px; font-size: 12px; line-height: 1.7; color: var(--text); }

      .keto-card {
        background: var(--surface); border: 1px solid var(--border); border-radius: 16px;
        padding: 16px;
      }
      .keto-card-top { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 12px; }
      .keto-day { font-family: 'Roboto Mono', monospace; font-size: 22px; font-weight: 700; }
      .keto-phase { font-size: 12px; color: var(--text-dim); margin-top: 2px; }

      .switch-options { display: flex; flex-direction: column; gap: 10px; }
      .switch-option {
        display: flex; align-items: center; justify-content: space-between;
        background: var(--surface-2); border: 1.5px solid; border-radius: 12px;
        padding: 14px; font-family: 'Heebo'; font-size: 14px;
      }
      .tag { font-size: 11px; background: var(--border); padding: 3px 8px; border-radius: 999px; color: var(--text-dim); }

      .stat-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
      .stat-card {
        background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
        padding: 12px; text-align: center;
      }
      .stat-label { font-size: 11px; color: var(--text-dim); }
      .stat-value {
        font-family: 'Roboto Mono', monospace; font-size: 19px; font-weight: 700;
        margin-top: 4px; display: flex; align-items: center; justify-content: center;
      }
      .stat-unit { font-size: 11px; color: var(--text-dim); margin-right: 3px; font-family: 'Heebo'; }

      .chart-card {
        background: var(--surface); border: 1px solid var(--border); border-radius: 16px;
        padding: 14px 6px; margin-top: 14px;
      }

      .text-input {
        width: 100%; background: var(--surface-2); border: 1px solid var(--border);
        border-radius: 12px; padding: 14px; color: var(--text); font-size: 18px;
        font-family: 'Roboto Mono', monospace; text-align: center;
      }
      .text-input:focus { outline: none; border-color: var(--steel); }

      .recipe-card {
        background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
        padding: 14px; margin-bottom: 10px;
      }
      .recipe-title-row {
        width: 100%; background: none; border: none; display: flex;
        align-items: flex-start; justify-content: space-between; text-align: right;
        color: var(--text); font-family: 'Heebo'; padding: 0;
      }
      .recipe-title { font-size: 15px; font-weight: 800; }
      .recipe-meta { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
      .recipe-badge { font-size: 11px; font-weight: 700; }
      .recipe-body { margin-top: 12px; border-top: 1px solid var(--border); padding-top: 12px; }
      .recipe-sub { font-size: 12px; font-weight: 800; color: var(--text-dim); margin-bottom: 6px; }
      .recipe-list { margin: 0 0 12px 0; padding-right: 18px; font-size: 13px; line-height: 1.7; }
      .recipe-list.numbered { padding-right: 20px; }

      .bottom-nav {
        position: fixed; bottom: 0; left: 50%; transform: translateX(-50%);
        width: 100%; max-width: 480px; background: var(--surface);
        border-top: 1px solid var(--border); display: flex;
        padding: 8px 12px calc(8px + env(safe-area-inset-bottom, 0px));
      }
      .nav-btn {
        flex: 1; background: none; border: none; display: flex; flex-direction: column;
        align-items: center; gap: 4px; padding: 6px 0; font-family: 'Heebo';
      }
      .nav-icon-wrap { border-radius: 10px; padding: 5px 16px; }
    `}</style>
  );
}

/* ------------------------------------------------------------------ */
/* מסך התחברות + הרצת האפליקציה                                      */
/* ------------------------------------------------------------------ */

function LoginScreen({ onSuccess }) {
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(false);

  async function handleSubmit(e) {
    e.preventDefault();
    setError("");
    setLoading(true);
    try {
      const res = await fetch("/api/login", {
        method: "POST",
        credentials: "include",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ username, password }),
      });
      if (res.ok) {
        onSuccess();
      } else {
        setError("שם משתמש או סיסמה שגויים");
      }
    } catch {
      setError("שגיאת חיבור לשרת");
    } finally {
      setLoading(false);
    }
  }

  return (
    <div className="app-shell center-loader" dir="rtl">
      <FontStyle />
      <form onSubmit={handleSubmit} className="login-card">
        <div className="app-title" style={{ marginBottom: 18, textAlign: "center" }}>
          שגרה
        </div>
        <input
          className="text-input"
          style={{ marginBottom: 10, fontFamily: "Heebo", fontSize: 15, textAlign: "right" }}
          placeholder="שם משתמש"
          value={username}
          onChange={(e) => setUsername(e.target.value)}
          autoFocus
        />
        <input
          className="text-input"
          style={{ marginBottom: 14, fontFamily: "Heebo", fontSize: 15, textAlign: "right" }}
          placeholder="סיסמה"
          type="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
        />
        {error && (
          <div style={{ color: "var(--danger)", fontSize: 13, marginBottom: 10, textAlign: "center" }}>
            {error}
          </div>
        )}
        <button className="primary-btn" type="submit" disabled={loading} style={{ marginTop: 0 }}>
          {loading ? "מתחבר..." : "התחבר"}
        </button>
      </form>
    </div>
  );
}

function AuthGate() {
  const [authed, setAuthed] = useState(null);

  useEffect(() => {
    fetch("/api/session", { credentials: "include" })
      .then((r) => r.json())
      .then((d) => setAuthed(!!d.authed))
      .catch(() => setAuthed(false));
  }, []);

  async function logout() {
    await fetch("/api/logout", { method: "POST", credentials: "include" }).catch(() => {});
    setAuthed(false);
  }

  if (authed === null) {
    return (
      <div className="app-shell center-loader">
        <FontStyle />
        <div className="loader-dot" />
      </div>
    );
  }
  if (!authed) {
    return <LoginScreen onSuccess={() => setAuthed(true)} />;
  }
  return <App onLogout={logout} />;
}

const container = document.getElementById("root");
const root = createRoot(container);
root.render(<AuthGate />);
