// Home, Shop, Product detail, Cart, Checkout, Confirmation
// Read shared things off `window`: VENDORS, PRODUCTS, CATEGORIES, Icon, ProductCard, ProductImage, Sprig, Logo

const { useState: useStateS, useEffect: useEffectS, useMemo: useMemoS, useRef: useRefS, useCallback: useCallbackS } = React;

// ─── HOME ───────────────────────────────────────────
function HomePage({ navigate, addToCart, events, products }) {
  const featured = useMemoS(() => {
    const TWO_WEEKS_MS = 14 * 24 * 60 * 60 * 1000;
    const recentlySold = (p) =>
      p.status === "sold" && p.sold_at &&
      (Date.now() - new Date(p.sold_at).getTime()) < TWO_WEEKS_MS;
    return (products || [])
      .filter((p) => p.featured && (p.status === "live" || recentlySold(p)))
      .sort((a, b) => (a.status === "sold" ? 1 : 0) - (b.status === "sold" ? 1 : 0) || a.featured - b.featured);
  }, [products]);
  const scrollerRef = useRefS(null);
  const scroll = (dir) => {
    const el = scrollerRef.current;
    if (!el) return;
    const amount = el.clientWidth * 0.6;
    el.scrollBy({ left: dir * amount, behavior: "smooth" });
  };

  // Upcoming live events, sorted ascending by date, capped at 4
  const upcomingEvents = useMemoS(() => {
    const today = new Date().toISOString().slice(0, 10);
    return (events || []).
    filter((e) => e.status === "live" && (e.date || "") >= today).
    sort((a, b) => (a.date || "").localeCompare(b.date || "")).
    slice(0, 4);
  }, [events]);

  return (
    <>
      {/* HERO */}
      <section className="hero">
        <video
          className="hero-video"
          src="assets/hero.mp4"
          autoPlay muted loop playsInline />
        
        <div className="hero-tint" />
        <div className="hero-content">
          <div className="hero-eyebrow"><span className="hero-eyebrow-line">Curated antiques</span> <span className="hero-eyebrow-sep">·</span> <span className="hero-eyebrow-loc">High Springs, Florida</span></div>
          <h1 className="hero-title">
            Yesterday's treasures<br />
            are <span style={{ color: "#f5e6c8" }}>today's pleasures</span>
          </h1>
          <p className="hero-sub">16 rooms, Six thousand square feet of carefully curated antiques and vintage — mid-century, garden iron, ceramics, jewelry, and everything in between.</p>
          <div className="hero-cta">
            <button className="btn btn-light-solid btn-lg" onClick={() => navigate({ page: "shop" })}>
              Shop Now
            </button>
            <button className="btn btn-light btn-lg" onClick={() => navigate({ page: "about" })}>
              Our Story
            </button>
          </div>
        </div>
        <div className="hero-scroll">
          <span>Scroll</span>
          <div className="hero-scroll-line" />
        </div>
      </section>

      {/* FEATURED — hidden when there are no featured products */}
      {featured.length > 0 &&
      <section className="section" style={{ paddingTop: 96 }}>
        <div className="container">
          <div className="section-head">
            <div>
              <span className="eyebrow">Newly arrived</span>
              <h2 className="serif italic">Featured Finds</h2>
            </div>
            <div className="carousel-nav">
              <button className="carousel-btn" onClick={() => scroll(-1)} aria-label="Previous"><Icon name="chevL" /></button>
              <button className="carousel-btn" onClick={() => scroll(1)} aria-label="Next"><Icon name="chevR" /></button>
              <button className="btn btn-ghost btn-sm" onClick={() => navigate({ page: "shop" })}>
                View all<Icon name="chevR" size={14} />
              </button>
            </div>
          </div>

          <div className="carousel">
            <div className="carousel-track" ref={scrollerRef}>
              {featured.map((p) =>
              <ProductCard key={p.id} product={p}
              onClick={() => navigate({ page: "product", id: p.id })} />
              )}
            </div>
          </div>
        </div>
      </section>
      }

      {/* ABOUT STRIP */}
      <section className="section" style={{ background: "var(--bg-alt)", padding: "96px 0" }}>
        <div className="container home-about-grid" style={{ display: "grid", gridTemplateColumns: "1fr 1.05fr", gap: "var(--s-8)", alignItems: "center" }}>
          {/* LEFT — storefront photo */}
          <div style={{
            aspectRatio: "5/6",
            borderRadius: "var(--radius)",
            overflow: "hidden",
            position: "relative",
            boxShadow: "0 30px 60px -30px rgba(0,0,0,0.4)"
          }}>
            <img src="assets/storefront.webp"
                 alt="Couple admiring the Decades on Main storefront at night"
                 style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", display: "block" }}/>
          </div>
          {/* RIGHT — text */}
          <div>
            <Sprig />
            <h2 className="serif italic" style={{ fontSize: 44, marginTop: 12, lineHeight: 1.05 }}>
              Twenty-plus years,<br />sixteen dealers,<br />endless treasures.
            </h2>
            <p style={{ fontSize: 18, lineHeight: 1.7, color: "var(--ink-soft)", marginTop: "var(--s-5)" }}>Decades on Main has been a quiet fixture in downtown High Springs for more than twenty years. Six thousand square feet under one roof — furniture, mid-century lighting, ceramics, jewelry, vintage toys, books, and everything in between, all chosen by dealers who actually love what they carry.





            </p>
            <p style={{ fontSize: 18, lineHeight: 1.7, color: "var(--ink-soft)" }}>
              Open six days a week. Come browse, bring a friend, take your time.
            </p>
            <div style={{ marginTop: 28, display: "flex", gap: 12, flexWrap: "wrap" }}>
              <button className="btn btn-outline" onClick={() => navigate({ page: "about" })}>Our story</button>
              <button className="btn btn-ghost" onClick={() => navigate({ page: "shop" })}>Browse the shop →</button>
            </div>
          </div>
        </div>
      </section>

      {/* EVENTS */}
      <section className="section">
        <div className="container">
          <div className="section-head">
            <div>
              <span className="eyebrow">Coming up at Decades</span>
              <h2 className="serif italic">Events & happenings</h2>
            </div>
            <button className="btn btn-ghost btn-sm" onClick={() => navigate({ page: "contact" })}>
              Got questions? <Icon name="chevR" size={14} />
            </button>
          </div>

          {upcomingEvents.length === 0 ?
          <div className="empty-state">
              <h3>Nothing on the calendar just yet</h3>
              <p>Check back soon, or follow along on Instagram for pop-ups.</p>
            </div> :

          <div className="events-grid">
              {upcomingEvents.map((ev) => <EventCard key={ev.id} event={ev} />)}
            </div>
          }
        </div>
      </section>

      {/* DISPATCH SIGNUP */}
      <section className="dispatch-section">
        <div className="container">
          <DispatchSignup />
        </div>
      </section>

    </>);

}

// ─── DECADES DISPATCH ───────────────────────────────
function DispatchSignup() {
  const [email, setEmail] = useStateS("");
  const [status, setStatus] = useStateS("idle");
  const [error, setError] = useStateS("");

  const submit = async (e) => {
    e.preventDefault();
    setError("");
    if (!email.trim()) { setError("Please enter your email."); return; }
    setStatus("busy");
    try {
      const r = await fetch("/api/unsubscribe", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email: email }),
      });
      const d = await r.json().catch(() => ({}));
      if (!r.ok) {
        setError(d.error || "Could not sign you up. Please try again.");
        setStatus("idle");
        return;
      }
      setStatus("done");
    } catch (e2) {
      setError("Could not reach the server. Please try again.");
      setStatus("idle");
    }
  };

  if (status === "done") {
    return (
      <div className="dispatch-thanks">
        <h2 className="serif italic">You're on the list.</h2>
        <p className="muted">We'll send a note when there's something worth sharing.</p>
      </div>);
  }

  return (
    <div className="dispatch-card">
      <span className="eyebrow">The Decades Dispatch</span>
      <h2 className="serif italic">Short notes from the store.</h2>
      <p className="dispatch-blurb">
        New arrivals, dealer features, the occasional Saturday porch concert.
        No spam — once a month, give or take.
      </p>
      <form className="dispatch-form" onSubmit={submit}>
        <input
          type="email"
          placeholder="you@example.com"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          required />
        <button className="btn btn-primary" type="submit" disabled={status === "busy"}>
          {status === "busy" ? "Signing up…" : "Sign me up"}
        </button>
      </form>
      {error && <p className="dispatch-error">{error}</p>}
    </div>);

}

// ─── EVENT CARD ─────────────────────────────────────
function EventCard({ event }) {
  // Parse YYYY-MM-DD -> { month: "JUN", day: "13", weekday: "SATURDAY" }
  const d = parseEventDate(event.date);
  const tagColors = {
    Sale: { bg: "var(--terracotta)", ink: "#fff" },
    Social: { bg: "var(--sage-dark)", ink: "#fff" },
    Consignment: { bg: "var(--gold)", ink: "#1f1a14" },
    Appraisal: { bg: "var(--ink)", ink: "var(--bg-card)" },
    Demo: { bg: "var(--rose)", ink: "#fff" }
  };
  const tag = tagColors[event.tag] || { bg: "var(--ink-soft)", ink: "#fff" };

  return (
    <article className="event-card">
      <div className="event-date">
        <div className="event-date-month">{d.month}</div>
        <div className="event-date-day">{d.day}</div>
        <div className="event-date-weekday">{d.weekday}</div>
      </div>
      <div className="event-body">
        {event.tag &&
        <span className="event-tag" style={{ background: tag.bg, color: tag.ink }}>
            {event.tag}
          </span>
        }
        <h3 className="event-title">{event.title}</h3>
        <div className="event-meta">
          <span><Icon name="phone" size={12} /> &nbsp;{event.time}</span>
          {event.location && <span><Icon name="pin" size={12} /> &nbsp;{event.location}</span>}
        </div>
        <p className="event-desc">{event.description}</p>
      </div>
    </article>);

}

function parseEventDate(dateStr) {
  // dateStr is YYYY-MM-DD; parse as local time
  const [y, m, day] = dateStr.split("-").map((n) => parseInt(n, 10));
  const dt = new Date(y, m - 1, day);
  const months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
  const weekdays = ["SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"];
  return {
    month: months[dt.getMonth()],
    day: String(dt.getDate()).padStart(2, "0"),
    weekday: weekdays[dt.getDay()]
  };
}

// ─── SHOP ───────────────────────────────────────────
function ShopPage({ navigate, route, products, productsLoaded }) {
  const initialView = route.view || "category";
  const [view, setView] = useStateS(initialView);
  const [filter, setFilter] = useStateS(route.filter || "all");
  const [sort, setSort] = useStateS("featured");
  const [search, setSearch] = useStateS("");

  useEffectS(() => {
    if (route.view) setView(route.view);
    if (route.filter) setFilter(route.filter);
  }, [route.view, route.filter]);

  const TWO_WEEKS_MS = 14 * 24 * 60 * 60 * 1000;
  const isRecentlySold = (p) =>
    p.status === "sold" && p.sold_at &&
    (Date.now() - new Date(p.sold_at).getTime()) < TWO_WEEKS_MS;

  const filteredProducts = useMemoS(() => {
    let list = (products || []).filter((p) => p.status === "live" || isRecentlySold(p));
    list = list.sort((a, b) => (a.status === "sold" ? 1 : 0) - (b.status === "sold" ? 1 : 0));
    if (search) list = list.filter((p) => (p.name || "").toLowerCase().includes(search.toLowerCase()));
    if (view === "category" && filter !== "all") list = list.filter((p) => p.category === filter);
    if (view === "vendor" && filter !== "all") list = list.filter((p) => p.vendor === filter);
    if (sort === "price-low") list = [...list].sort((a, b) => Number(a.price) - Number(b.price));
    if (sort === "price-high") list = [...list].sort((a, b) => Number(b.price) - Number(a.price));
    if (sort === "name") list = [...list].sort((a, b) => (a.name || "").localeCompare(b.name || ""));
    return list;
  }, [products, view, filter, sort, search]);

  // Distinct dealer/vendor names present in the catalog
  const vendorNames = useMemoS(() => {
    const names = [];
    (products || []).forEach((p) => {
      if (p.vendor && names.indexOf(p.vendor) === -1) names.push(p.vendor);
    });
    return names.sort();
  }, [products]);

  // For vendor view (showing all), group products by vendor
  const groupedByVendor = useMemoS(() => {
    if (view !== "vendor" || filter !== "all") return null;
    const map = {};
    filteredProducts.forEach((p) => {
      const key = p.vendor || "Other";
      (map[key] = map[key] || []).push(p);
    });
    return Object.keys(map).sort().map((name) => ({ vendor: name, products: map[name] }));
  }, [view, filter, filteredProducts]);

  const filterOptions = useMemoS(() => {
    const base = view === "category" ?
    (window.CATEGORIES || []).map((c) => ({ id: c.id, name: c.name })) :
    vendorNames.map((n) => ({ id: n, name: n }));
    base.sort((a, b) => a.name.localeCompare(b.name));
    return [{ id: "all", name: view === "category" ? "All categories" : "All vendors" }, ...base];
  }, [view, vendorNames]);

  return (
    <main style={{ paddingTop: 150, paddingBottom: 96 }}>
      <div className="container">
        <header style={{ padding: "var(--s-7) 0 var(--s-5)", textAlign: "center" }}>
          <Sprig color="var(--ink-muted)" />
          <h1 className="serif italic" style={{ fontSize: 72, fontWeight: 400, marginTop: 4 }}>The Shop</h1>
          <p className="muted" style={{ maxWidth: 56 + "ch", margin: "12px auto 0", fontSize: 16 }}>
            Every piece is photographed and listed by its dealer. Browse by category, or
            step through the booths one at a time.
          </p>
        </header>

        <div className="shop-toolbar">
          <div className="segmented" role="tablist">
            <button className={view === "category" ? "active" : ""}
            onClick={() => {setView("category");setFilter("all");}}>
              By Category
            </button>
            <button className={view === "vendor" ? "active" : ""}
            onClick={() => {setView("vendor");setFilter("all");}}>
              By Vendor
            </button>
          </div>
          <div style={{ display: "flex", gap: 12, alignItems: "center", flexWrap: "wrap" }}>
            <div style={{ position: "relative" }}>
              <input
                placeholder="Search items…"
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                style={{
                  background: "var(--bg-card)", border: "1px solid var(--line)",
                  padding: "9px 14px 9px 36px", borderRadius: 999, fontFamily: "var(--sans)",
                  fontSize: 14, width: 220, color: "var(--ink)"
                }} />
              <span style={{ position: "absolute", left: 12, top: "50%", transform: "translateY(-50%)", color: "var(--ink-muted)" }}>
                <Icon name="search" size={15} />
              </span>
            </div>
            <select value={sort} onChange={(e) => setSort(e.target.value)}
            style={{ background: "var(--bg-card)", border: "1px solid var(--line)", padding: "9px 14px", borderRadius: 999, fontFamily: "var(--sans)", fontSize: 13, color: "var(--ink)" }}>
              <option value="featured">Featured first</option>
              <option value="price-low">Price: low → high</option>
              <option value="price-high">Price: high → low</option>
              <option value="name">A → Z</option>
            </select>
          </div>
        </div>

        <div className="filter-bar" style={{ marginBottom: "var(--s-7)" }}>
          <select className="filter-select" value={filter} onChange={(e) => setFilter(e.target.value)}>
            {filterOptions.map((o) =>
            <option key={o.id} value={o.id}>{o.name}</option>
            )}
          </select>
        </div>

        {productsLoaded && filteredProducts.length === 0 &&
        <div className="empty-state">
            <h3>Nothing here yet</h3>
            <p>{(products || []).length === 0
            ? "New pieces are added all the time — check back soon."
            : "Try a different filter or search."}</p>
          </div>
        }

        {view === "vendor" && filter === "all" && groupedByVendor ?
        groupedByVendor.map(({ vendor, products }) =>
        <section key={vendor}>
              <div className="vendor-header">
                <div className="vendor-info">
                  <h3>{vendor}</h3>
                </div>
                <button className="btn btn-ghost btn-sm" onClick={() => {setFilter(vendor);window.scrollTo({ top: 0, behavior: "smooth" });}}>
                  See all {products.length}<Icon name="chevR" size={14} />
                </button>
              </div>
              <div className="product-grid">
                {products.slice(0, 4).map((p) =>
            <ProductCard key={p.id} product={p}
            onClick={() => navigate({ page: "product", id: p.id })} />
            )}
              </div>
            </section>
        ) :

        <div className="product-grid">
            {filteredProducts.map((p) =>
          <ProductCard key={p.id} product={p}
          onClick={() => navigate({ page: "product", id: p.id })} />
          )}
          </div>
        }
      </div>
    </main>);

}

// ─── PRODUCT DETAIL ─────────────────────────────────
function ProductPage({ navigate, route, products, addToCart }) {
  const p = (products || []).find((x) => x.id === route.id);
  const [qty, setQty] = useStateS(1);
  const [added, setAdded] = useStateS(false);
  const [imgIdx, setImgIdx] = useStateS(0);

  const TWO_WEEKS_MS_P = 14 * 24 * 60 * 60 * 1000;
  const isSold = p && p.status === "sold";
  const recentlySold = isSold && p.sold_at && (Date.now() - new Date(p.sold_at).getTime()) < TWO_WEEKS_MS_P;

  if (!p || (p.status !== "live" && !recentlySold)) return (
    <main className="container" style={{ paddingTop: 200, paddingBottom: 200, textAlign: "center" }}>
      <h2 className="serif italic">Sold or moved</h2>
      <p className="muted">This piece may have been sold. Browse the rest of the shop.</p>
      <button className="btn btn-outline" onClick={() => navigate({ page: "shop" })}>Back to shop</button>
    </main>);
  const related = (products || []).filter((x) => x.vendor && x.vendor === p.vendor && x.id !== p.id && x.status === "live").slice(0, 4);

  const images = (Array.isArray(p.images) && p.images.length) ? p.images : (p.image_url ? [p.image_url] : []);
  const safeIdx = Math.min(imgIdx, Math.max(0, images.length - 1));
  const available = p.quantity == null ? 1 : Math.max(0, parseInt(p.quantity, 10) || 0);

  const handleAdd = () => {
    addToCart(p, Math.min(qty, available));
    setAdded(true);
    setTimeout(() => setAdded(false), 2200);
  };

  return (
    <main className="container">
      <div className="pdp">
        <div className="pdp-gallery">
          <div className="main">
            <ProductImage product={{ ...p, image_url: images[safeIdx] || p.image_url }} tag={isSold ? "Sold Out" : null} />
          </div>
          {images.length > 1 &&
          <div className="pdp-thumbs">
            {images.map((url, i) =>
            <div key={url + i} className={"pdp-thumb" + (i === safeIdx ? " active" : "")} onClick={() => setImgIdx(i)}>
                <img src={url} alt="" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} />
              </div>
            )}
          </div>}
        </div>
        <div className="pdp-info">
          {p.vendor &&
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <a className="vendor-tag" onClick={() => navigate({ page: "shop", view: "vendor", filter: p.vendor })}
            style={{ cursor: "pointer", borderBottom: "1px solid var(--ink-muted)" }}>{p.vendor}</a>
          </div>
          }
          <h1 className="serif italic">{p.name}</h1>
          <div className={"price" + (isSold ? " sold" : "")}>${Number(p.price || 0).toLocaleString()}</div>
          <p className="desc">{p.description}</p>
          <dl className="pdp-specs">
            {p.era && <><dt>Era</dt><dd>{p.era}</dd></>}
            {p.origin && <><dt>Origin</dt><dd>{p.origin}</dd></>}
            {p.dims && <><dt>Dimensions</dt><dd>{p.dims}</dd></>}
            {p.condition && <><dt>Condition</dt><dd>{p.condition}</dd></>}
          </dl>
          {!isSold && available > 1 &&
          <div style={{ fontSize: 13, color: "var(--ink-muted)", marginTop: -4 }}>{available} available</div>}
          <div className="pdp-cta">
            <div className="qty">
              <button onClick={() => setQty(Math.max(1, qty - 1))} disabled={isSold}><Icon name="minus" size={14} /></button>
              <span>{qty}</span>
              <button onClick={() => setQty(Math.min(available, qty + 1))} disabled={isSold || qty >= available}><Icon name="plus" size={14} /></button>
            </div>
            <button className="btn btn-primary btn-lg" disabled={isSold} onClick={handleAdd}>
              {isSold ? "Sold" : added ? "Added to cart ✓" : "Add to cart"}
            </button>
            <button className="btn btn-outline btn-lg" onClick={() => navigate({ page: "contact" })}>
              Ask about this piece
            </button>
          </div>
          <div style={{ marginTop: "var(--s-5)", fontSize: 13, color: "var(--ink-muted)", lineHeight: 1.7 }}>
            <strong style={{ color: "var(--ink-soft)" }}>Pickup & delivery:</strong>&nbsp;
            Local pickup is free in store. We also arrange white-glove delivery within
            a 20-mile radius for furniture and large pieces — we'll quote at checkout.
          </div>
        </div>
      </div>

      {related.length > 0 &&
      <section style={{ marginTop: "var(--s-9)" }}>
          <div className="section-head">
            <div>
              <span className="eyebrow">More from</span>
              <h2 className="serif italic">{p.vendor}</h2>
            </div>
          </div>
          <div className="product-grid">
            {related.map((r) =>
          <ProductCard key={r.id} product={r}
          onClick={() => {navigate({ page: "product", id: r.id });window.scrollTo({ top: 0 });}} />
          )}
          </div>
        </section>
      }
    </main>);

}

// ─── CART ───────────────────────────────────────────
function CartPage({ navigate, cart, updateQty, removeFromCart }) {
  const subtotal = cart.reduce((s, item) => s + item.product.price * item.qty, 0);
  const shipping = subtotal > 0 ? subtotal > 500 ? 0 : 35 : 0;
  const tax = +(subtotal * 0.07).toFixed(2);
  const total = subtotal + shipping + tax;

  if (cart.length === 0) {
    return (
      <main className="container">
        <div className="empty-state" style={{ paddingTop: 200 }}>
          <Sprig color="var(--ink-muted)" />
          <h3 style={{ marginTop: 12 }}>Your cart is empty</h3>
          <p>Wander the store — something will catch your eye.</p>
          <button className="btn btn-primary" onClick={() => navigate({ page: "shop" })} style={{ marginTop: 16 }}>Browse the shop</button>
        </div>
      </main>);

  }

  return (
    <main className="container">
      <div className="cart-wrap">
        <div>
          <header style={{ marginBottom: "var(--s-6)" }}>
            <span className="eyebrow">Your cart</span>
            <h1 className="serif italic" style={{ fontSize: 56, marginTop: 8 }}>
              {cart.length} {cart.length === 1 ? "piece" : "pieces"}, set aside.
            </h1>
          </header>
          <div className="cart-list">
            {cart.map((item) => {
              return (
                <div className="cart-row" key={item.product.id}>
                  <div className="thumb"><ProductImage product={item.product} /></div>
                  <div className="info">
                    <span className="vendor">{item.product.vendor || ""}</span>
                    <h4 onClick={() => navigate({ page: "product", id: item.product.id })} style={{ cursor: "pointer" }}>{item.product.name}</h4>
                    <div className="qty-row">
                      <span style={{ color: "var(--ink-muted)", fontSize: 13 }}>Qty</span>
                      <button onClick={() => updateQty(item.product.id, item.qty - 1)}>−</button>
                      <span style={{ minWidth: 18, textAlign: "center" }}>{item.qty}</span>
                      <button onClick={() => updateQty(item.product.id, item.qty + 1)}>+</button>
                      <span style={{ color: "var(--ink-muted)", margin: "0 8px" }}>·</span>
                      <button onClick={() => removeFromCart(item.product.id)} style={{ color: "var(--terracotta)" }}>Remove</button>
                    </div>
                  </div>
                  <div className="price-col">${(item.product.price * item.qty).toLocaleString()}</div>
                </div>);

            })}
          </div>
        </div>
        <aside className="summary">
          <h3>Order summary</h3>
          <div className="summary-row"><span>Subtotal</span><span>${subtotal.toLocaleString()}</span></div>
          <div className="summary-row"><span>Shipping</span><span>{shipping === 0 ? "Free" : "$" + shipping}</span></div>
          <div className="summary-row"><span>Tax (est.)</span><span>${tax.toLocaleString()}</span></div>
          <div className="summary-row total"><span>Total</span><span>${total.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span></div>
          <button className="btn btn-primary" style={{ width: "100%", marginTop: "var(--s-5)" }}
          onClick={() => navigate({ page: "checkout" })}>
            Checkout
          </button>
          <p style={{ fontSize: 12, color: "var(--ink-muted)", textAlign: "center", marginTop: 12 }}>
            Or <a onClick={() => navigate({ page: "shop" })} style={{ borderBottom: "1px solid var(--ink-muted)", cursor: "pointer" }}>keep browsing</a>
          </p>
        </aside>
      </div>
    </main>);

}

// ─── CHECKOUT ───────────────────────────────────────
// Load the Square Web Payments SDK for the given environment.
function loadSquareSdk(env) {
  return new Promise((resolve, reject) => {
    if (window.Square) { resolve(); return; }
    const existing = document.querySelector("script[data-square-sdk]");
    if (existing) {
      existing.addEventListener("load", () => resolve());
      existing.addEventListener("error", () => reject(new Error("Square SDK failed to load")));
      return;
    }
    const s = document.createElement("script");
    s.src = env === "production" ?
    "https://web.squarecdn.com/v1/square.js" :
    "https://sandbox.web.squarecdn.com/v1/square.js";
    s.setAttribute("data-square-sdk", "1");
    s.onload = () => resolve();
    s.onerror = () => reject(new Error("Square SDK failed to load"));
    document.head.appendChild(s);
  });
}

function CheckoutPage({ navigate, cart, clearCart, reloadProducts }) {
  const [step, setStep] = useStateS("contact"); // contact | shipping | payment
  const [form, setForm] = useStateS({
    email: "", name: "", phone: "",
    addr1: "", addr2: "", city: "", state: "FL", zip: "",
    delivery: "ship"
  });
  const [sqConfig, setSqConfig] = useStateS(null);
  const [cardReady, setCardReady] = useStateS(false);
  const [processing, setProcessing] = useStateS(false);
  const [payError, setPayError] = useStateS("");
  const [shipQuote, setShipQuote] = useStateS(null);
  const [quoting, setQuoting] = useStateS(false);
  const cardRef = useRefS(null);

  const subtotal = cart.reduce((s, item) => s + Number(item.product.price) * item.qty, 0);
  const pickup = form.delivery === "pickup";
  const shipping = subtotal > 0 && !pickup ? (shipQuote != null ? shipQuote : 0) : 0;
  const tax = +(subtotal * 0.07).toFixed(2);
  const total = subtotal + shipping + tax;
  const money2 = (n) => "$" + Number(n).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  const shippingLabel = pickup ? "Free"
    : quoting ? "Calculating…"
    : shipQuote != null ? money2(shipQuote)
    : "Enter address";

  const set = (k, v) => setForm((f) => ({ ...f, [k]: v }));

  // Fetch Square's public settings once.
  useEffectS(() => {
    fetch("/api/checkout")
      .then((r) => r.json())
      .then((c) => setSqConfig(c && c.appId ? c : { error: true }))
      .catch(() => setSqConfig({ error: true }));
  }, []);

  // Live shipping quote: recompute whenever the destination changes.
  useEffectS(() => {
    if (pickup) { setShipQuote(0); setQuoting(false); return; }
    const zip = (form.zip || "").replace(/[^0-9]/g, "");
    if (zip.length < 5) { setShipQuote(null); setQuoting(false); return; }
    let cancelled = false;
    setQuoting(true);
    const t = setTimeout(() => {
      fetch("/api/checkout", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          quote: true,
          cart: cart.map((c) => ({ id: c.product.id, qty: c.qty })),
          destination: { zip: zip, state: form.state, city: form.city, street1: form.addr1 },
        }),
      })
        .then((r) => r.json())
        .then((d) => { if (!cancelled) setShipQuote(typeof d.shipping === "number" ? d.shipping : null); })
        .catch(() => { if (!cancelled) setShipQuote(null); })
        .finally(() => { if (!cancelled) setQuoting(false); });
    }, 500);
    return () => { cancelled = true; clearTimeout(t); };
  }, [pickup, form.zip, form.state, form.city, form.addr1, cart]);

  // Build the Square card form when the payment step opens.
  useEffectS(() => {
    if (step !== "payment" || !sqConfig || sqConfig.error) return;
    let cancelled = false;
    (async () => {
      try {
        await loadSquareSdk(sqConfig.env);
        if (cancelled) return;
        const payments = window.Square.payments(sqConfig.appId, sqConfig.locationId);
        const card = await payments.card();
        if (cancelled) { try { card.destroy(); } catch (e) {} return; }
        await card.attach("#sq-card");
        cardRef.current = card;
        setCardReady(true);
      } catch (e) {
        setPayError("The payment form could not load. Refresh the page and try again.");
      }
    })();
    return () => {
      cancelled = true;
      setCardReady(false);
      if (cardRef.current) { try { cardRef.current.destroy(); } catch (e) {} cardRef.current = null; }
    };
  }, [step, sqConfig]);

  const next = () => {
    setPayError("");
    if (step === "contact") {
      if (!form.email || !form.name) { setPayError("Please add your name and email."); return; }
      setStep("shipping");
    } else if (step === "shipping") {
      if (form.delivery === "ship" && (!form.addr1 || !form.city || !form.zip)) {
        setPayError("Please fill in your shipping address.");
        return;
      }
      if (form.delivery === "ship" && quoting) {
        setPayError("One moment — we're calculating shipping for your address.");
        return;
      }
      if (form.delivery === "ship" && shipQuote == null) {
        setPayError("We couldn't calculate shipping for that address. Please double-check your ZIP code.");
        return;
      }
      setStep("payment");
    }
  };

  const placeOrder = async () => {
    setPayError("");
    if (!cardRef.current) { setPayError("The payment form isn't ready yet — one moment."); return; }
    setProcessing(true);
    try {
      const result = await cardRef.current.tokenize();
      if (result.status !== "OK") {
        setPayError("Please check your card details and try again.");
        setProcessing(false);
        return;
      }
      const res = await fetch("/api/checkout", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          sourceId: result.token,
          cart: cart.map((c) => ({ id: c.product.id, qty: c.qty })),
          customer: {
            name: form.name, email: form.email, phone: form.phone,
            delivery: form.delivery,
            address: form.delivery === "ship" ?
            [form.addr1, form.addr2, form.city, form.state, form.zip].filter(Boolean).join(", ") :
            "",
            street1: form.delivery === "ship" ? form.addr1 : "",
            city: form.delivery === "ship" ? form.city : "",
            state: form.delivery === "ship" ? form.state : "",
            zip: form.delivery === "ship" ? form.zip : ""
          }
        })
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        setPayError(data.error || "Payment could not be completed.");
        setProcessing(false);
        return;
      }
      clearCart();
      if (reloadProducts) reloadProducts();
      navigate({ page: "confirmation", orderNum: data.orderNum || "" });
    } catch (e) {
      setPayError("Something went wrong. If you were not charged, please try again.");
      setProcessing(false);
    }
  };

  if (cart.length === 0) {
    navigate({ page: "shop" });
    return null;
  }

  return (
    <main className="container">
      <div className="checkout-grid">
        <div>
          <header style={{ marginBottom: "var(--s-6)" }}>
            <span className="eyebrow">Checkout</span>
            <h1 className="serif italic" style={{ fontSize: 56, marginTop: 8 }}>Almost yours.</h1>
          </header>
          <div className="steps">
            <span className={step === "contact" ? "active" : "done"}>1 · Contact</span>
            <span className={step === "shipping" ? "active" : step === "payment" ? "done" : ""}>2 · Shipping</span>
            <span className={step === "payment" ? "active" : ""}>3 · Payment</span>
          </div>

          {step === "contact" &&
          <div className="form-grid">
              <div className="field full"><label>Email</label><input type="email" value={form.email} onChange={(e) => set("email", e.target.value)} placeholder="you@example.com" /></div>
              <div className="field"><label>Full name</label><input value={form.name} onChange={(e) => set("name", e.target.value)} placeholder="Jane Doe" /></div>
              <div className="field"><label>Phone</label><input value={form.phone} onChange={(e) => set("phone", e.target.value)} placeholder="(352) 555-0100" /></div>
            </div>
          }

          {step === "shipping" &&
          <>
              <div style={{ marginBottom: "var(--s-5)" }}>
                <label style={{ fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--ink-muted)", marginBottom: 8, display: "block" }}>Delivery</label>
                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
                  {[{ id: "ship", label: "Ship to me", sub: "Calculated by size & destination" }, { id: "pickup", label: "Pick up in store", sub: "Free · 18559 High Springs Main" }].map((opt) =>
                <label key={opt.id} style={{
                  padding: 16, borderRadius: 8,
                  border: "1px solid " + (form.delivery === opt.id ? "var(--ink)" : "var(--line)"),
                  background: "var(--bg-card)", cursor: "pointer",
                  display: "block"
                }}>
                      <input type="radio" name="delivery" checked={form.delivery === opt.id}
                  onChange={() => set("delivery", opt.id)} style={{ marginRight: 8 }} />
                      <span style={{ fontWeight: 500 }}>{opt.label}</span>
                      <div style={{ fontSize: 13, color: "var(--ink-muted)", marginTop: 4, paddingLeft: 24 }}>{opt.sub}</div>
                    </label>
                )}
                </div>
              </div>
              {form.delivery === "ship" &&
            <div className="form-grid">
                  <div className="field full"><label>Address</label><input value={form.addr1} onChange={(e) => set("addr1", e.target.value)} placeholder="123 Main St" /></div>
                  <div className="field full"><label>Apt / Suite (optional)</label><input value={form.addr2} onChange={(e) => set("addr2", e.target.value)} /></div>
                  <div className="field"><label>City</label><input value={form.city} onChange={(e) => set("city", e.target.value)} /></div>
                  <div className="field"><label>State</label><input value={form.state} onChange={(e) => set("state", e.target.value)} /></div>
                  <div className="field full"><label>Zip</label><input value={form.zip} onChange={(e) => set("zip", e.target.value)} /></div>
                </div>
            }
            </>
          }

          {step === "payment" &&
          <div>
            {sqConfig && sqConfig.error ?
            <p style={{ color: "var(--terracotta)", fontSize: 14 }}>
                Online payment is temporarily unavailable. Please call the store to complete your purchase.
              </p> :
            <>
                <label style={{ fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--ink-muted)", marginBottom: 8, display: "block" }}>Card details</label>
                <div id="sq-card" style={{ minHeight: 48 }} />
                {!cardReady &&
              <p style={{ fontSize: 13, color: "var(--ink-muted)", marginTop: 8 }}>Loading secure payment form…</p>}
                <p style={{ fontSize: 12, color: "var(--ink-muted)", marginTop: 10 }}>
                  Payments are processed securely by Square — your card details never touch our servers.
                </p>
              </>}
          </div>
          }

          {payError &&
          <p style={{ color: "var(--terracotta)", fontSize: 13, marginTop: "var(--s-5)" }}>{payError}</p>}

          <div style={{ display: "flex", justifyContent: "space-between", marginTop: "var(--s-5)", gap: 12 }}>
            <button className="btn btn-ghost" disabled={processing} onClick={() => {
              if (step === "shipping") setStep("contact");else
              if (step === "payment") setStep("shipping");else
              navigate({ page: "cart" });
            }}>← Back</button>
            {step === "payment" ?
            <button className="btn btn-primary btn-lg" onClick={placeOrder} disabled={processing || !cardReady || quoting}>
                {processing ? "Processing…" : "Place order · $" + total.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
              </button> :
            <button className="btn btn-primary btn-lg" onClick={next}>Continue</button>}
          </div>
        </div>
        <aside className="summary">
          <h3>In your order</h3>
          <div style={{ display: "flex", flexDirection: "column", gap: 12, marginBottom: "var(--s-4)" }}>
            {cart.map((item) =>
            <div key={item.product.id} style={{ display: "flex", gap: 12 }}>
                <div style={{ width: 56, aspectRatio: "4/5", borderRadius: 4, overflow: "hidden", position: "relative", flexShrink: 0 }}>
                  <ProductImage product={item.product} />
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div className="serif italic" style={{ fontSize: 16, lineHeight: 1.2 }}>{item.product.name}</div>
                  <div style={{ fontSize: 12, color: "var(--ink-muted)" }}>Qty {item.qty}</div>
                </div>
                <div style={{ fontWeight: 500 }}>${(item.product.price * item.qty).toLocaleString()}</div>
              </div>
            )}
          </div>
          <div className="summary-row"><span>Subtotal</span><span>${subtotal.toLocaleString()}</span></div>
          <div className="summary-row"><span>Shipping</span><span>{shippingLabel}</span></div>
          <div className="summary-row"><span>Tax</span><span>${tax.toLocaleString()}</span></div>
          <div className="summary-row total"><span>Total</span><span>${total.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span></div>
        </aside>
      </div>
    </main>);

}

// ─── CONFIRMATION ───────────────────────────────────
function ConfirmationPage({ navigate, route }) {
  return (
    <main className="confirmation container">
      <div className="check"><Icon name="check" size={36} stroke={1.4} /></div>
      <span className="order-num">Order {route.orderNum || "DOM-9000"}</span>
      <h1>Thank you,<br />your pieces are set aside.</h1>
      <p className="muted" style={{ maxWidth: 50 + "ch", margin: "0 auto var(--s-6)", lineHeight: 1.7 }}>
        We'll send a confirmation to your email shortly. Pickup orders are ready
        within 24 hours; shipped orders go out on Wednesdays and Saturdays.
      </p>
      <div style={{ display: "flex", gap: 12, justifyContent: "center", flexWrap: "wrap" }}>
        <button className="btn btn-primary" onClick={() => navigate({ page: "shop" })}>Keep browsing</button>
        <button className="btn btn-outline" onClick={() => navigate({ page: "home" })}>Back to home</button>
      </div>
    </main>);

}

Object.assign(window, { HomePage, ShopPage, ProductPage, CartPage, CheckoutPage, ConfirmationPage, EventCard });