/* ============================================================
   ADORN — Shop / listing + Product Detail Page
   Category-aware selectors:
     · colour  — every product (named swatches + custom request)
     · size    — ONLY rings (US/UK), belts (inches/S–XXL),
                 headwear (optional fit). Everything else: none.
   ============================================================ */

/* ---------------- SHOP ---------------- */
function FilterGroup({ title, children, open = true }) {
  const [o, setO] = useState(open);
  return (
    <div className="fgroup">
      <button className="fgroup-h" onClick={() => setO(!o)}>
        <span>{title}</span><Icon name={o ? "minus" : "plus"} size={16} />
      </button>
      {o && <div className="fgroup-body">{children}</div>}
    </div>
  );
}

function ShopPage({ route, onNav }) {
  const { addToCart, toggleWish, wishlist } = useContext(RBCtx);
  const p0 = route.params || {};
  const [cat, setCat] = useState(p0.cat || null);
  const [sub, setSub] = useState(p0.sub || null);
  const [tag, setTag] = useState(p0.tag || null);
  const [editTitle, setEditTitle] = useState(p0.editTitle || null);
  const [maxPrice, setMaxPrice] = useState(80000);
  const [sort, setSort] = useState("featured");
  const [mobFilters, setMobFilters] = useState(false);

  useEffect(() => {
    const p = route.params || {};
    setCat(p.cat || null); setSub(p.sub || null); setTag(p.tag || null); setEditTitle(p.editTitle || null);
  }, [route]);

  let list = RB.PRODUCTS.filter((p) =>
    (!cat || p.cat === cat) &&
    (!sub || p.sub === sub) &&
    (!tag || (p.tags || []).includes(tag)) &&
    p.price <= maxPrice
  );
  if (sort === "low") list = [...list].sort((a, b) => a.price - b.price);
  if (sort === "high") list = [...list].sort((a, b) => b.price - a.price);
  if (sort === "new") list = [...list].sort((a, b) => (b.badge === "New" ? 1 : 0) - (a.badge === "New" ? 1 : 0));

  const clearAll = () => { setCat(null); setSub(null); setTag(null); setEditTitle(null); setMaxPrice(80000); };
  const heading = editTitle || sub || cat || "All Pieces";
  const activeCount = [cat, sub, tag].filter(Boolean).length;

  const Filters = () => (
    <>
      <FilterGroup title="Category">
        <button className={"fcheck" + (!cat ? " on" : "")} onClick={() => { setCat(null); setSub(null); }}>All categories</button>
        {RB.CATEGORIES.map((c) => (
          <button key={c} className={"fcheck" + (cat === c ? " on" : "")} onClick={() => { setCat(c); setSub(null); }}>{c}</button>
        ))}
      </FilterGroup>
      {cat === "Jewellery" && (
        <FilterGroup title="Jewellery type">
          <button className={"fcheck" + (!sub ? " on" : "")} onClick={() => setSub(null)}>All jewellery</button>
          {RB.JEWELLERY_TYPES.map((s) => (
            <button key={s} className={"fcheck" + (sub === s ? " on" : "")} onClick={() => setSub(s)}>{s}</button>
          ))}
        </FilterGroup>
      )}
      <FilterGroup title="Price">
        <div className="price-range">
          <input type="range" min="5000" max="80000" step="2500" value={maxPrice} onChange={(e) => setMaxPrice(+e.target.value)} />
          <div className="spread" style={{ fontSize: 13, color: "var(--ink-soft)" }}>
            <span>Up to</span><Price ngn={maxPrice} alt={false} />
          </div>
        </div>
      </FilterGroup>
    </>
  );

  return (
    <div className="fade-page shop-page">
      <div className="shop-hero">
        <div className="wrap-wide">
          <h1 className="serif shop-title">{heading}</h1>
        </div>
      </div>

      <div className="wrap-wide shop-body">
        <aside className="shop-filters">
          <div className="spread" style={{ marginBottom: 8 }}>
            <span className="eyebrow muted">Refine</span>
            {activeCount > 0 && <button className="clear-btn" onClick={clearAll}>Clear all</button>}
          </div>
          <Filters />
          <div className="filter-help">
            <Icon name="ruler" size={20} />
            <div><strong>Sizing, simplified.</strong><span>Only rings &amp; belts are sized — every guide lives on the piece itself.</span></div>
          </div>
        </aside>

        <div className="shop-main">
          <div className="shop-toolbar">
            <div className="active-chips">
              {cat && <button className="achip" onClick={() => { setCat(null); setSub(null); }}>{cat} <Icon name="close" size={13} /></button>}
              {sub && <button className="achip" onClick={() => setSub(null)}>{sub} <Icon name="close" size={13} /></button>}
              {tag && <button className="achip" onClick={() => { setTag(null); setEditTitle(null); }}>{editTitle || tag} <Icon name="close" size={13} /></button>}
            </div>
            <div className="row" style={{ gap: 12 }}>
              <button className="mob-filter-btn" onClick={() => setMobFilters(true)}><Icon name="menu" size={16} /> Filters{activeCount ? ` (${activeCount})` : ""}</button>
              <div className="sort-wrap">
                <label>Sort</label>
                <select className="sort-select" value={sort} onChange={(e) => setSort(e.target.value)}>
                  <option value="featured">Featured</option>
                  <option value="new">Newest</option>
                  <option value="low">Price: Low to High</option>
                  <option value="high">Price: High to Low</option>
                </select>
              </div>
            </div>
          </div>

          {list.length === 0 ? (
            <div className="shop-empty">
              <p className="serif" style={{ fontSize: 28 }}>No pieces match those filters.</p>
              <Btn variant="ghost" arrow={false} onClick={clearAll}>Clear filters</Btn>
            </div>
          ) : (
            <div className="product-grid shop-grid">
              {list.map((p, i) => (
                <Reveal key={p.id} delay={(i % 4) + 1}>
                  <ProductCard p={p} onNav={onNav} onAdd={addToCart} wished={wishlist.includes(p.id)} onWish={toggleWish} />
                </Reveal>
              ))}
            </div>
          )}

          <div className="shop-editorial">
            <div className="zoomable" style={{ overflow: "hidden", borderRadius: "var(--radius)" }}><Ph label="EDIT · STYLED LOOK" ratio="wide" /></div>
            <div className="shop-editorial-body">
              <h3 className="serif" style={{ fontSize: 30, fontWeight: 500, margin: "0 0 14px" }}>Start with one piece</h3>
              <button className="link-arrow" onClick={() => onNav("lookbook", {})}>Open the Lookbook</button>
            </div>
          </div>
        </div>
      </div>

      {mobFilters && (
        <div className="filter-drawer-wrap">
          <div className="scrim show" onClick={() => setMobFilters(false)} />
          <div className="filter-drawer">
            <div className="spread" style={{ marginBottom: 20 }}>
              <span className="serif" style={{ fontSize: 24 }}>Filters</span>
              <button className="ic-btn" onClick={() => setMobFilters(false)}><Icon name="close" /></button>
            </div>
            <Filters />
            <Btn block style={{ marginTop: 20 }} arrow={false} onClick={() => setMobFilters(false)}>Show {list.length} results</Btn>
          </div>
        </div>
      )}
    </div>
  );
}

/* ---------------- SIZE GUIDE MODAL (per sizing type) ---------------- */
function SizeGuide({ type, onClose }) {
  const GUIDES = {
    ring: {
      title: "Ring size guide",
      note: "Measure the inside diameter of a ring that fits, or wrap a strip of paper around the finger and measure against a ruler. Between sizes? Go up.",
      head: ["US", "UK", "Inside Ø"],
      rows: [["4", "H", "14.9 mm"], ["5", "J½", "15.7 mm"], ["6", "L½", "16.5 mm"], ["7", "N½", "17.3 mm"], ["8", "P½", "18.1 mm"], ["9", "R½", "19.0 mm"], ["10", "T½", "19.8 mm"], ["11", "V½", "20.6 mm"], ["12", "X½", "21.4 mm"], ["13", "Z½", "22.2 mm"]],
    },
    belt: {
      title: "Belt size guide",
      note: "Measure over the clothing you'll wear the belt with. Your belt size is roughly your trouser waist + 2 inches.",
      head: ["Letter", "Waist", "Length (cm)"],
      rows: [["S", "28–30\u2033", "85 cm"], ["M", "32–34\u2033", "95 cm"], ["L", "36–38\u2033", "105 cm"], ["XL", "40–42\u2033", "115 cm"], ["XXL", "44–46\u2033", "125 cm"]],
    },
    headwear: {
      title: "Headwear fit guide",
      note: "Measure around your head just above the ears and eyebrows. Most of our headwear is One Size with an internal adjuster.",
      head: ["Fit", "Circumference", "Best for"],
      rows: [["One Size", "56–58 cm", "Most adults"], ["S/M", "55–57 cm", "Smaller fit"], ["M/L", "58–60 cm", "Fuller fit"]],
    },
  };
  const g = GUIDES[type] || GUIDES.ring;
  return (
    <div className="modal-wrap" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <div className="spread" style={{ marginBottom: 18 }}>
          <div><h3 className="serif" style={{ fontSize: 28 }}>{g.title}</h3></div>
          <button className="ic-btn" onClick={onClose}><Icon name="close" /></button>
        </div>
        <table className="size-table">
          <thead><tr>{g.head.map((h) => <th key={h}>{h}</th>)}</tr></thead>
          <tbody>{g.rows.map((r) => <tr key={r[0]}>{r.map((c, i) => <td key={i}>{c}</td>)}</tr>)}</tbody>
        </table>
        <p style={{ fontSize: 13, color: "var(--ink-soft)", marginTop: 16 }}>{g.note}</p>
      </div>
    </div>
  );
}

/* ---------------- COLOUR SELECTOR ---------------- */
function ColorSelector({ p, color, setColor, onNav }) {
  const light = (hex) => {
    const n = parseInt(hex.slice(1), 16);
    return ((n >> 16 & 255) * 0.299 + (n >> 8 & 255) * 0.587 + (n & 255) * 0.114) > 186;
  };
  return (
    <div className="pdp-opt">
      <div className="spread">
        <span className="opt-label">Colour — <em className="opt-val">{color.name}{color.custom ? " (custom)" : ""}</em></span>
      </div>
      <div className="cswatch-row">
        {p.colors.map((c) => (
          <button key={c.name} className={"cswatch" + (color.name === c.name ? " on" : "") + (light(c.hex) ? " lite" : "")}
            style={{ background: c.hex }} onClick={() => setColor(c)} title={c.name} aria-label={c.name}>
            {color.name === c.name && <Icon name="check" size={13} />}
          </button>
        ))}
      </div>
      <button className="opt-link custom-color-link" onClick={() => onNav("contact", {})}>
        <Icon name="plus" size={13} /> Want another shade? Request a custom colour
      </button>
    </div>
  );
}

/* ---------------- SIZE SELECTOR (only for sized categories) ---------------- */
function SizeSelector({ sizing, scaleIdx, setScaleIdx, size, setSize, err, setErr, onGuide }) {
  const scale = sizing.scales[scaleIdx];
  return (
    <div className="pdp-opt">
      <div className="spread">
        <span className="opt-label">
          {sizing.label}{size ? <> — <em className="opt-val">{scale.fmt(size)}</em></> : ""}
          {!sizing.required && <span className="opt-optional">Optional</span>}
        </span>
        <button className="opt-link" onClick={onGuide}>Size guide</button>
      </div>
      {sizing.scales.length > 1 && (
        <div className="scale-toggle" role="group" aria-label="Size scale">
          {sizing.scales.map((s, i) => (
            <button key={s.id} className={"scale-btn" + (i === scaleIdx ? " on" : "")}
              onClick={() => { setScaleIdx(i); setSize(null); }}>{s.name}</button>
          ))}
        </div>
      )}
      <div className={"size-row" + (err ? " err" : "")} style={{ marginTop: 10 }}>
        {scale.sizes.map((s) => (
          <button key={s} className={"size-btn" + (size === s ? " on" : "")} onClick={() => { setSize(s); setErr(false); }}>{s}</button>
        ))}
      </div>
      {err && <span className="size-err">Please select a {sizing.label.toLowerCase()}</span>}
      {!sizing.required && <span className="size-hint">Leave unselected for the standard fit.</span>}
    </div>
  );
}

/* ---------------- PDP ---------------- */
function ProductPage({ route, onNav }) {
  const { addToCart, toggleWish, wishlist, openCart } = useContext(RBCtx);
  const p = RB.byId(route.params.id) || RB.PRODUCTS[0];
  const sizing = RB.SIZING[p.sizing] || null;
  const [scaleIdx, setScaleIdx] = useState(0);
  const [size, setSize] = useState(null);
  const [color, setColor] = useState(p.colors[0]);
  const [qty, setQty] = useState(1);
  const [activeImg, setActiveImg] = useState(0);
  const [acc, setAcc] = useState("details");
  const [showGuide, setShowGuide] = useState(false);
  const [err, setErr] = useState(false);

  useEffect(() => {
    setScaleIdx(0); setSize(null); setColor(p.colors[0]); setQty(1); setActiveImg(0); setErr(false); setAcc("details");
    window.scrollTo({ top: 0, behavior: "smooth" });
  }, [route.params.id]);

  const CAT = p.cat.toUpperCase();
  const imgs = [p.label, "DETAIL · " + CAT, "STYLED · " + CAT];
  const add = () => {
    if (sizing && sizing.required && !size) { setErr(true); return; }
    const sizeLabel = sizing && size ? sizing.scales[scaleIdx].fmt(size) : null;
    addToCart(p, { size: sizeLabel, color: color.name, qty });
    openCart();
  };

  const CARE = {
    "Bags": "Store stuffed, in its dust bag, away from direct sun. Wipe leather with a dry soft cloth; condition twice a year.",
    "Jewellery": "Keep dry — perfume and spray first, jewellery last. Store in the pouch provided and polish with the soft cloth included.",
    "Belts": "Roll, don't fold. Condition the leather lightly twice a year and keep buckles dry.",
    "Scarves": "Silk: cool hand-wash or dry-clean, iron on low from the reverse. Adire cotton: gentle hand-wash separately, first wash may release dye.",
    "Hair Accessories": "Spot-clean satin and silk with a damp cloth; air-dry away from heat.",
    "Wallets": "Wipe with a dry cloth. Leather deepens in colour with use — that's the point.",
    "Sunglasses": "Keep in the hard case provided. Clean lenses with the microfibre cloth only.",
    "Headwear": "Reshape by hand while dry. Raffia: keep dry; spot-clean canvas with mild soap.",
  };
  const pairs = RB.pairsWith(p, 3);
  const rel = RB.related(p, 4);

  return (
    <div className="fade-page pdp">
      <div className="wrap-wide pdp-grid">
        {/* gallery */}
        <div className="pdp-gallery">
          <div className="pdp-thumbs">
            {imgs.map((im, i) => (
              <button key={i} className={"pdp-thumb" + (activeImg === i ? " on" : "")} onClick={() => setActiveImg(i)}>
                <Ph label={im} ratio="portrait" />
              </button>
            ))}
          </div>
          <div className="pdp-main-img zoomable">
            {p.badge && <span className="pcard-tag" style={{ top: 18, left: 18 }}>{p.badge}</span>}
            <Ph label={imgs[activeImg]} ratio="tall" />
          </div>
        </div>

        {/* info */}
        <div className="pdp-info">
          <button className="pdp-crumb" onClick={() => onNav("shop", { cat: p.cat, sub: p.sub })}>{p.cat}{p.sub ? " · " + p.sub : ""}</button>
          <h1 className="serif pdp-title">{p.name}</h1>
          <div className="row" style={{ gap: 14, marginBottom: 16 }}>
            <Stars value={5} size={15} />
          </div>
          <div className="pdp-price"><Price ngn={p.price} old={p.oldPrice} /></div>
          <p className="pdp-blurb">{p.blurb}</p>

          <ColorSelector p={p} color={color} setColor={setColor} onNav={onNav} />

          {sizing && (
            <SizeSelector sizing={sizing} scaleIdx={scaleIdx} setScaleIdx={setScaleIdx}
              size={size} setSize={setSize} err={err} setErr={setErr} onGuide={() => setShowGuide(true)} />
          )}

          <div className="pdp-buy">
            <div className="qty">
              <button onClick={() => setQty(Math.max(1, qty - 1))}><Icon name="minus" size={15} /></button>
              <span>{qty}</span>
              <button onClick={() => setQty(qty + 1)}><Icon name="plus" size={15} /></button>
            </div>
            <Btn block arrow={false} onClick={add}>Add to bag — <Price ngn={p.price * qty} alt={false} /></Btn>
            <button className={"pdp-wish" + (wishlist.includes(p.id) ? " on" : "")} onClick={() => toggleWish(p.id)} aria-label="Wishlist">
              <Icon name={wishlist.includes(p.id) ? "star-f" : "heart"} size={20} />
            </button>
          </div>

          <div className="pdp-assure">
            {[["truck", "Ships from Lagos, worldwide"], ["spark", "Gift-wrapped as standard"], ["return", "7-day exchanges"]].map(([ic, t]) => (
              <div key={t} className="assure-item"><Icon name={ic} size={18} /><span>{t}</span></div>
            ))}
          </div>

          {/* accordions */}
          <div className="pdp-acc">
            {[
              ["details", "Details", <ul className="acc-list"><li>{p.blurb}</li><li>{p.material}</li><li>Checked by hand and gift-wrapped in our Lagos studio</li></ul>],
              ["care", "Material & Care", <div><p style={{ marginBottom: 10 }}><strong>{p.material}</strong></p><p style={{ color: "var(--ink-soft)" }}>{CARE[p.cat]}</p></div>],
              ["shipping", "Shipping & Returns", <div><p style={{ marginBottom: 8 }}>Lagos 1–2 days · nationwide 2–5 days · worldwide 5–12 days, tracked door-to-door. Free Lagos delivery over {RB.format((window.BRAND?.freeShipThreshold) || 150000, "NGN")}.</p><p style={{ color: "var(--ink-soft)" }}>Unworn pieces can be exchanged or returned within 7 days. Earrings are exchange-only for hygiene reasons.</p></div>],
            ].map(([k, label, body]) => (
              <div className={"acc-item" + (acc === k ? " open" : "")} key={k}>
                <button className="acc-h" onClick={() => setAcc(acc === k ? "" : k)}>{label}<Icon name={acc === k ? "minus" : "plus"} size={18} /></button>
                <div className="acc-body"><div className="acc-inner">{body}</div></div>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* pairs well with */}
      {pairs.length > 0 && (
        <section className="section-pad ctl-sec">
          <div className="wrap-wide">
            <div className="section-head" style={{ marginBottom: 40 }}>
              <div><h2 className="serif">Pairs well with</h2></div>
            </div>
            <div className="ctl-grid">
              <div className="ctl-hero zoomable"><Ph label={"STYLED · " + CAT} ratio="portrait" /></div>
              <div className="ctl-items">
                {[p, ...pairs].map((item, i) => {
                  const itemSizing = RB.SIZING[item.sizing];
                  const needsSize = itemSizing && itemSizing.required;
                  return (
                    <button key={item.id + i} className="ctl-item" onClick={() => i === 0 ? null : onNav("product", { id: item.id })}>
                      <Ph label={item.label} ratio="square" style={{ width: 78, height: 78 }} />
                      <div className="ctl-item-body">
                        <span className="pcard-cat">{i === 0 ? "This piece" : (item.sub || item.cat)}</span>
                        <span className="serif" style={{ fontSize: 19 }}>{item.name}</span>
                        <Price ngn={item.price} style={{ fontSize: 14, color: "var(--ink-soft)" }} />
                      </div>
                      {i !== 0 && (
                        <span className="ctl-add" onClick={(e) => {
                          e.stopPropagation();
                          if (needsSize) { onNav("product", { id: item.id }); return; }
                          addToCart(item, { color: item.colors[0].name });
                        }}>{needsSize ? "View" : "Add"}</span>
                      )}
                    </button>
                  );
                })}
              </div>
            </div>
          </div>
        </section>
      )}

      {/* related */}
      <FeaturedRow title="More to adore" products={rel} onNav={onNav} link={{ cat: p.cat }} />

      {showGuide && sizing && <SizeGuide type={p.sizing} onClose={() => setShowGuide(false)} />}
    </div>
  );
}

Object.assign(window, { ShopPage, ProductPage, SizeGuide });
