// Florio Analytics — Shop tab (ported from js/pages/shop.js).
// Cosmetic-shop admin config, rebuilt in the new design kit. NOT range-based.
//
// Behaviour preserved exactly from the old vanilla page:
//   • Rarity prices — set a coin price for each rarity tier (saved to
//     appConfig/shop.rarityPrices)
//   • Item rarities — assign a rarity to each catalog item (saved to
//     appConfig/shop.itemRarities); price is derived from rarity
//   • Weekly shop — pick 6 items for "this week" + "next week", each item must
//     have a rarity (and that rarity must have a price). Saved to
//     appConfig/shop.weeks[mondayStr] = [{ itemId, slot, rarity, price }]
//   • Item picker modal (dedupes items already used in that week)
//
// Reads/writes the SAME Firestore doc the old page used (appConfig/shop) via
// window.FlorioDB: { db, doc, getDoc, setDoc }.
(function () {
  const NS = window.HyperChartsDesignSystem_e51a95;
  const I = window.HyperIcons;
  const { useState, useEffect, useRef } = React;

  // ─── Item Catalog (verbatim from shop.js) ──────────────────────────────────
  const ITEMS = [
    { id: "BirdNestHat",          label: "Bird Nest",        slot: "hatwearEnum",   img: "birdNestHat.png" },
    { id: "LilyPadHat",           label: "Lily Pad",         slot: "hatwearEnum",   img: "lilyPadHat.png" },
    { id: "TulipHat",             label: "Tulip",            slot: "hatwearEnum",   img: "RoseBulbHat.png" },
    { id: "CloudHat",             label: "Cloud",            slot: "hatwearEnum",   img: "Cloud.png" },
    { id: "TopHat",               label: "Top Hat",          slot: "hatwearEnum",   img: "TopHat.png" },
    { id: "TrafficConeHat",       label: "Traffic Cone",     slot: "hatwearEnum",   img: "TrafficConeHat.png" },
    { id: "Beanie",               label: "Beanie",           slot: "hatwearEnum",   img: "Beanie.png" },
    { id: "StrawHat",             label: "Straw Hat",        slot: "hatwearEnum",   img: "StrawHat.png" },
    { id: "GraduationHat",        label: "Graduation",       slot: "hatwearEnum",   img: "GraduationCap.png" },
    { id: "SkiGoggles",           label: "Ski Goggles",      slot: "eyewearEnum",   img: "SkiGoggles.png" },
    { id: "LedGlasses",           label: "LED Glasses",      slot: "eyewearEnum",   img: "NeonGlasses.png" },
    { id: "SunGlasses",           label: "Sunglasses",       slot: "eyewearEnum",   img: "sunglasses.png" },
    { id: "SnorkelGlasses",       label: "Snorkel",          slot: "eyewearEnum",   img: "snorkelGlasses.png" },
    { id: "AviationGlasses",      label: "Aviation",         slot: "eyewearEnum",   img: "aviationGlasses.png" },
    { id: "ComicDisquiseGlasses", label: "Comic Disguise",   slot: "eyewearEnum",   img: "ComicDisguiseGlasses.png" },
    { id: "PixelGlasses",         label: "Pixel",            slot: "eyewearEnum",   img: "PixelGlasses.png" },
    { id: "monacle",              label: "Monocle",          slot: "eyewearEnum",   img: "Monacle.png" },
    { id: "VrHeadset",            label: "VR Headset",       slot: "eyewearEnum",   img: "VRHeadset.png" },
    { id: "GoldenBracelet",       label: "Golden",           slot: "jewelleryEnum", img: "GoldenBracelet.png" },
    { id: "LedBracelet",          label: "LED",              slot: "jewelleryEnum", img: "Led-bracelet.png" },
    { id: "SnakeBracelet",        label: "Snake",            slot: "jewelleryEnum", img: "SnakeBracelet.png" },
    { id: "VineBracelet",         label: "Vine",             slot: "jewelleryEnum", img: "VineBracelet.png" },
    { id: "BeadBracelet",         label: "Bead",             slot: "jewelleryEnum", img: "BeadBracelet.png" },
    { id: "WaterBracelet",        label: "Water",            slot: "jewelleryEnum", img: "WaterBracelet.png" },
    { id: "NeonPants",            label: "Neon",             slot: "lowerBodyEnum", img: "neonPants.png" },
    { id: "LeopardSwimmingPants", label: "Leopard",          slot: "lowerBodyEnum", img: "LeopardSwimmingPants.png" },
    { id: "Diaper",               label: "Diaper",           slot: "lowerBodyEnum", img: "Diaper.png" },
    { id: "OrangeSwimmingPants",  label: "Orange Swimming",  slot: "lowerBodyEnum", img: "orangeSwimPants.png" },
  ];

  // The old page lives at js/pages/ → uses "../assets/...". This tab lives in
  // app/ (one level deeper than index.html's root sibling), so prepend one more
  // "../" so the path still resolves to the web-root assets dir.
  const IMG_BASE = "../../assets/images/store/";
  const ITEM_MAP = {};
  for (const item of ITEMS) ITEM_MAP[item.id] = item;

  const SLOT_LABELS = {
    hatwearEnum: "Hats",
    eyewearEnum: "Eyewear",
    jewelleryEnum: "Jewellery",
    lowerBodyEnum: "Pants",
  };
  const SLOT_KEYS = Object.keys(SLOT_LABELS);

  const RARITIES = [
    { id: "common",    label: "Common",    color: "#8E8E93" },
    { id: "uncommon",  label: "Uncommon",  color: "#34C759" },
    { id: "rare",      label: "Rare",      color: "#007AFF" },
    { id: "epic",      label: "Epic",      color: "#AF52DE" },
    { id: "legendary", label: "Legendary", color: "#FF9500" },
  ];
  const RARITY_MAP = {};
  for (const r of RARITIES) RARITY_MAP[r.id] = r;

  // ─── Date helpers (verbatim logic from shop.js) ────────────────────────────
  function getMonday(date) {
    const d = new Date(date);
    const day = d.getDay();
    const diff = d.getDate() - day + (day === 0 ? -6 : 1);
    d.setDate(diff);
    return d;
  }
  function fmtDate(d) {
    return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
  }
  function fmtWeekRange(mondayStr) {
    const mon = new Date(mondayStr + "T00:00:00");
    const sun = new Date(mon); sun.setDate(sun.getDate() + 6);
    const m = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
    return `${m[mon.getMonth()]} ${mon.getDate()} – ${m[sun.getMonth()]} ${sun.getDate()}`;
  }

  const currentWeek = fmtDate(getMonday(new Date()));
  const _nextMon = getMonday(new Date()); _nextMon.setDate(_nextMon.getDate() + 7);
  const nextWeek = fmtDate(_nextMon);

  const FB = () => window.FlorioDB;

  // ─── Small presentational helpers ──────────────────────────────────────────

  function InlineStatus({ status }) {
    if (!status || !status.msg) return null;
    const ok = status.type === "ok";
    return (
      <span style={{
        fontFamily: "var(--font-mono)", fontSize: 12, fontWeight: 600,
        color: ok ? "var(--app-accent)" : "var(--negative)",
        marginLeft: 12,
      }}>{status.msg}</span>
    );
  }

  function SaveButton({ onClick, children, disabled }) {
    return (
      <button onClick={onClick} disabled={disabled} style={{
        fontFamily: "var(--font-sans)", fontWeight: 700, fontSize: 13,
        color: "#fff", border: "none", borderRadius: "var(--radius-md)",
        background: disabled ? "var(--text-muted)" : "var(--app-accent)",
        padding: "9px 18px", cursor: disabled ? "default" : "pointer",
        opacity: disabled ? 0.6 : 1,
      }}>{children}</button>
    );
  }

  function ItemImg({ img, label, size = 52 }) {
    const [err, setErr] = useState(false);
    if (err) {
      return (
        <div style={{
          width: size, height: size, borderRadius: 10, display: "grid",
          placeItems: "center", background: "var(--surface-sunken)", color: "var(--text-muted)",
        }}>{I.grid ? I.grid({ size: Math.round(size * 0.4) }) : null}</div>
      );
    }
    return (
      <img src={IMG_BASE + img} alt={label} onError={() => setErr(true)}
        style={{ width: size, height: size, objectFit: "contain" }} />
    );
  }

  function RarityTag({ rarity, children }) {
    const ro = RARITY_MAP[rarity];
    if (!ro) return null;
    return (
      <span style={{
        fontFamily: "var(--font-mono)", fontSize: 10, fontWeight: 700, color: "#fff",
        background: ro.color, borderRadius: 99, padding: "2px 8px", whiteSpace: "nowrap",
      }}>{children != null ? children : ro.label}</span>
    );
  }

  // ─── Main component ─────────────────────────────────────────────────────────
  function Shop() {
    // shopData mirrors appConfig/shop. null === loading.
    const [shopData, setShopData] = useState(null);
    const [loadError, setLoadError] = useState(false);

    // local editable state
    const [prices, setPrices] = useState({});          // { rarityId: number }
    const [itemRarities, setItemRarities] = useState({}); // { itemId: rarityId }
    const [weekItems, setWeekItems] = useState({ current: [], next: [] }); // arrays of itemId|null (len 6)

    // per-section status messages
    const [statusPrices, setStatusPrices] = useState(null);
    const [statusRarities, setStatusRarities] = useState(null);
    const [statusWeek, setStatusWeek] = useState({ current: null, next: null });

    // item picker modal
    const [picker, setPicker] = useState(null); // { prefix, index } | null

    const statusTimers = useRef({});
    function flashStatus(setter, key, msg, type) {
      setter(key ? (prev) => ({ ...prev, [key]: { msg, type } }) : { msg, type });
      const tk = (key || "") + "_" + (setter.name || Math.random());
      if (statusTimers.current[tk]) clearTimeout(statusTimers.current[tk]);
      statusTimers.current[tk] = setTimeout(() => {
        setter(key ? (prev) => ({ ...prev, [key]: null }) : null);
      }, 4000);
    }

    useEffect(() => {
      let alive = true;
      (async () => {
        await window.FlorioReady;
        const { db, doc, getDoc } = FB();
        let data = {};
        try {
          const snap = await getDoc(doc(db, "appConfig", "shop"));
          data = snap.exists() ? (snap.data() || {}) : {};
        } catch (e) {
          console.error("[Shop] load failed:", e);
          if (!alive) return;
          setLoadError(true);
          data = {};
        }
        if (!alive) return;

        // hydrate local editable state
        const rp = data.rarityPrices || {};
        const np = {};
        for (const r of RARITIES) if (rp[r.id]) np[r.id] = rp[r.id];
        setPrices(np);

        setItemRarities({ ...(data.itemRarities || {}) });

        const hydrateWeek = (mondayStr) => {
          const arr = new Array(6).fill(null);
          const list = data.weeks && data.weeks[mondayStr];
          if (Array.isArray(list)) {
            for (let i = 0; i < Math.min(list.length, 6); i++) {
              const wi = list[i];
              if (wi && wi.itemId && ITEM_MAP[wi.itemId]) arr[i] = wi.itemId;
            }
          }
          return arr;
        };
        setWeekItems({ current: hydrateWeek(currentWeek), next: hydrateWeek(nextWeek) });

        setShopData(data);
      })();
      return () => { alive = false; };
    }, []);

    // ── Save: rarity prices ──
    async function saveRarityPrices() {
      const out = {};
      for (const r of RARITIES) {
        const val = parseInt(prices[r.id], 10);
        if (!val || val <= 0) {
          flashStatus(setStatusPrices, null, `Set a price for ${r.label}`, "err");
          return;
        }
        out[r.id] = val;
      }
      try {
        const { db, doc, setDoc } = FB();
        await setDoc(doc(db, "appConfig", "shop"), { rarityPrices: out }, { merge: true });
        setShopData((p) => ({ ...(p || {}), rarityPrices: out }));
        flashStatus(setStatusPrices, null, "Saved", "ok");
      } catch (e) {
        flashStatus(setStatusPrices, null, "Failed: " + e.message, "err");
      }
    }

    // ── Save: item rarities ──
    async function saveItemRarities() {
      const out = {};
      for (const item of ITEMS) {
        if (itemRarities[item.id]) out[item.id] = itemRarities[item.id];
      }
      try {
        const { db, doc, setDoc } = FB();
        await setDoc(doc(db, "appConfig", "shop"), { itemRarities: out }, { merge: true });
        setShopData((p) => ({ ...(p || {}), itemRarities: out }));
        flashStatus(setStatusRarities, null, `Saved ${Object.keys(out).length} items`, "ok");
      } catch (e) {
        flashStatus(setStatusRarities, null, "Failed: " + e.message, "err");
      }
    }

    // ── Save: a week column ──
    async function saveWeek(prefix, mondayStr) {
      const slots = weekItems[prefix] || [];
      const items = [];
      for (let i = 0; i < 6; i++) {
        const itemId = slots[i];
        if (!itemId) continue;
        const itemInfo = ITEM_MAP[itemId];
        const rarity = itemRarities[itemId];
        if (!rarity) {
          flashStatus(setStatusWeek, prefix, `"${(itemInfo && itemInfo.label) || itemId}" has no rarity set`, "err");
          return;
        }
        const price = prices[rarity];
        if (!price) {
          flashStatus(setStatusWeek, prefix, `No price set for ${rarity} rarity`, "err");
          return;
        }
        items.push({ itemId, slot: itemInfo.slot, rarity, price });
      }
      if (items.length === 0) {
        flashStatus(setStatusWeek, prefix, "Add at least one item", "err");
        return;
      }
      try {
        const { db, doc, setDoc } = FB();
        const weeks = { ...((shopData && shopData.weeks) || {}) };
        weeks[mondayStr] = items;
        await setDoc(doc(db, "appConfig", "shop"), { currentWeek, nextWeek, weeks }, { merge: true });
        setShopData((p) => ({ ...(p || {}), weeks, currentWeek, nextWeek }));
        flashStatus(setStatusWeek, prefix, `Saved ${items.length} items`, "ok");
      } catch (e) {
        flashStatus(setStatusWeek, prefix, "Failed: " + e.message, "err");
      }
    }

    // ── Week slot mutations ──
    function fillSlot(prefix, index, itemId) {
      setWeekItems((p) => {
        const next = { ...p, [prefix]: [...p[prefix]] };
        next[prefix][index] = itemId;
        return next;
      });
    }
    function clearSlot(prefix, index) {
      setWeekItems((p) => {
        const next = { ...p, [prefix]: [...p[prefix]] };
        next[prefix][index] = null;
        return next;
      });
    }

    // ── Loading state ──
    if (!shopData) {
      return (
        <div style={{ display: "grid", placeItems: "center", minHeight: "60vh" }}>
          <div className="pa-spin" style={{ width: 38, height: 38, borderRadius: "50%", border: "3px solid var(--border-default)", borderTopColor: "var(--app-accent)" }} />
        </div>
      );
    }

    const P = window.PA;

    return (
      <div style={{ display: "grid", gridTemplateColumns: "repeat(12, minmax(0,1fr))", gap: 20 }}>
        {loadError && (
          <div style={{
            gridColumn: "span 12", background: "color-mix(in srgb, var(--negative) 10%, transparent)",
            border: "1px solid var(--negative)", borderRadius: "var(--radius-md)", padding: "12px 16px",
            fontFamily: "var(--font-sans)", fontSize: 13, color: "var(--negative)",
          }}>Couldn't load the saved shop config — starting from a blank config. Saving will overwrite.</div>
        )}

        {/* ── Section 1: Rarity prices ── */}
        <P.ChartCard title="Rarity Prices" eyebrow="Set the coin price for each rarity tier" span={12}>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))", gap: 14 }}>
            {RARITIES.map((r) => (
              <div key={r.id} style={{
                display: "flex", alignItems: "center", gap: 10, padding: "12px 14px",
                background: "var(--surface-sunken)", borderRadius: "var(--radius-md)", border: "1px solid var(--border-subtle)",
              }}>
                <span style={{ width: 12, height: 12, borderRadius: "50%", background: r.color, flexShrink: 0 }} />
                <span style={{ fontFamily: "var(--font-sans)", fontWeight: 600, fontSize: 13, color: "var(--text-primary)", flex: 1 }}>{r.label}</span>
                <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                  <span style={{ display: "flex", color: "#FF9500" }}>{I.coin ? I.coin({ size: 16 }) : "🪙"}</span>
                  <input type="number" min="1" max="9999" placeholder="0"
                    value={prices[r.id] != null ? prices[r.id] : ""}
                    onChange={(e) => setPrices((p) => ({ ...p, [r.id]: e.target.value }))}
                    style={{
                      width: 70, fontFamily: "var(--font-mono)", fontSize: 14, fontWeight: 700,
                      textAlign: "right", color: "var(--text-primary)", border: "1px solid var(--border-default)",
                      borderRadius: 8, padding: "6px 8px", background: "var(--surface-card)",
                    }} />
                </div>
              </div>
            ))}
          </div>
          <div style={{ marginTop: 18, display: "flex", alignItems: "center" }}>
            <SaveButton onClick={saveRarityPrices}>Save Prices</SaveButton>
            <InlineStatus status={statusPrices} />
          </div>
        </P.ChartCard>

        {/* ── Section 2: Item rarities ── */}
        <P.ChartCard title="Item Rarities" eyebrow="Assign a rarity to each item — price is determined by rarity" span={12}>
          {SLOT_KEYS.map((slot) => {
            const items = ITEMS.filter((i) => i.slot === slot);
            return (
              <div key={slot} style={{ marginBottom: 22 }}>
                <div style={{
                  fontFamily: "var(--font-mono-display)", fontSize: 10, letterSpacing: ".14em",
                  textTransform: "uppercase", color: "var(--text-muted)", marginBottom: 12,
                }}>{SLOT_LABELS[slot]}</div>
                <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(150px, 1fr))", gap: 12 }}>
                  {items.map((item) => {
                    const sel = itemRarities[item.id];
                    const selObj = sel ? RARITY_MAP[sel] : null;
                    return (
                      <div key={item.id} style={{
                        display: "flex", flexDirection: "column", alignItems: "center", gap: 8, padding: 12,
                        borderRadius: "var(--radius-md)", border: "1px solid " + (selObj ? selObj.color : "var(--border-subtle)"),
                        background: selObj ? "color-mix(in srgb, " + selObj.color + " 9%, var(--surface-card))" : "var(--surface-card)",
                      }}>
                        <ItemImg img={item.img} label={item.label} size={52} />
                        <span style={{ fontFamily: "var(--font-sans)", fontWeight: 600, fontSize: 12, color: "var(--text-primary)", textAlign: "center" }}>{item.label}</span>
                        <div style={{ display: "flex", gap: 6 }}>
                          {RARITIES.map((r) => {
                            const active = sel === r.id;
                            return (
                              <button key={r.id} title={r.label}
                                onClick={() => setItemRarities((p) => ({ ...p, [item.id]: r.id }))}
                                style={{
                                  width: 18, height: 18, borderRadius: "50%", padding: 0, cursor: "pointer",
                                  background: r.color, border: active ? "2px solid var(--text-primary)" : "2px solid transparent",
                                  boxShadow: active ? "0 0 0 2px var(--surface-card)" : "none",
                                  opacity: active ? 1 : 0.55,
                                }} />
                            );
                          })}
                        </div>
                        <span style={{ fontFamily: "var(--font-mono)", fontSize: 10, fontWeight: 700, color: selObj ? selObj.color : "var(--text-muted)", minHeight: 13 }}>
                          {selObj ? selObj.label : ""}
                        </span>
                      </div>
                    );
                  })}
                </div>
              </div>
            );
          })}
          <div style={{ display: "flex", alignItems: "center" }}>
            <SaveButton onClick={saveItemRarities}>Save Rarities</SaveButton>
            <InlineStatus status={statusRarities} />
          </div>
        </P.ChartCard>

        {/* ── Section 3: Weekly shop ── */}
        <P.ChartCard title="Weekly Shop" eyebrow="Pick 6 items for each week" span={12}>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(320px, 1fr))", gap: 20 }}>
            {[
              { prefix: "current", monday: currentWeek, title: "This Week" },
              { prefix: "next", monday: nextWeek, title: "Next Week" },
            ].map((col) => (
              <div key={col.prefix} style={{
                border: "1px solid var(--border-subtle)", borderRadius: "var(--radius-md)", padding: 16,
                background: "var(--surface-sunken)",
              }}>
                <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", marginBottom: 14, gap: 12 }}>
                  <div>
                    <div style={{ fontFamily: "var(--font-sans)", fontWeight: 700, fontSize: 15, color: "var(--text-primary)" }}>{col.title}</div>
                    <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--text-muted)", marginTop: 2 }}>{fmtWeekRange(col.monday)}</div>
                  </div>
                  <div style={{ display: "flex", alignItems: "center" }}>
                    <SaveButton onClick={() => saveWeek(col.prefix, col.monday)}>Save</SaveButton>
                  </div>
                </div>
                {statusWeek[col.prefix] && statusWeek[col.prefix].msg && (
                  <div style={{ marginBottom: 10 }}><InlineStatus status={statusWeek[col.prefix]} /></div>
                )}
                <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 10 }}>
                  {Array.from({ length: 6 }).map((_, i) => {
                    const itemId = weekItems[col.prefix][i];
                    const item = itemId ? ITEM_MAP[itemId] : null;
                    const rarity = item ? itemRarities[itemId] : null;
                    if (!item) {
                      return (
                        <button key={i} onClick={() => setPicker({ prefix: col.prefix, index: i })}
                          style={{
                            aspectRatio: "1 / 1", borderRadius: "var(--radius-md)", cursor: "pointer",
                            border: "1.5px dashed var(--border-default)", background: "var(--surface-card)",
                            color: "var(--text-muted)", fontSize: 26, fontWeight: 300,
                            display: "grid", placeItems: "center",
                          }}>+</button>
                      );
                    }
                    return (
                      <div key={i} style={{
                        position: "relative", aspectRatio: "1 / 1", borderRadius: "var(--radius-md)",
                        border: "1px solid var(--border-subtle)", background: "var(--surface-card)",
                        display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 4, padding: 6,
                      }}>
                        <button onClick={(e) => { e.stopPropagation(); clearSlot(col.prefix, i); }}
                          style={{
                            position: "absolute", top: 4, right: 4, width: 20, height: 20, borderRadius: "50%",
                            border: "none", cursor: "pointer", background: "var(--surface-sunken)",
                            color: "var(--text-muted)", fontSize: 14, lineHeight: "18px", display: "grid", placeItems: "center",
                          }}>×</button>
                        <ItemImg img={item.img} label={item.label} size={44} />
                        <span style={{ fontFamily: "var(--font-sans)", fontWeight: 600, fontSize: 11, color: "var(--text-primary)", textAlign: "center" }}>{item.label}</span>
                        {rarity && <RarityTag rarity={rarity} />}
                      </div>
                    );
                  })}
                </div>
              </div>
            ))}
          </div>
        </P.ChartCard>

        {/* ── Item picker modal ── */}
        {picker && (
          <div onClick={(e) => { if (e.target === e.currentTarget) setPicker(null); }}
            style={{
              position: "fixed", inset: 0, zIndex: 1000, background: "rgba(0,0,0,.4)",
              display: "grid", placeItems: "center", padding: 24,
            }}>
            <div style={{
              width: "min(720px, 100%)", maxHeight: "82vh", overflowY: "auto",
              background: "var(--surface-card)", borderRadius: "var(--radius-2xl)",
              boxShadow: "var(--shadow-card)", border: "1px solid var(--border-subtle)", padding: 22,
            }}>
              <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 18 }}>
                <div style={{ fontFamily: "var(--font-sans)", fontWeight: 700, fontSize: 17, color: "var(--text-primary)" }}>Select Item</div>
                <button onClick={() => setPicker(null)} style={{
                  border: "none", background: "var(--surface-sunken)", color: "var(--text-secondary)",
                  width: 30, height: 30, borderRadius: "50%", cursor: "pointer", fontSize: 18, lineHeight: "28px",
                }}>×</button>
              </div>
              <PickerBody
                used={new Set((weekItems[picker.prefix] || []).filter(Boolean))}
                itemRarities={itemRarities}
                prices={prices}
                onPick={(itemId) => { fillSlot(picker.prefix, picker.index, itemId); setPicker(null); }}
              />
            </div>
          </div>
        )}
      </div>
    );
  }

  // ─── Picker body (grouped by slot, dedupes already-used items) ──────────────
  function PickerBody({ used, itemRarities, prices, onPick }) {
    return (
      <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
        {SLOT_KEYS.map((slot) => {
          const items = ITEMS.filter((i) => i.slot === slot);
          return (
            <div key={slot}>
              <div style={{
                fontFamily: "var(--font-mono-display)", fontSize: 10, letterSpacing: ".14em",
                textTransform: "uppercase", color: "var(--text-muted)", marginBottom: 10,
              }}>{SLOT_LABELS[slot]}</div>
              <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(110px, 1fr))", gap: 10 }}>
                {items.map((item) => {
                  const isUsed = used.has(item.id);
                  const rarity = itemRarities[item.id];
                  const ro = rarity ? RARITY_MAP[rarity] : null;
                  const price = rarity ? (prices[rarity] != null ? prices[rarity] : "?") : "?";
                  return (
                    <button key={item.id} disabled={isUsed}
                      onClick={() => { if (!isUsed) onPick(item.id); }}
                      style={{
                        display: "flex", flexDirection: "column", alignItems: "center", gap: 6, padding: 10,
                        borderRadius: "var(--radius-md)", border: "1px solid var(--border-subtle)",
                        background: "var(--surface-card)", cursor: isUsed ? "default" : "pointer",
                        opacity: isUsed ? 0.4 : 1,
                      }}>
                      <ItemImg img={item.img} label={item.label} size={44} />
                      <span style={{ fontFamily: "var(--font-sans)", fontWeight: 600, fontSize: 11, color: "var(--text-primary)", textAlign: "center" }}>{item.label}</span>
                      {ro && (
                        <RarityTag rarity={rarity}>
                          <span style={{ display: "inline-flex", alignItems: "center", gap: 3 }}>{price} {I.coin ? I.coin({ size: 10 }) : "🪙"}</span>
                        </RarityTag>
                      )}
                    </button>
                  );
                })}
              </div>
            </div>
          );
        })}
      </div>
    );
  }

  (window.FlorioTabs = window.FlorioTabs || {}).shop = Shop;
})();
