/* NutriDMS, API Sandbox */
const { useState: useSbState, useEffect: useSbEffect, useMemo: useSbMemo, useRef: useSbRef } = React;
const _SbCtx = { role: "super-admin", page: "sandbox", setPage: () => {}, lang: "en", setLang: () => {}, openCmd: () => {}, openNotif: () => {} };

const DS = window.NUTRIDMS_SANDBOX || { ingredients: [], recipes: [], beverages: [] };

/* ─── Pretty JSON renderer ─── */
function PrettyJson({ data }) {
  const render = (v, indent = 0) => {
    const pad = "  ".repeat(indent);
    if (v === null) return <span className="b">null</span>;
    if (typeof v === "boolean") return <span className="b">{String(v)}</span>;
    if (typeof v === "number") return <span className="n">{v}</span>;
    if (typeof v === "string") return <span className="s">{JSON.stringify(v)}</span>;
    if (Array.isArray(v)) {
      if (v.length === 0) return <span className="p">[]</span>;
      return (
        <>
          <span className="p">[</span>
          {v.map((x, i) =>
          <React.Fragment key={i}>
              {"\n"}{pad}  {render(x, indent + 1)}{i < v.length - 1 && <span className="p">,</span>}
            </React.Fragment>
          )}
          {"\n"}{pad}<span className="p">]</span>
        </>);

    }
    if (typeof v === "object") {
      const keys = Object.keys(v);
      if (keys.length === 0) return <span className="p">{"{}"}</span>;
      return (
        <>
          <span className="p">{"{"}</span>
          {keys.map((k, i) =>
          <React.Fragment key={k}>
              {"\n"}{pad}  <span className="k">"{k}"</span><span className="p">:</span> {render(v[k], indent + 1)}{i < keys.length - 1 && <span className="p">,</span>}
            </React.Fragment>
          )}
          {"\n"}{pad}<span className="p">}</span>
        </>);

    }
    return null;
  };
  return <pre className="sb-code">{render(data)}</pre>;
}

function copyToClipboard(text) {
  try {navigator.clipboard.writeText(text);} catch (e) {}
}

/* ─── Verification badge ─── */
function VerifyBadge({ status }) {
  const s = (status || "Verified").toLowerCase();
  const cls = s.includes("verif") || s.includes("approv") ? "verified" : s.includes("pend") ? "pending" : s.includes("suggest") ? "suggested" : "verified";
  return <span className={`sb-verify ${cls}`}><Icon name="check-check" size={11} stroke={2.6} /> {status || "Verified"}</span>;
}

/* ─── Ingredient response card ─── */
function IngredientCard({ ing, qty, unit }) {
  if (!ing) return null;
  const factor = (qty || 0) / 100;
  const n = ing.nutrition_per_100g;
  const calc = (val) => val == null ? "—" : +(val * factor).toFixed(2);
  return (
    <div className="sb-result">
      <div className="sb-hero-photo">
        <span className="em">{ing.emoji}</span>
        <span className="badge"><Icon name="check-circle-2" size={11} stroke={2.6} /> RDN Verified</span>
        <div className="meta">
          <span className="chip">{ing.category || "Ingredient"}</span>
          <span className="chip">{ing.state}</span>
          {ing.allergens.length === 0 && <span className="chip">Allergen-free</span>}
        </div>
      </div>
      <div className="sb-result-head">
        <div className="emoji-tile">{ing.emoji}</div>
        <div className="nm">
          <h3>{ing.name}</h3>
          <div className="sub">
            <strong>{ing.id}</strong> · {qty || 100}{unit || "g"} serving · {ing.canonical}
          </div>
        </div>
        <VerifyBadge status={ing.verification} />
      </div>
      <div className="sb-result-body">
        {ing.description && <p style={{ fontSize: 13, color: "var(--gray-700)", margin: "0 0 14px", lineHeight: 1.55 }}>{ing.description}</p>}

        <div className="sb-section-lbl"><Icon name="activity" size={12} stroke={2.4} /> Nutrition · per {qty || 100}{unit || "g"}</div>
        <div className="sb-nutr-grid">
          <div className="sb-nutr"><div className="lbl">Calories</div><div className="val">{calc(n.calories_kcal)}<span className="u">kcal</span></div></div>
          <div className="sb-nutr"><div className="lbl">Protein</div><div className="val">{calc(n.protein_g)}<span className="u">g</span></div></div>
          <div className="sb-nutr"><div className="lbl">Fat</div><div className="val">{calc(n.fat_g)}<span className="u">g</span></div></div>
          <div className="sb-nutr"><div className="lbl">Carbs</div><div className="val">{calc(n.carbohydrates_g)}<span className="u">g</span></div></div>
          <div className="sb-nutr"><div className="lbl">Sugar</div><div className="val">{calc(n.sugar_g)}<span className="u">g</span></div></div>
          <div className="sb-nutr"><div className="lbl">Fiber</div><div className="val">{calc(n.fiber_g)}<span className="u">g</span></div></div>
          <div className="sb-nutr"><div className="lbl">Sodium</div><div className="val">{calc(n.sodium_mg)}<span className="u">mg</span></div></div>
          <div className="sb-nutr"><div className="lbl">Potassium</div><div className="val">{calc(n.potassium_mg)}<span className="u">mg</span></div></div>
          <div className="sb-nutr"><div className="lbl">Iron</div><div className="val">{calc(n.iron_mg)}<span className="u">mg</span></div></div>
        </div>

        <div className="sb-section-lbl"><Icon name="shield-alert" size={12} stroke={2.4} /> Allergens</div>
        <div className="sb-tag-row">
          {ing.allergens.length === 0 ?
          <span className="sb-tag muted"><Icon name="check" size={11} stroke={2.6} /> No declared allergens</span> :
          ing.allergens.map((a) => <span key={a} className="sb-tag allergen"><Icon name="alert-triangle" size={11} stroke={2.6} /> {a}</span>)}
        </div>

        <div className="sb-section-lbl"><Icon name="heart-pulse" size={12} stroke={2.4} /> Health tags</div>
        <div className="sb-tag-row">
          {ing.health_tags.length === 0 ?
          <span className="sb-tag muted">No matching health rules</span> :
          ing.health_tags.map((t) => <span key={t} className="sb-tag health"><Icon name="check" size={11} stroke={2.6} /> {t}</span>)}
        </div>

        <div className="sb-source">
          <Icon name="file-check" size={14} stroke={2.4} />
          <div>
            <strong>Source · NutriDMS Master Ingredient DB</strong><br />
            Reference: {ing.source_ref || "—"} · Reviewed by RDN · {typeof ing.source === "string" && ing.source.startsWith("http") ? <a href={ing.source} target="_blank" rel="noreferrer">view source</a> : ing.source || "USDA"}
          </div>
        </div>
      </div>
    </div>);

}

/* ─── Recipe response card ─── */
function RecipeCard({ rec }) {
  if (!rec) return null;
  const n = rec.nutrition_per_serving;
  const ings = (rec.ingredients_text || "").split(/[,•]/).map((s) => s.trim()).filter(Boolean).slice(0, 12);
  return (
    <div className="sb-result">
      <div className="sb-hero-photo" style={{ width: "36px" }}>
        <span className="em">{rec.emoji}</span>
        <span className="badge"><Icon name="check-circle-2" size={11} stroke={2.6} /> RDN Approved</span>
        <div className="meta">
          <span className="chip"><Icon name="globe" size={10} stroke={2.4} /> {rec.country}</span>
          <span className="chip"><Icon name="clock" size={10} stroke={2.4} /> {(rec.prep_time_min || 0) + (rec.cook_time_min || 0)} min</span>
          <span className="chip"><Icon name="users" size={10} stroke={2.4} /> Serves {rec.serves}</span>
        </div>
      </div>
      <div className="sb-result-head">
        <div className="emoji-tile" style={{ height: "130px", width: "210px" }}>{rec.emoji}</div>
        <div className="nm">
          <h3>{rec.name}</h3>
          <div className="sub"><strong>{rec.id}</strong> · {rec.type} · {rec.meal_time}</div>
        </div>
        <VerifyBadge status={rec.verification} />
      </div>
      <div className="sb-result-body">
        {rec.description && <p style={{ fontSize: 13, color: "var(--gray-700)", margin: "0 0 14px", lineHeight: 1.55 }}>{rec.description}</p>}

        <div className="sb-section-lbl"><Icon name="activity" size={12} stroke={2.4} /> Per serving · {rec.serving_g}g</div>
        <div className="sb-nutr-grid">
          <div className="sb-nutr"><div className="lbl">Calories</div><div className="val">{n.calories_kcal}<span className="u">kcal</span></div></div>
          <div className="sb-nutr"><div className="lbl">Protein</div><div className="val">{n.protein_g}<span className="u">g</span></div></div>
          <div className="sb-nutr"><div className="lbl">Fat</div><div className="val">{n.fat_g}<span className="u">g</span></div></div>
          <div className="sb-nutr"><div className="lbl">Carbs</div><div className="val">{n.carbs_g}<span className="u">g</span></div></div>
          <div className="sb-nutr"><div className="lbl">Fiber</div><div className="val">{n.fiber_g}<span className="u">g</span></div></div>
          <div className="sb-nutr"><div className="lbl">Serves</div><div className="val">{rec.serves}<span className="u">people</span></div></div>
        </div>

        {rec.vitamins && <>
          <div className="sb-section-lbl"><Icon name="leaf" size={12} stroke={2.4} /> Vitamins &amp; minerals</div>
          <p style={{ fontSize: 12.5, color: "var(--gray-700)", margin: "0 0 12px", lineHeight: 1.55 }}>{rec.vitamins}</p>
        </>}

        <div className="sb-section-lbl"><Icon name="shield-alert" size={12} stroke={2.4} /> Allergens</div>
        <div className="sb-tag-row">
          {rec.allergens.length === 0 ?
          <span className="sb-tag muted"><Icon name="check" size={11} stroke={2.6} /> No declared allergens</span> :
          rec.allergens.map((a) => <span key={a} className="sb-tag allergen"><Icon name="alert-triangle" size={11} stroke={2.6} /> {a}</span>)}
        </div>

        {rec.tags.length > 0 && <>
          <div className="sb-section-lbl"><Icon name="tag" size={12} stroke={2.4} /> Health tags</div>
          <div className="sb-tag-row">
            {rec.tags.map((t, i) => <span key={i} className="sb-tag health"><Icon name="check" size={11} stroke={2.6} /> {t}</span>)}
          </div>
        </>}

        {ings.length > 0 && <>
          <div className="sb-section-lbl"><Icon name="list" size={12} stroke={2.4} /> Ingredients ({ings.length})</div>
          <ol className="sb-recipe-ings" style={{ paddingLeft: 20, margin: 0 }}>
            {ings.map((it, i) => <li key={i}>{it}</li>)}
          </ol>
        </>}

        <div className="sb-source">
          <Icon name="file-check" size={14} stroke={2.4} />
          <div>
            <strong>NutriDMS Recipe DB · RDN-approved</strong><br />
            {rec.source ? <a href={rec.source} target="_blank" rel="noreferrer">{rec.source}</a> : "Internal recipe"}
          </div>
        </div>
      </div>
    </div>);

}

/* ─── Beverage response card ─── */
function BeverageCard({ bev }) {
  if (!bev) return null;
  const n = bev.nutrition_per_serving;
  return (
    <div className="sb-result">
      <div className="sb-hero-photo">
        <span className="em">{bev.emoji}</span>
        <span className="badge"><Icon name="check-circle-2" size={11} stroke={2.6} /> RDN Approved</span>
        <div className="meta">
          <span className="chip"><Icon name="droplet" size={10} stroke={2.4} /> {bev.serving_ml}ml</span>
          <span className="chip"><Icon name="clock" size={10} stroke={2.4} /> {bev.prep_time_min || 5} min</span>
          <span className="chip">{bev.type}</span>
        </div>
      </div>
      <div className="sb-result-head">
        <div className="emoji-tile">{bev.emoji}</div>
        <div className="nm">
          <h3>{bev.name}</h3>
          <div className="sub"><strong>{bev.id}</strong> · {bev.type} · {bev.texture}</div>
        </div>
        <VerifyBadge status={bev.verification} />
      </div>
      <div className="sb-result-body">
        {bev.description && <p style={{ fontSize: 13, color: "var(--gray-700)", margin: "0 0 14px", lineHeight: 1.55 }}>{bev.description}</p>}

        <div className="sb-section-lbl"><Icon name="activity" size={12} stroke={2.4} /> Per {bev.serving_ml}ml serving</div>
        <div className="sb-nutr-grid">
          <div className="sb-nutr"><div className="lbl">Calories</div><div className="val">{n.calories_kcal}<span className="u">kcal</span></div></div>
          <div className="sb-nutr"><div className="lbl">Protein</div><div className="val">{n.protein_g}<span className="u">g</span></div></div>
          <div className="sb-nutr"><div className="lbl">Carbs</div><div className="val">{n.carbs_g}<span className="u">g</span></div></div>
          <div className="sb-nutr"><div className="lbl">Sugar*</div><div className="val">{n.carbs_g ? Math.round(n.carbs_g * 0.7) : "—"}<span className="u">g</span></div></div>
          <div className="sb-nutr"><div className="lbl">Fat</div><div className="val">{n.fat_g}<span className="u">g</span></div></div>
          <div className="sb-nutr"><div className="lbl">Fiber</div><div className="val">{n.fiber_g}<span className="u">g</span></div></div>
        </div>

        {bev.benefits && <>
          <div className="sb-section-lbl"><Icon name="heart-pulse" size={12} stroke={2.4} /> Key benefits</div>
          <p style={{ fontSize: 12.5, color: "var(--gray-700)", margin: "0 0 12px", lineHeight: 1.55 }}>{bev.benefits}</p>
        </>}

        <div className="sb-section-lbl"><Icon name="shield-alert" size={12} stroke={2.4} /> Allergens</div>
        <div className="sb-tag-row">
          {bev.allergens.length === 0 ?
          <span className="sb-tag muted"><Icon name="check" size={11} stroke={2.6} /> Allergen-free</span> :
          bev.allergens.map((a) => <span key={a} className="sb-tag allergen"><Icon name="alert-triangle" size={11} stroke={2.6} /> {a}</span>)}
        </div>

        {bev.tags.length > 0 && <>
          <div className="sb-section-lbl"><Icon name="tag" size={12} stroke={2.4} /> Tags</div>
          <div className="sb-tag-row">
            {bev.tags.map((t, i) => <span key={i} className="sb-tag health">{t}</span>)}
          </div>
        </>}

        <div className="sb-source">
          <Icon name="file-check" size={14} stroke={2.4} />
          <div>
            <strong>NutriDMS Beverage DB · RDN-approved</strong><br />
            {bev.source ? <a href={bev.source} target="_blank" rel="noreferrer">{bev.source}</a> : "Internal beverage"}
          </div>
        </div>
      </div>
    </div>);

}

/* ─── Ingredient Tab ─── */
function IngredientTab() {
  const [query, setQuery] = useSbState("");
  const [selected, setSelected] = useSbState(DS.ingredients[0] || null);
  const [qty, setQty] = useSbState(100);
  const [unit, setUnit] = useSbState("g");
  const [view, setView] = useSbState("pretty");
  const matches = useSbMemo(() => {
    if (!query) return [];
    const q = query.toLowerCase();
    return DS.ingredients.filter((i) => i.name.toLowerCase().includes(q) || i.category.toLowerCase().includes(q)).slice(0, 8);
  }, [query]);

  const popular = useSbMemo(() => DS.ingredients.filter((i) => i.health_tags.length > 0).slice(0, 12), []);

  const request = {
    endpoint: "/v1/ingredients/lookup",
    method: "POST",
    mode: "sandbox",
    body: { ingredient_name: selected ? selected.name : "", quantity: qty, unit }
  };

  const factor = qty / 100;
  const response = selected ? {
    status: "success",
    mode: "sandbox",
    matched_ingredient: selected.canonical,
    ingredient_id: selected.id,
    verification_status: selected.verification,
    reviewed_by: "Registered Dietitian (RDN)",
    serving: { quantity: qty, unit },
    nutrition: Object.fromEntries(Object.entries(selected.nutrition_per_100g).map(([k, v]) => [k, v == null ? null : +(v * factor).toFixed(3)])),
    allergens: selected.allergens,
    health_tags: selected.health_tags,
    source: { db: "NutriDMS Master Ingredient Database", ref: selected.source_ref, url: selected.source }
  } : null;

  return (
    <div className="sb-grid">
      {/* Request panel */}
      <div className="sb-stage">
        <div className="sb-panel">
          <div className="sb-panel-head">
            <div className="t"><span className="method post">POST</span> /v1/ingredients/lookup</div>
            <span className="sb-mode-badge"><span className="dot" /> Sandbox mode</span>
          </div>
          <div className="sb-panel-body">
            <div className="sb-field">
              <label>Ingredient name <span className="opt">matched against the verified master DB</span></label>
              <div className="sb-search-wrap">
                <Icon name="search" size={14} stroke={2.2} className="ic" />
                <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search 250+ verified ingredients (e.g. chicken, onion, rice)…" />
                {query && <button className="clear" onClick={() => setQuery("")}><Icon name="x" size={13} stroke={2.4} /></button>}
                {matches.length > 0 &&
                <div className="sb-suggest">
                    {matches.map((m) =>
                  <button key={m.id} onClick={() => {setSelected(m);setQuery("");}}>
                        <span className="emoji">{m.emoji}</span>
                        <div>
                          <div style={{ fontWeight: 600 }}>{m.name}</div>
                          <div style={{ fontSize: 11, color: "var(--gray-500)" }}>{m.category} · {m.state}</div>
                        </div>
                        <span className="meta">{m.nutrition_per_100g.calories_kcal} kcal</span>
                      </button>
                  )}
                  </div>
                }
              </div>
            </div>

            <div className="sb-field">
              <label>Quantity &amp; unit</label>
              <div className="row" style={{ gridTemplateColumns: "1fr 1fr" }}>
                <input type="number" value={qty} onChange={(e) => setQty(+e.target.value || 0)} min={1} />
                <select value={unit} onChange={(e) => setUnit(e.target.value)}>
                  <option>g</option><option>kg</option><option>oz</option><option>lb</option>
                </select>
              </div>
            </div>

            <div className="sb-catalog-head">
              <h3>Popular verified ingredients</h3>
              <span style={{ fontSize: 11, color: "var(--gray-500)", fontWeight: 600 }}>Tap to test</span>
            </div>
            <div className="sb-catalog">
              {popular.map((p) =>
              <button key={p.id} className="sb-catalog-item" onClick={() => {setSelected(p);setQuery("");}}>
                  <span className="emoji">{p.emoji}</span>
                  <div className="nm">{p.name}</div>
                </button>
              )}
            </div>
          </div>
        </div>

        <div className="sb-panel">
          <div className="sb-panel-head">
            <div className="t"><Icon name="code" size={13} stroke={2.4} /> Request</div>
            <div className="actions">
              <button onClick={() => copyToClipboard(JSON.stringify(request, null, 2))}><Icon name="copy" size={12} stroke={2.4} /> Copy</button>
            </div>
          </div>
          <PrettyJson data={request} />
        </div>
      </div>

      {/* Response panel */}
      <div className="sb-stage">
        <div className="sb-panel">
          <div className="sb-panel-head">
            <div className="t"><Icon name="play-circle" size={13} stroke={2.4} /> Response · 200 OK <span style={{ color: "var(--gray-500)", fontWeight: 500, marginLeft: 6 }}>· 142ms</span></div>
            <div className="sb-view-toggle">
              <button className={view === "pretty" ? "on" : ""} onClick={() => setView("pretty")}><Icon name="layout-grid" size={11} stroke={2.4} /> Pretty</button>
              <button className={view === "json" ? "on" : ""} onClick={() => setView("json")}><Icon name="code" size={11} stroke={2.4} /> JSON</button>
              <button onClick={() => copyToClipboard(JSON.stringify(response, null, 2))}><Icon name="copy" size={11} stroke={2.4} /></button>
            </div>
          </div>
          {selected ?
          view === "pretty" ? <IngredientCard ing={selected} qty={qty} unit={unit} /> : <PrettyJson data={response} /> :

          <div className="sb-empty">
              <div className="ic"><Icon name="search" size={20} stroke={2.2} /></div>
              <h3>Pick an ingredient</h3>
              <p>Search for an ingredient or tap one from the popular list to see verified nutrition data.</p>
            </div>
          }
        </div>
      </div>
    </div>);

}

/* ─── Recipe Tab ─── */
function RecipeTab() {
  const [selected, setSelected] = useSbState(DS.recipes[0] || null);
  const [view, setView] = useSbState("pretty");
  const [query, setQuery] = useSbState("");
  const filtered = useSbMemo(() => {
    if (!query) return DS.recipes;
    const q = query.toLowerCase();
    return DS.recipes.filter((r) => r.name.toLowerCase().includes(q) || (r.tags || []).join(" ").toLowerCase().includes(q));
  }, [query]);
  const request = {
    endpoint: "/v1/recipes/analyze",
    method: "POST",
    mode: "sandbox",
    body: { recipe_id: selected ? selected.id : "" }
  };
  const response = selected ? {
    status: "success",
    mode: "sandbox",
    recipe_id: selected.id,
    name: selected.name,
    country: selected.country,
    verification_status: selected.verification,
    reviewed_by: "Registered Dietitian (RDN)",
    serves: selected.serves,
    serving_size_g: selected.serving_g,
    prep_time_min: selected.prep_time_min,
    cook_time_min: selected.cook_time_min,
    nutrition_per_serving: selected.nutrition_per_serving,
    vitamins_and_minerals: selected.vitamins,
    allergens: selected.allergens,
    health_tags: selected.tags,
    ingredients_count: (selected.ingredients_text || "").split(/[,•]/).length,
    source: selected.source
  } : null;

  return (
    <div className="sb-grid">
      <div className="sb-stage">
        <div className="sb-panel">
          <div className="sb-panel-head">
            <div className="t"><span className="method post">POST</span> /v1/recipes/analyze</div>
            <span className="sb-mode-badge"><span className="dot" /> Sandbox mode</span>
          </div>
          <div className="sb-panel-body">
            <div className="sb-field">
              <label>Recipe</label>
              <div className="sb-search-wrap">
                <Icon name="search" size={14} stroke={2.2} className="ic" />
                <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search Caribbean recipe library…" />
                {query && <button className="clear" onClick={() => setQuery("")}><Icon name="x" size={13} stroke={2.4} /></button>}
              </div>
            </div>

            <div className="sb-catalog-head">
              <h3>{DS.recipes.length} verified recipes</h3>
              <span style={{ fontSize: 11, color: "var(--gray-500)", fontWeight: 600 }}>Caribbean library</span>
            </div>
            <div className="sb-catalog" style={{ maxHeight: 460 }}>
              {filtered.map((r) =>
              <button key={r.id} className="sb-catalog-item" onClick={() => setSelected(r)} style={{ borderColor: selected?.id === r.id ? "var(--green-700)" : "" }}>
                  <span className="emoji">{r.emoji}</span>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div className="nm">{r.name}</div>
                    <div className="cat">{r.country} · {r.nutrition_per_serving.calories_kcal} kcal/serving</div>
                  </div>
                </button>
              )}
            </div>
          </div>
        </div>

        <div className="sb-panel">
          <div className="sb-panel-head">
            <div className="t"><Icon name="code" size={13} stroke={2.4} /> Request</div>
            <div className="actions">
              <button onClick={() => copyToClipboard(JSON.stringify(request, null, 2))}><Icon name="copy" size={12} stroke={2.4} /> Copy</button>
            </div>
          </div>
          <PrettyJson data={request} />
        </div>
      </div>

      <div className="sb-stage">
        <div className="sb-panel">
          <div className="sb-panel-head">
            <div className="t"><Icon name="play-circle" size={13} stroke={2.4} /> Response · 200 OK <span style={{ color: "var(--gray-500)", fontWeight: 500, marginLeft: 6 }}>· 386ms</span></div>
            <div className="sb-view-toggle">
              <button className={view === "pretty" ? "on" : ""} onClick={() => setView("pretty")}><Icon name="layout-grid" size={11} stroke={2.4} /> Pretty</button>
              <button className={view === "json" ? "on" : ""} onClick={() => setView("json")}><Icon name="code" size={11} stroke={2.4} /> JSON</button>
              <button onClick={() => copyToClipboard(JSON.stringify(response, null, 2))}><Icon name="copy" size={11} stroke={2.4} /></button>
            </div>
          </div>
          {selected ?
          view === "pretty" ? <RecipeCard rec={selected} /> : <PrettyJson data={response} /> :

          <div className="sb-empty">
              <div className="ic"><Icon name="chef-hat" size={20} stroke={2.2} /></div>
              <h3>Pick a recipe</h3>
              <p>Choose any verified recipe from the library to see calculated nutrition.</p>
            </div>
          }
        </div>
      </div>
    </div>);

}

/* ─── Beverage Tab ─── */
function BeverageTab() {
  const [selected, setSelected] = useSbState(DS.beverages[0] || null);
  const [view, setView] = useSbState("pretty");
  const [query, setQuery] = useSbState("");
  const filtered = useSbMemo(() => {
    if (!query) return DS.beverages;
    const q = query.toLowerCase();
    return DS.beverages.filter((b) => b.name.toLowerCase().includes(q) || b.type.toLowerCase().includes(q));
  }, [query]);

  const request = {
    endpoint: "/v1/beverages/analyze",
    method: "POST",
    mode: "sandbox",
    body: { beverage_id: selected ? selected.id : "" }
  };
  const response = selected ? {
    status: "success",
    mode: "sandbox",
    beverage_id: selected.id,
    name: selected.name,
    type: selected.type,
    verification_status: selected.verification,
    reviewed_by: "Registered Dietitian (RDN)",
    serving_ml: selected.serving_ml,
    yield_ml: selected.yield_ml,
    nutrition_per_serving: selected.nutrition_per_serving,
    vitamins_and_minerals: selected.vitamins,
    allergens: selected.allergens,
    tags: selected.tags,
    source: selected.source
  } : null;

  return (
    <div className="sb-grid">
      <div className="sb-stage">
        <div className="sb-panel">
          <div className="sb-panel-head">
            <div className="t"><span className="method post">POST</span> /v1/beverages/analyze</div>
            <span className="sb-mode-badge"><span className="dot" /> Sandbox mode</span>
          </div>
          <div className="sb-panel-body">
            <div className="sb-field">
              <label>Beverage</label>
              <div className="sb-search-wrap">
                <Icon name="search" size={14} stroke={2.2} className="ic" />
                <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search beverage library…" />
                {query && <button className="clear" onClick={() => setQuery("")}><Icon name="x" size={13} stroke={2.4} /></button>}
              </div>
            </div>

            <div className="sb-catalog-head">
              <h3>{DS.beverages.length} verified beverages</h3>
              <span style={{ fontSize: 11, color: "var(--gray-500)", fontWeight: 600 }}>Juices · smoothies · teas</span>
            </div>
            <div className="sb-catalog" style={{ maxHeight: 460 }}>
              {filtered.map((b) =>
              <button key={b.id} className="sb-catalog-item" onClick={() => setSelected(b)} style={{ borderColor: selected?.id === b.id ? "var(--green-700)" : "" }}>
                  <span className="emoji">{b.emoji}</span>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div className="nm">{b.name}</div>
                    <div className="cat">{b.type} · {b.nutrition_per_serving.calories_kcal} kcal/{b.serving_ml}ml</div>
                  </div>
                </button>
              )}
            </div>
          </div>
        </div>

        <div className="sb-panel">
          <div className="sb-panel-head">
            <div className="t"><Icon name="code" size={13} stroke={2.4} /> Request</div>
            <div className="actions">
              <button onClick={() => copyToClipboard(JSON.stringify(request, null, 2))}><Icon name="copy" size={12} stroke={2.4} /> Copy</button>
            </div>
          </div>
          <PrettyJson data={request} />
        </div>
      </div>

      <div className="sb-stage">
        <div className="sb-panel">
          <div className="sb-panel-head">
            <div className="t"><Icon name="play-circle" size={13} stroke={2.4} /> Response · 200 OK <span style={{ color: "var(--gray-500)", fontWeight: 500, marginLeft: 6 }}>· 198ms</span></div>
            <div className="sb-view-toggle">
              <button className={view === "pretty" ? "on" : ""} onClick={() => setView("pretty")}><Icon name="layout-grid" size={11} stroke={2.4} /> Pretty</button>
              <button className={view === "json" ? "on" : ""} onClick={() => setView("json")}><Icon name="code" size={11} stroke={2.4} /> JSON</button>
              <button onClick={() => copyToClipboard(JSON.stringify(response, null, 2))}><Icon name="copy" size={11} stroke={2.4} /></button>
            </div>
          </div>
          {selected ?
          view === "pretty" ? <BeverageCard bev={selected} /> : <PrettyJson data={response} /> :

          <div className="sb-empty">
              <div className="ic"><Icon name="droplet" size={20} stroke={2.2} /></div>
              <h3>Pick a beverage</h3>
              <p>Choose any beverage to test the /v1/beverages/analyze endpoint.</p>
            </div>
          }
        </div>
      </div>
    </div>);

}

/* ─── Sidebar ─── */
function SbSide({ tab, setTab, collapsed, setCollapsed }) {
  const endpoints = [
  { id: "ingredient", t: "Ingredient API", ic: "leaf", count: DS.ingredients.length, method: "POST" },
  { id: "recipe", t: "Recipe API", ic: "chef-hat", count: DS.recipes.length, method: "POST" },
  { id: "beverage", t: "Beverage API", ic: "droplet", count: DS.beverages.length, method: "POST" }];

  const soon = [
  { id: "allergen", t: "Allergen Detection", ic: "shield-alert" },
  { id: "nutrition", t: "Nutrition Calc", ic: "calculator" },
  { id: "compliance", t: "Compliance Score", ic: "shield-check" },
  { id: "labels", t: "Label Render", ic: "file-text" },
  { id: "audit", t: "Audit Log", ic: "file-clock" }];

  const help = [
  { id: "verify", t: "How data is verified", ic: "check-circle-2", href: "data-verification.html" },
  { id: "console", t: "API Console", ic: "layout-grid", href: "api-dashboard.html" },
  { id: "docs", t: "Documentation", ic: "book-open", href: "documentation.html" }];

  const Item = ({ it, disabled, badge }) =>
  <button className={`api-side-item ${tab === it.id ? "on" : ""}`} title={it.t} disabled={disabled} onClick={() => {if (it.href) {window.location.href = it.href;return;}if (disabled) return;setTab(it.id);}} style={disabled ? { opacity: .5, cursor: "not-allowed" } : {}}>
      <Icon name={it.ic} size={17} stroke={2} /> <span className="label">{it.t}</span>
      {it.count != null && <span className="count">{it.count}</span>}
      {badge && <span className="count" style={{ background: "rgba(245,158,11,.2)", color: "#FCC95C" }}>{badge}</span>}
    </button>;

  return (
    <aside className={`api-side ${collapsed ? "collapsed" : ""}`} style={{ borderRight: "1px solid #233028" }}>
      <div className="api-side-brand">
        {collapsed ?
        <img src="/brand/nutridms-mark.svg" alt="NutriDMS" width="28" height="28" style={{ display: "block", objectFit: "contain", margin: "0 auto" }} /> :
        <NutriHoriz height={32} forceTheme="dark" />}
        <button className="api-side-collapse" onClick={() => setCollapsed(!collapsed)} aria-label={collapsed ? "Expand sidebar" : "Collapse sidebar"} title={collapsed ? "Expand" : "Collapse"}>
          <Icon name={collapsed ? "chevrons-right" : "chevrons-left"} size={14} stroke={2.4} />
        </button>
      </div>
      <a href="screens/workspace.html" className="api-side-workspace" title="Switch workspace">
        <div className="icn">AP</div>
        <div className="meta">
          <div className="t">Acme, Production</div>
          <div className="s"><span className="dot" /> Sandbox · v1 API</div>
        </div>
        <Icon name="chevrons-up-down" size={13} stroke={2.4} />
      </a>
      <div className="api-side-section">
        <div className="label">Endpoints</div>
        {endpoints.map((it) => <Item key={it.id} it={it} />)}
      </div>
      <div className="api-side-section">
        <div className="label">Coming soon</div>
        {soon.map((it) => <Item key={it.id} it={it} disabled badge="Soon" />)}
      </div>
      <div className="api-side-section">
        <div className="label">Help</div>
        {help.map((it) => <Item key={it.id} it={it} />)}
      </div>
      <div className="api-side-foot">
        <div className="api-side-account">
          <div className="avt" style={{ background: "linear-gradient(135deg,#FEC84B,#DC6803)", color: "#fff" }}>S</div>
          <div className="nm">
            <div className="t">Sandbox mode</div>
            <div className="s">No billing · v1 API</div>
          </div>
        </div>
      </div>
    </aside>);

}

/* ─── Shell ─── */
function SbShell() {
  const [tab, setTab] = useSbState("ingredient");
  const [collapsed, setCollapsed] = useSbState(() => localStorage.getItem("nutridms.sb.sidebar.collapsed") === "1");
  useSbEffect(() => {localStorage.setItem("nutridms.sb.sidebar.collapsed", collapsed ? "1" : "0");}, [collapsed]);
  const titleMap = { ingredient: "Ingredient API", recipe: "Recipe API", beverage: "Beverage API" };
  const endpointMap = { ingredient: "/v1/ingredients/lookup", recipe: "/v1/recipes/analyze", beverage: "/v1/beverages/analyze" };
  return (
    <AppCtx.Provider value={_SbCtx}>
      <div className={`api-app ${collapsed ? "side-collapsed" : ""}`}>
        <SbSide tab={tab} setTab={setTab} collapsed={collapsed} setCollapsed={setCollapsed} />
        <div>
          <div className="api-top">
            <div className="crumbs">API Sandbox <span style={{ opacity: .4 }}>/</span> <strong>{titleMap[tab]}</strong> <span style={{ opacity: .4, marginLeft: 6 }}>·</span> <span className="mono" style={{ marginLeft: 6, fontFamily: "ui-monospace,monospace", fontSize: 12, color: "var(--gray-500)" }}>{endpointMap[tab]}</span></div>
            <span className="sb-mode-badge" style={{ marginLeft: "auto" }}><span className="dot" /> Sandbox · no keys · no billing</span>
            <LangSwitch />
            <ThemeToggle />
            <a href="data-verification.html" className="btn ghost sm" title="How data is verified"><Icon name="shield-check" size={13} stroke={2.4} /></a>
            <a href="documentation.html#api" className="btn secondary sm"><Icon name="book-open" size={13} stroke={2.2} /> API Docs</a>
          </div>

          <div className="api-page">
            <div className="sb-page-head" style={{ marginBottom: 18 }}>
              <div>
                <h1>{titleMap[tab]}</h1>
                <p>Test the NutriDMS {titleMap[tab].toLowerCase()} with RDN-verified data. Switch endpoints in the sidebar; pretty-card or raw JSON in the response panel.</p>
              </div>
            </div>

            <div className="sb-banner" style={{ marginBottom: 18 }}>
              <div className="ic"><Icon name="shield-check" size={16} stroke={2.4} /></div>
              <div>
                <strong>RDN-verified data only.</strong> Every record below has been mapped to USDA / FDA references and reviewed by a Registered Dietitian. Suggestions, mappings, and edits go through our verification workflow before they're served by the API.
              </div>
            </div>

            {tab === "ingredient" && <IngredientTab />}
            {tab === "recipe" && <RecipeTab />}
            {tab === "beverage" && <BeverageTab />}
          </div>
        </div>
      </div>
    </AppCtx.Provider>);

}

function SbApp() {return <I18nProvider><SbShell /></I18nProvider>;}
ReactDOM.createRoot(document.getElementById("root")).render(<SbApp />);