// Info pages: About, Contact, Selling?
// Admin: Login, Dashboard with Items, Vendors, Sales, Settings

const { useState: useStateI, useEffect: useEffectI, useMemo: useMemoI, useRef: useRefI } = React;

// ─── ABOUT ──────────────────────────────────────────
function AboutPage({ navigate }) {
  return (
    <main className="editorial container about-page">
      <section className="about-hero">
        <Sprig color="var(--ink-muted)" />
        <h1 className="serif italic about-hero-title">
          Shop local.<br />Shop Decades.
        </h1>
        <p className="about-hero-sub">
          Sixteen vendors, six thousand square feet, on Main Street in High Springs.
        </p>
      </section>

      <figure className="about-hero-image">
        <img src="assets/storefront.webp" alt="Decades on Main storefront" />
      </figure>

      <section className="about-story-column">
        <div style={{ textAlign: "center" }}>
          <span className="eyebrow">Our story</span>
        </div>
        <h2 className="serif italic about-section-h">
          Twenty-plus years<br />on Main Street.
        </h2>
        <p>Decades on Main has been a quiet fixture in High Springs for more than twenty years — long before downtown caught on, back when the building had just a few rooms and a handful of vendors. It earned its name honestly, the same way old furniture does: slowly, and through use.</p>

        <figure className="about-inline-image">
          <img src="assets/about-photo.webp" alt="The dealers of Decades on Main" loading="lazy" />
          <figcaption>The dealers of Decades</figcaption>
        </figure>

        <p>In 2023, the store was bought by a local couple who'd always find themselves picking through it on Saturdays — and who had a vision for what it could still become. Since then, we've expanded tremendously and grown to more than could have been imagined, brought in new dealers, and made room for more of the things people actually come here for: bigger furniture, more art, a bigger jewelry case, and weekend tunes on the porch.</p>

        <p>We've grown every year since, and we plan to keep growing. But the heart of the place hasn't changed — sixteen dealers who actually love what they carry, a slow afternoon's worth of stories under one roof, and a staff that will always be happy to have you.</p>
      </section>

      <div className="about-stats-rule">
        <span><b>16</b> dealers</span>
        <span className="dot">·</span>
        <span><b>6,000+</b> sqft</span>
        <span className="dot">·</span>
        <span><b>1,200+</b> items</span>
        <span className="dot">·</span>
        <span><b>Tue – Sun · 11 – 6</b></span>
      </div>

      <section className="about-cta">
        <Sprig color="var(--ink-muted)" />
        <h2 className="serif italic about-section-h">Come on in.</h2>
        <p className="muted" style={{ marginTop: 8 }}>
          You can find us off of High Springs Main Street.
        </p>
        <div className="about-cta-buttons">
          <button className="btn btn-primary" onClick={() => navigate({ page: "shop" })}>Shop online</button>
          <button className="btn btn-outline" onClick={() => navigate({ page: "contact" })}>Get directions</button>
        </div>
      </section>
    </main>);

}

// ─── CONTACT ────────────────────────────────────────
function ContactPage({ route }) {
  const [sent, setSent] = useStateI(false);
  const [subject, setSubject] = useStateI(route?.subject || "general");
  const [name, setName] = useStateI("");
  const [email, setEmail] = useStateI("");
  const [message, setMessage] = useStateI("");
  const [busy, setBusy] = useStateI(false);
  const [err, setErr] = useStateI("");
  useEffectI(() => {if (route?.subject) setSubject(route.subject);}, [route?.subject]);

  const submit = async (e) => {
    e.preventDefault();
    setErr("");
    setBusy(true);
    try {
      const r = await fetch("/api/contact", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name, email, subject, message }),
      });
      const data = await r.json().catch(() => ({}));
      if (!r.ok) { setErr(data.error || "Something went wrong. Please call us at (352) 575-3633."); return; }
      setSent(true);
      setName(""); setEmail(""); setMessage("");
    } catch (e2) {
      setErr("Couldn't reach the server. Please call us at (352) 575-3633.");
    } finally {
      setBusy(false);
    }
  };
  return (
    <main className="editorial container">
      <section style={{ padding: "var(--s-9) 0 var(--s-7)", textAlign: "center" }}>
        <span className="eyebrow">Get in touch</span>
        <h1 className="serif italic" style={{ fontSize: 88, marginTop: 6, lineHeight: 1, fontWeight: 400 }}>
          We'd love to hear from you.
        </h1>
      </section>

      <section className="contact-grid" style={{ display: "grid", gridTemplateColumns: "1.2fr 1fr", gap: "var(--s-8)", padding: "var(--s-7) 0" }}>
        <div>
          {sent ?
          <div style={{ padding: "var(--s-7)", background: "var(--bg-card)", border: "1px solid var(--line-soft)", borderRadius: 8, textAlign: "center" }}>
              <Icon name="check" size={36} stroke={1.4} />
              <h3 className="serif italic" style={{ fontSize: 32, marginTop: 12, fontWeight: 400 }}>Note sent.</h3>
              <p className="muted">We'll get back to you within a day or two.</p>
              <button className="btn btn-ghost btn-sm" onClick={() => setSent(false)}>Send another</button>
            </div> :

          <form className="form-grid" onSubmit={submit}>
              <div className="field"><label>Your name</label>
                <input required value={name} onChange={(e) => setName(e.target.value)} /></div>
              <div className="field"><label>Email</label>
                <input type="email" required value={email} onChange={(e) => setEmail(e.target.value)} /></div>
              <div className="field full"><label>Subject</label>
                <select value={subject} onChange={(e) => setSubject(e.target.value)}>
                  <option value="general">General question</option>
                  <option value="item">Question about an item</option>
                  <option value="vendor">Selling</option>
                  <option value="appraisal">Appraisal request</option>
                </select>
              </div>
              <div className="field full"><label>Message</label>
                <textarea required placeholder="Tell us what you're after…" value={message} onChange={(e) => setMessage(e.target.value)} /></div>
              {err && <div className="full" style={{ color: "var(--terracotta)", fontSize: 14 }}>{err}</div>}
              <div className="full"><button className="btn btn-primary btn-lg" type="submit" disabled={busy}>
                {busy ? "Sending…" : "Send message"}
              </button></div>
            </form>
          }
        </div>
        <aside style={{ display: "flex", flexDirection: "column", gap: "var(--s-6)" }}>
          <div>
            <div className="eyebrow"><Icon name="pin" size={13} /> &nbsp;Address</div>
            <p className="serif" style={{ fontSize: 22, fontStyle: "italic", lineHeight: 1.4, marginTop: 6 }}>
              18559 High Springs<br />Main Street<br />High Springs, FL 32643
            </p>
          </div>
          <div>
            <div className="eyebrow"><Icon name="phone" size={13} /> &nbsp;Call</div>
            <p className="serif" style={{ fontSize: 22, fontStyle: "italic", marginTop: 6 }}>
              <a href="tel:3525753633">(352) 575-3633</a>
            </p>
          </div>
          <div>
            <div className="eyebrow">Hours</div>
            <ul className="hours-list" style={{ marginTop: 8 }}>
              <li className="closed"><span>Monday</span><span>Closed</span></li>
              <li><span>Tuesday</span><span>11 – 6</span></li>
              <li><span>Wednesday</span><span>11 – 6</span></li>
              <li><span>Thursday</span><span>11 – 6</span></li>
              <li><span>Friday</span><span>11 – 6</span></li>
              <li><span>Saturday</span><span>11 – 6</span></li>
              <li><span>Sunday</span><span>11 – 6</span></li>
            </ul>
          </div>
          <div>
            <div className="eyebrow">Follow along</div>
            <div className="socials" style={{ marginTop: 10, color: "var(--ink-soft)" }}>
              <a href="https://www.facebook.com/DecadesOnMain/" target="_blank" rel="noreferrer" style={{ border: "1px solid var(--line)" }}><Icon name="fb" size={16} /></a>
              <a href="https://www.instagram.com/decadesonmain/" target="_blank" rel="noreferrer" style={{ border: "1px solid var(--line)" }}><Icon name="ig" size={16} /></a>
            </div>
          </div>
        </aside>
      </section>
    </main>);

}

// ─── SCHEDULE A CONSULTATION ────────────────────────
// Standalone page (its own route): customer picks a consultation type and
// preferred time; the request is emailed to the store via /api/booking.
// Staff confirm the time (and any fee) at the appointment.
const CONSULTATIONS = [
  {
    id: "estate-sale",
    title: "Estate Sale Consultation",
    blurb: "Sit down with us to plan an estate sale — what's worth selling, how to price it, and how to make the day run smoothly.",
  },
  {
    id: "seller",
    title: "Seller Consultation",
    blurb: "Tell us about what you'd like to sell or consign. We'll talk value, whether it's a fit for the shop, and next steps.",
  },
  {
    id: "home-decor",
    title: "Home Décor Consultation",
    sub: "Designs by Renee",
    blurb: "One-on-one styling with Renee — pull a room together with antiques and finds, in your home or here in the shop.",
    price: "$100 / hour",
  },
];

function ConsultPage() {
  const [type, setType] = useStateI("");
  const [form, setForm] = useStateI({ name: "", email: "", phone: "", preferred: "", notes: "" });
  const [busy, setBusy] = useStateI(false);
  const [err, setErr] = useStateI("");
  const [sent, setSent] = useStateI(false);
  const formRef = useRefI(null);

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

  const choose = (id) => {
    setType(id);
    setErr("");
    if (formRef.current) formRef.current.scrollIntoView({ behavior: "smooth", block: "center" });
  };

  const submit = async (e) => {
    e.preventDefault();
    setErr("");
    if (!type) { setErr("Please choose a consultation type above."); return; }
    setBusy(true);
    try {
      const r = await fetch("/api/booking", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ type, ...form }),
      });
      const data = await r.json().catch(() => ({}));
      if (!r.ok) { setErr(data.error || "Something went wrong. Please call us at (352) 575-3633."); return; }
      setSent(true);
      window.scrollTo({ top: 0, behavior: "smooth" });
    } catch (e2) {
      setErr("Couldn't reach the server. Please call us at (352) 575-3633.");
    } finally {
      setBusy(false);
    }
  };

  return (
    <main className="editorial container">
      <section style={{ padding: "var(--s-9) 0 var(--s-6)", textAlign: "center" }}>
        <span className="eyebrow">By appointment</span>
        <h1 className="serif italic" style={{ fontSize: 88, marginTop: 6, lineHeight: 1, fontWeight: 400 }}>
          Schedule a consultation.
        </h1>
        <p className="muted" style={{ fontSize: 18, maxWidth: 60 + "ch", margin: "var(--s-5) auto 0", lineHeight: 1.7 }}>
          Sit down with us one-on-one. Pick what you'd like to talk through, send a few preferred times,
          and we'll confirm a slot with you.
        </p>
      </section>

      <div className="info-grid" style={{ borderTop: "none", padding: "0 0 var(--s-7)" }}>
        {CONSULTATIONS.map((c) => {
          const active = type === c.id;
          return (
            <div key={c.id} style={{
              background: "var(--bg-card)",
              border: "1.5px solid " + (active ? "var(--sage)" : "var(--line-soft)"),
              borderRadius: 12,
              padding: "var(--s-6)",
              display: "flex",
              flexDirection: "column",
              transition: "border-color 160ms ease",
            }}>
              <h3 className="serif italic" style={{ fontSize: 28, fontWeight: 400, marginBottom: c.sub ? 2 : "var(--s-3)" }}>
                {c.title}
              </h3>
              {c.sub &&
                <div className="eyebrow" style={{ marginBottom: "var(--s-3)", color: "var(--sage)" }}>{c.sub}</div>}
              <p className="muted" style={{ fontSize: 15, lineHeight: 1.7, flex: 1 }}>{c.blurb}</p>
              <div className="serif italic" style={{ fontSize: 22, margin: "var(--s-4) 0", color: c.price ? "var(--ink)" : "var(--ink-muted)" }}>
                {c.price || "By appointment"}
              </div>
              <button
                type="button"
                className={active ? "btn btn-primary" : "btn btn-outline"}
                onClick={() => choose(c.id)}>
                {active ? "Selected ✓" : "Request this"}
              </button>
            </div>);

        })}
      </div>

      <div ref={formRef} style={{
        background: "var(--bg-card)",
        border: "1px solid var(--line-soft)",
        borderRadius: 14,
        padding: "var(--s-7)",
        maxWidth: 760,
        margin: "0 auto var(--s-9)",
      }}>
        {sent ?
          <div style={{ textAlign: "center", padding: "var(--s-4) 0" }}>
            <Icon name="check" size={36} stroke={1.4} />
            <h3 className="serif italic" style={{ fontSize: 32, marginTop: 12, fontWeight: 400 }}>Request sent.</h3>
            <p className="muted">
              Thanks — we'll reach out to confirm a time. Payment of $100/hour is handled at the appointment.
            </p>
            <button className="btn btn-ghost btn-sm" onClick={() => {
              setSent(false); setType(""); setErr("");
              setForm({ name: "", email: "", phone: "", preferred: "", notes: "" });
            }}>Book another</button>
          </div> :

          <form className="form-grid" onSubmit={submit}>
            <div className="field"><label>Your name</label>
              <input required value={form.name} onChange={(e) => set("name", e.target.value)} /></div>
            <div className="field"><label>Email</label>
              <input type="email" required value={form.email} onChange={(e) => set("email", e.target.value)} /></div>
            <div className="field"><label>Phone</label>
              <input type="tel" value={form.phone} onChange={(e) => set("phone", e.target.value)} /></div>
            <div className="field"><label>Consultation</label>
              <select value={type} onChange={(e) => setType(e.target.value)}>
                <option value="">Choose one…</option>
                {CONSULTATIONS.map((c) => <option key={c.id} value={c.id}>{c.title}</option>)}
              </select>
            </div>
            <div className="field full"><label>Preferred days / times</label>
              <input value={form.preferred} onChange={(e) => set("preferred", e.target.value)}
                placeholder="e.g. Weekday mornings, the week of July 7" /></div>
            <div className="field full"><label>Anything else?</label>
              <textarea value={form.notes} onChange={(e) => set("notes", e.target.value)}
                placeholder="Tell us a little about what you're after…" /></div>
            {err && <div className="full" style={{ color: "var(--terracotta)", fontSize: 14 }}>{err}</div>}
            <div className="full">
              <button className="btn btn-primary btn-lg" type="submit" disabled={busy}>
                {busy ? "Sending…" : "Request appointment"}
              </button>
            </div>
          </form>
        }
      </div>
    </main>);

}

// ─── SELLING ────────────────────────────────────────
// A focused submission page: tell us what you have to sell, attach photos.
function SellingPage({ navigate }) {
  const [form, setForm] = useStateI({
    name: "", email: "", phone: "",
    itemType: "", description: "",
    askingPrice: ""
  });
  const [photos, setPhotos] = useStateI([]); // { id, url, name, size }
  const [dragOver, setDragOver] = useStateI(false);
  const [sent, setSent] = useStateI(false);
  const fileInputRef = useRefI(null);

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

  const handleFiles = (fileList) => {
    const arr = Array.from(fileList).filter((f) => f.type.startsWith("image/")).slice(0, 12 - photos.length);
    arr.forEach((file) => {
      const reader = new FileReader();
      reader.onload = (e) => {
        setPhotos((p) => [...p, {
          id: Math.random().toString(36).slice(2),
          url: e.target.result,
          name: file.name,
          size: file.size
        }]);
      };
      reader.readAsDataURL(file);
    });
  };

  const onDrop = (e) => {
    e.preventDefault();
    setDragOver(false);
    handleFiles(e.dataTransfer.files);
  };

  const submit = (e) => {
    e.preventDefault();
    setSent(true);
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  if (sent) {
    return (
      <main className="editorial container">
        <section style={{ padding: "var(--s-9) 0", textAlign: "center", maxWidth: 640, margin: "0 auto" }}>
          <div className="check" style={{
            width: 80, height: 80, borderRadius: "50%",
            border: "1.5px solid var(--sage)", color: "var(--sage)",
            display: "inline-flex", alignItems: "center", justifyContent: "center",
            margin: "var(--s-6) auto var(--s-5)"
          }}>
            <Icon name="check" size={36} stroke={1.4} />
          </div>
          <h1 className="serif italic" style={{ fontSize: 56, fontWeight: 400 }}>Got it — thank you.</h1>
          <p className="muted" style={{ fontSize: 18, lineHeight: 1.7, marginTop: "var(--s-4)" }}>
            We received your submission with {photos.length} {photos.length === 1 ? "photo" : "photos"}.
            Someone from the store will take a look and get back to you within a day or two.
          </p>
          <div style={{ display: "flex", gap: 12, justifyContent: "center", marginTop: "var(--s-6)", flexWrap: "wrap" }}>
            <button className="btn btn-primary" onClick={() => navigate({ page: "home" })}>Back to home</button>
            <button className="btn btn-outline" onClick={() => {
              setSent(false);setPhotos([]);
              setForm({ name: "", email: "", phone: "", itemType: "", description: "", askingPrice: "" });
            }}>Submit another</button>
          </div>
        </section>
      </main>);

  }

  return (
    <main className="editorial container">
      <section style={{ padding: "var(--s-9) 0 var(--s-6)", textAlign: "center" }}>
        <Sprig />
        <span className="eyebrow" style={{ display: "block", marginTop: 6 }}>Selling?</span>
        <h1 className="serif italic" style={{ fontSize: 88, marginTop: 6, lineHeight: 1, fontWeight: 400 }}>
          Got something to sell?
        </h1>
        <p className="muted" style={{ fontSize: 18, maxWidth: 56 + "ch", margin: "var(--s-5) auto 0", lineHeight: 1.7 }}>
          Send us a few photos and tell us a little about what you have.
          We'll take a look and let you know if it's a fit for the store.
        </p>
      </section>

      <section style={{
        background: "var(--bg-card)",
        border: "1px solid var(--line-soft)",
        borderRadius: 14,
        padding: "var(--s-7)",
        margin: "var(--s-5) 0 var(--s-9)"
      }}>
        <form onSubmit={submit}>
          {/* PHOTO UPLOAD */}
          <h2 className="serif italic" style={{ fontSize: 28, fontWeight: 400, marginBottom: "var(--s-3)" }}>Photos</h2>
          <p className="muted" style={{ fontSize: 14, marginBottom: "var(--s-4)" }}>
            Add up to 12 photos. Different angles help — and a shot of any maker's mark or signature is great if it has one.
          </p>

          <div
            onClick={() => fileInputRef.current?.click()}
            onDragOver={(e) => {e.preventDefault();setDragOver(true);}}
            onDragLeave={() => setDragOver(false)}
            onDrop={onDrop}
            style={{
              border: "2px dashed " + (dragOver ? "var(--ink)" : "var(--line)"),
              background: dragOver ? "var(--bg)" : "transparent",
              borderRadius: 10,
              padding: "var(--s-7)",
              textAlign: "center",
              cursor: "pointer",
              transition: "all 160ms ease",
              marginBottom: "var(--s-5)"
            }}>
            
            <div style={{
              width: 60, height: 60, borderRadius: "50%",
              background: "var(--bg)", color: "var(--ink-soft)",
              display: "inline-flex", alignItems: "center", justifyContent: "center",
              marginBottom: 14
            }}>
              <Icon name="upload" size={26} stroke={1.4} />
            </div>
            <div className="serif italic" style={{ fontSize: 22, color: "var(--ink)" }}>
              Drop photos here or click to choose
            </div>
            <div className="muted" style={{ fontSize: 13, marginTop: 6 }}>
              JPG, PNG, or HEIC · up to 12 files
            </div>
            <input
              ref={fileInputRef}
              type="file"
              accept="image/*"
              multiple
              onChange={(e) => handleFiles(e.target.files)}
              style={{ display: "none" }} />
            
          </div>

          {photos.length > 0 &&
          <div style={{
            display: "grid",
            gridTemplateColumns: "repeat(auto-fill, minmax(120px, 1fr))",
            gap: "var(--s-3)",
            marginBottom: "var(--s-6)"
          }}>
              {photos.map((p) =>
            <div key={p.id} style={{
              position: "relative",
              aspectRatio: "1/1",
              borderRadius: 6,
              overflow: "hidden",
              border: "1px solid var(--line-soft)"
            }}>
                  <img src={p.url} alt={p.name} style={{
                width: "100%", height: "100%", objectFit: "cover"
              }} />
                  <button
                type="button"
                onClick={(e) => {e.stopPropagation();setPhotos((arr) => arr.filter((x) => x.id !== p.id));}}
                aria-label="Remove photo"
                style={{
                  position: "absolute", top: 6, right: 6,
                  width: 26, height: 26, borderRadius: "50%",
                  background: "rgba(20,15,10,0.85)", color: "#fff",
                  border: "none", cursor: "pointer",
                  display: "inline-flex", alignItems: "center", justifyContent: "center"
                }}>
                
                    <Icon name="x" size={14} />
                  </button>
                </div>
            )}
              {photos.length < 12 &&
            <button type="button" onClick={() => fileInputRef.current?.click()}
            style={{
              aspectRatio: "1/1", borderRadius: 6,
              border: "1.5px dashed var(--line)",
              background: "transparent",
              color: "var(--ink-muted)",
              cursor: "pointer",
              fontSize: 24
            }}>
                  +
                </button>
            }
            </div>
          }

          <hr style={{ border: "none", borderTop: "1px solid var(--line-soft)", margin: "var(--s-6) 0" }} />

          {/* ABOUT THE ITEM(S) */}
          <h2 className="serif italic" style={{ fontSize: 28, fontWeight: 400, marginBottom: "var(--s-4)" }}>About the piece</h2>
          <div className="form-grid">
            <div className="field full">
              <label>What is it?</label>
              <input value={form.itemType} onChange={(e) => set("itemType", e.target.value)}
              placeholder="e.g. Walnut roll-top desk · Set of Depression glassware · Box of estate jewelry"
              required />
            </div>
            <div className="field full">
              <label>Tell us a little more</label>
              <textarea value={form.description} onChange={(e) => set("description", e.target.value)}
              placeholder="Where did it come from? About how old is it? Any maker's marks or condition notes? Rough dimensions if you know them."
              style={{ minHeight: 130 }}
              required />
            </div>
            <div className="field full">
              <label>Asking price (optional)</label>
              <input value={form.askingPrice} onChange={(e) => set("askingPrice", e.target.value)}
              placeholder="$ — or 'open to offers'" />
            </div>
          </div>

          <hr style={{ border: "none", borderTop: "1px solid var(--line-soft)", margin: "var(--s-6) 0" }} />

          {/* CONTACT */}
          <h2 className="serif italic" style={{ fontSize: 28, fontWeight: 400, marginBottom: "var(--s-4)" }}>How can we reach you?</h2>
          <div className="form-grid">
            <div className="field">
              <label>Your name</label>
              <input value={form.name} onChange={(e) => set("name", e.target.value)} required />
            </div>
            <div className="field">
              <label>Email</label>
              <input type="email" value={form.email} onChange={(e) => set("email", e.target.value)} required />
            </div>
            <div className="field full">
              <label>Phone</label>
              <input value={form.phone} onChange={(e) => set("phone", e.target.value)} placeholder="(352) 555-0100" required />
            </div>
          </div>

          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: "var(--s-7)", gap: 12, flexWrap: "wrap" }}>
            <div className="muted" style={{ fontSize: 13 }}>
              We'll reply within a day or two — usually faster.
            </div>
            <button className="btn btn-primary btn-lg" type="submit">
              Submit {photos.length > 0 && `· ${photos.length} ${photos.length === 1 ? "photo" : "photos"}`}
            </button>
          </div>
        </form>
      </section>

      {/* How it works */}
      <section style={{ padding: "var(--s-7) 0", borderTop: "1px solid var(--line-soft)" }}>
        <div className="section-head" style={{ marginBottom: "var(--s-6)" }}>
          <div>
            <span className="eyebrow">How it works</span>
            <h2 className="serif italic" style={{ fontSize: 40, fontWeight: 400 }}>From your photos to the floor</h2>
          </div>
        </div>
        <div className="selling-steps" style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "var(--s-5)" }}>
          {[
          { n: "01", t: "Send us photos", d: "Use the form above. A few angles is plenty — we'll ask if we need more." },
          { n: "02", t: "We take a look", d: "Within a day or two, you'll hear back. If it's a fit, we'll quote a consignment split or an outright price." },
          { n: "03", t: "Drop off or pickup", d: "Bring it by during open hours, or we can arrange pickup for larger pieces within a 20-mile radius." }].
          map((s) =>
          <div key={s.n} style={{
            borderTop: "1px solid var(--line)",
            paddingTop: "var(--s-4)"
          }}>
              <div className="serif italic" style={{ fontSize: 18, color: "var(--ink-muted)", marginBottom: 6 }}>{s.n}</div>
              <h3 className="serif italic" style={{ fontSize: 26, fontWeight: 400, marginBottom: 8 }}>{s.t}</h3>
              <p style={{ color: "var(--ink-soft)", lineHeight: 1.65 }}>{s.d}</p>
            </div>
          )}
        </div>
      </section>
    </main>);

}

// ════════════════════════════════════════════════════
// ADMIN
// ════════════════════════════════════════════════════

function AdminLogin({ onLogin, navigate }) {
  const [email, setEmail] = useStateI("");
  const [password, setPassword] = useStateI("");
  const [err, setErr] = useStateI("");
  const [busy, setBusy] = useStateI(false);

  const submit = async (e) => {
    e.preventDefault();
    setErr("");
    if (!email || !password) { setErr("Please fill both fields."); return; }
    setBusy(true);
    try {
      const res = await fetch("/api/auth", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email, password }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        setErr(data.error || "Sign in failed. Please try again.");
        setBusy(false);
        return;
      }
      onLogin(data.token, data.admin);
    } catch (e) {
      setErr("Could not reach the server. Check your connection and try again.");
      setBusy(false);
    }
  };

  return (
    <div className="admin-login">
      <form className="admin-login-card" onSubmit={submit}>
        <Logo height={140} className="logo" />
        <h2 className="serif italic">Welcome back</h2>
        <div className="sub">Vendor & Store Administration</div>
        <div className="form-grid" style={{ gridTemplateColumns: "1fr", gap: 16 }}>
          <div className="field"><label>Email</label>
            <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="admin@decadesonmain.com" autoFocus /></div>
          <div className="field"><label>Password</label>
            <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="••••••••" /></div>
        </div>
        {err && <p style={{ color: "var(--terracotta)", fontSize: 13, marginTop: 8 }}>{err}</p>}
        <button className="btn btn-primary" type="submit" style={{ width: "100%", marginTop: 20 }} disabled={busy}>
          {busy ? "Signing in…" : "Sign in"}
        </button>
      </form>
      <button type="button" className="admin-back" onClick={() => navigate({ page: "home" })}>
        ← Back to Decades on Main
      </button>
    </div>);

}

function AdminTopbar({ admin, navigate, onSignOut }) {
  return (
    <header className="admin-topbar">
      <div className="admin-topbar-inner">
        <div className="admin-topbar-left">
          <button className="admin-topbar-link" onClick={() => navigate({ page: "home" })}>
            <Icon name="chevL" size={13} /> View store
          </button>
        </div>
        <div className="admin-topbar-center">
          <a onClick={() => navigate({ page: "home" })} style={{ cursor: "pointer", display: "inline-block" }}>
            <Logo height={110} className="logo" />
          </a>
        </div>
        <div className="admin-topbar-right">
          <div style={{ textAlign: "right" }}>
            <div className="admin-topbar-eyebrow" style={{ fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--ink-muted)" }}>Signed in</div>
            <div style={{ fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 17, lineHeight: 1.1, color: "var(--ink)" }}>{admin.name}</div>
            <button className="admin-topbar-signout" onClick={onSignOut}>Sign out</button>
          </div>
        </div>
      </div>
    </header>);

}

function AdminDashboard({ admin, navigate, onSignOut, events, saveEvent, deleteEvent, products, reloadProducts }) {
  const [tab, setTab] = useStateI("overview");
  const [editingItem, setEditingItem] = useStateI(null);
  const [editingEvent, setEditingEvent] = useStateI(null);
  const [vendors, setVendors] = useStateI([]);
  const [vendorsErr, setVendorsErr] = useStateI("");
  const loadVendors = () => {
    fetch("/api/vendors")
      .then((r) => (r.ok ? r.json() : Promise.reject()))
      .then((d) => { setVendors(Array.isArray(d) ? d : []); setVendorsErr(""); })
      .catch(() => setVendorsErr("notready"));
  };
  useEffectI(() => { loadVendors(); }, []);

  const tabs = [
  { id: "overview", label: "Overview", icon: "dashboard" },
  { id: "items", label: "Items", icon: "box" },
  { id: "orders", label: "Orders", icon: "bag" },
  { id: "subscribers", label: "Subscribers", icon: "mail" },
  { id: "newsletter", label: "Newsletter", icon: "edit" },
  { id: "events", label: "Events", icon: "leaf" },
  { id: "vendors", label: "Vendors", icon: "users" },
  { id: "sales", label: "Sales", icon: "chart" },
  { id: "settings", label: "Settings", icon: "settings" }];


  const liveItems = (products || []).filter((p) => p.status === "live").length;
  const soldItems = (products || []).filter((p) => p.status === "sold").length;
  const vendorCount = new Set((products || []).map((p) => p.vendor).filter(Boolean)).size;

  return (
    <div className="admin">
      <AdminTopbar admin={admin} navigate={navigate} onSignOut={onSignOut} />
      <div className="admin-mobile-tabs">
        <select value={tab} onChange={(e) => setTab(e.target.value)}>
          {tabs.map((t) =>
          <option key={t.id} value={t.id}>{t.label}</option>
          )}
        </select>
      </div>
      <div className="admin-layout">
        <aside className="admin-sidebar">
          <h4>Manage</h4>
          {tabs.map((t) =>
          <button key={t.id}
          className={"admin-tab " + (tab === t.id ? "active" : "")}
          onClick={() => setTab(t.id)}>
              <Icon name={t.icon} size={16} />{t.label}
            </button>
          )}
        </aside>

        <main className="admin-main">
          {tab === "overview" && <AdminOverview liveItems={liveItems} soldItems={soldItems} vendorCount={vendorCount} products={products} />}
          {tab === "items" && <AdminItems products={products} reloadProducts={reloadProducts} setEditingItem={setEditingItem} />}
          {tab === "orders" && <AdminOrders />}
          {tab === "subscribers" && <AdminSubscribers />}
          {tab === "newsletter" && <AdminNewsletter />}
          {tab === "events" && <AdminEvents events={events} setEditingEvent={setEditingEvent} deleteEvent={deleteEvent} />}
          {tab === "vendors" && <AdminVendors products={products} vendors={vendors} vendorsErr={vendorsErr} reloadVendors={loadVendors} />}
          {tab === "sales" && <AdminSales />}
          {tab === "settings" && <AdminSettings />}
        </main>
      </div>

      {editingItem !== null &&
      <ItemEditorModal
        item={editingItem}
        vendors={vendors}
        onClose={() => setEditingItem(null)}
        onSaved={() => { setEditingItem(null); reloadProducts(); }} />
      }
      {editingEvent !== null &&
      <EventEditorModal
        event={editingEvent}
        onClose={() => setEditingEvent(null)}
        onSave={(ev) => {saveEvent(ev);setEditingEvent(null);}} />
      }
    </div>);

}

function AdminOverview({ liveItems, soldItems, vendorCount, products }) {
  const [recentOrders, setRecentOrders] = useStateI(null);
  useEffectI(() => {
    fetch("/api/orders", {
      headers: { Authorization: "Bearer " + (sessionStorage.getItem("dom-admin-token") || "") },
    }).
    then((r) => (r.ok ? r.json() : [])).
    then((d) => setRecentOrders(Array.isArray(d) ? d : [])).
    catch(() => setRecentOrders([]));
  }, []);
  const grossSales = (recentOrders || []).reduce((s, o) => s + Number(o.total || 0), 0);

  const counts = {};
  (products || []).forEach((p) => {
    const n = (p.vendor && p.vendor.trim()) || "Unassigned";
    counts[n] = (counts[n] || 0) + 1;
  });
  const topVendors = Object.keys(counts)
    .map((n) => ({ name: n, count: counts[n] }))
    .sort((a, b) => b.count - a.count)
    .slice(0, 6);
  return (
    <>
      <div className="admin-head">
        <div>
          <span className="eyebrow">Welcome back</span>
          <h1 className="serif italic">Overview</h1>
        </div>
      </div>

      <div className="stat-grid">
        <StatCard label="Gross sales" value={"$" + grossSales.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} />
        <StatCard label="Live items" value={liveItems} />
        <StatCard label="Sold items" value={soldItems} />
        <StatCard label="Active vendors" value={vendorCount} />
      </div>

      <div className="admin-overview-grid" style={{ display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: "var(--s-5)" }}>
        <div className="admin-table">
          <div style={{ padding: "var(--s-4) var(--s-5)", borderBottom: "1px solid var(--line-soft)" }}>
            <h3 className="serif italic" style={{ fontSize: 22, fontWeight: 400 }}>Recent orders</h3>
          </div>
          {recentOrders === null ?
          <div style={{ padding: "var(--s-7) var(--s-5)", textAlign: "center", color: "var(--ink-muted)", fontSize: 14 }}>Loading…</div> :
          recentOrders.length === 0 ?
          <div style={{ padding: "var(--s-7) var(--s-5)", textAlign: "center", color: "var(--ink-muted)", fontSize: 14 }}>
              No orders yet. Online orders will appear here as they come in.
            </div> :
          <table>
              <tbody>
                {recentOrders.slice(0, 5).map((o) =>
              <tr key={o.id}>
                    <td>
                      <div style={{ fontWeight: 500, color: "var(--ink)" }}>DOM-{String(o.id).slice(0, 8).toUpperCase()}</div>
                      <div style={{ fontSize: 12, color: "var(--ink-muted)" }}>{new Date(o.created_at).toLocaleDateString()}</div>
                    </td>
                    <td>{o.customer_name || "—"}</td>
                    <td style={{ textAlign: "right", fontWeight: 500, color: "var(--ink)" }}>
                      ${Number(o.total || 0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
                    </td>
                  </tr>
              )}
              </tbody>
            </table>}
        </div>

        <div className="admin-table">
          <div style={{ padding: "var(--s-4) var(--s-5)", borderBottom: "1px solid var(--line-soft)" }}>
            <h3 className="serif italic" style={{ fontSize: 22, fontWeight: 400 }}>Vendors</h3>
          </div>
          <table>
            <tbody>
              {topVendors.length === 0 &&
              <tr><td style={{ padding: "var(--s-5)", color: "var(--ink-muted)", fontSize: 13 }}>No dealers yet.</td></tr>}
              {topVendors.map((v, i) =>
              <tr key={v.name}>
                  <td style={{ width: 30, color: "var(--ink-muted)" }}>{i + 1}</td>
                  <td>
                    <div style={{ fontWeight: 500, color: "var(--ink)" }}>{v.name}</div>
                    <div style={{ fontSize: 12, color: "var(--ink-muted)" }}>{v.count} {v.count === 1 ? "item" : "items"}</div>
                  </td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
      </div>
    </>);

}

function StatCard({ label, value, delta }) {
  const down = delta && delta.includes("-");
  return (
    <div className="stat-card">
      <div className="label">{label}</div>
      <div className="value">{value}</div>
      {delta && <div className={"delta " + (down ? "down" : "")}>{delta}</div>}
    </div>);

}

function AdminItems({ products, reloadProducts, setEditingItem }) {
  const [filterStatus, setFilterStatus] = useStateI("all");
  const [search, setSearch] = useStateI("");
  const [deletingId, setDeletingId] = useStateI(null);

  const filtered = (products || []).filter((p) => {
    if (filterStatus !== "all" && p.status !== filterStatus) return false;
    if (search && !(p.name || "").toLowerCase().includes(search.toLowerCase())) return false;
    return true;
  });

  const remove = async (p) => {
    if (!confirm('Delete "' + p.name + '"? This cannot be undone.')) return;
    setDeletingId(p.id);
    try {
      const res = await fetch("/api/products?id=" + encodeURIComponent(p.id), {
        method: "DELETE",
        headers: { Authorization: "Bearer " + (sessionStorage.getItem("dom-admin-token") || "") },
      });
      if (!res.ok) throw new Error();
      reloadProducts();
    } catch (e) {
      alert("Could not delete that item. Please try again.");
    } finally {
      setDeletingId(null);
    }
  };

  return (
    <>
      <div className="admin-head">
        <div>
          <span className="eyebrow">Inventory</span>
          <h1 className="serif italic">Items</h1>
        </div>
        <button className="btn btn-primary" onClick={() => setEditingItem({})}>
          <Icon name="plus" size={14} /> Add item
        </button>
      </div>

      <div style={{ display: "flex", gap: 12, marginBottom: "var(--s-5)", flexWrap: "wrap" }}>
        <div className="segmented" style={{ background: "var(--bg-card)" }}>
          {["all", "live", "draft", "sold"].map((s) =>
          <button key={s} className={filterStatus === s ? "active" : ""}
          onClick={() => setFilterStatus(s)}>{s}</button>
          )}
        </div>
        <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", borderRadius: 999, fontSize: 14, color: "var(--ink)", flex: 1, minWidth: 240 }} />
      </div>

      <div className="admin-table admin-table--items">
        <table>
          <thead><tr><th></th><th>Item</th><th>Dealer</th><th>Category</th><th>Price</th><th>Status</th><th></th></tr></thead>
          <tbody>
            {filtered.map((p) =>
            <tr key={p.id}>
                <td>
                  {p.image_url ?
                  <div className="thumb-cell" style={{ backgroundImage: "url(" + p.image_url + ")", backgroundSize: "cover", backgroundPosition: "center" }} /> :
                  <div className="thumb-cell" style={{ background: window.CATEGORY_TINT[p.category]?.bg || "#bba98a" }}
                    dangerouslySetInnerHTML={{ __html: window.categoryGlyph(p.category, window.CATEGORY_TINT[p.category]?.ink || "#fff") }} />}
                </td>
                <td><div style={{ color: "var(--ink)", fontWeight: 500 }}>{p.name}</div></td>
                <td>{p.vendor || "—"}</td>
                <td>{window.CATEGORIES.find((c) => c.id === p.category)?.name || "—"}</td>
                <td style={{ color: "var(--ink)", fontWeight: 500 }}>${Number(p.price || 0).toLocaleString()}</td>
                <td><span className={"status-pill " + p.status}>{p.status}</span></td>
                <td style={{ textAlign: "right", whiteSpace: "nowrap" }}>
                  <button className="btn btn-ghost btn-sm" onClick={() => setEditingItem(p)}><Icon name="edit" size={13} /></button>
                  <button className="btn btn-ghost btn-sm" disabled={deletingId === p.id} onClick={() => remove(p)}>
                    <Icon name="trash" size={13} />
                  </button>
                </td>
              </tr>
            )}
            {filtered.length === 0 &&
            <tr><td colSpan="7" style={{ textAlign: "center", padding: 40, color: "var(--ink-muted)" }}>
                {(products || []).length === 0
                ? 'No items yet. Click "Add item" to list your first piece.'
                : "No items match."}
              </td></tr>
            }
          </tbody>
        </table>
      </div>
    </>);

}

function AdminEvents({ events, setEditingEvent, deleteEvent }) {
  const sorted = [...(events || [])].sort((a, b) => (a.date || "").localeCompare(b.date || ""));
  return (
    <>
      <div className="admin-head">
        <div>
          <span className="eyebrow">Calendar</span>
          <h1 className="serif italic">Events</h1>
        </div>
        <button className="btn btn-primary" onClick={() => setEditingEvent({})}>
          <Icon name="plus" size={14} /> New event
        </button>
      </div>

      <div className="admin-table admin-table--events">
        <table>
          <thead>
            <tr>
              <th style={{ width: 110 }}>Date</th>
              <th>Event</th>
              <th>Tag</th>
              <th>Status</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {sorted.length === 0 &&
            <tr><td colSpan="5" style={{ textAlign: "center", padding: 40, color: "var(--ink-muted)" }}>
                No events yet. Click <strong>New event</strong> to add one.
              </td></tr>
            }
            {sorted.map((ev) =>
            <tr key={ev.id}>
                <td>
                  <div style={{ fontWeight: 500, color: "var(--ink)" }}>{ev.date}</div>
                  <div style={{ fontSize: 12, color: "var(--ink-muted)" }}>{ev.time}</div>
                </td>
                <td>
                  <div style={{ fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 18, color: "var(--ink)" }}>{ev.title}</div>
                  <div style={{ fontSize: 12, color: "var(--ink-muted)" }}>{ev.location || "—"}</div>
                </td>
                <td>{ev.tag || "—"}</td>
                <td><span className={"status-pill " + ev.status}>{ev.status}</span></td>
                <td style={{ textAlign: "right" }}>
                  <button className="btn btn-ghost btn-sm" onClick={() => setEditingEvent(ev)}><Icon name="edit" size={13} /></button>
                  <button className="btn btn-ghost btn-sm" onClick={() => {
                  if (confirm("Delete \"" + ev.title + "\"?")) deleteEvent(ev.id);
                }}><Icon name="trash" size={13} /></button>
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
    </>);

}

function EventEditorModal({ event, onClose, onSave }) {
  const isEdit = !!event?.id;
  const [form, setForm] = useStateI({
    id: event?.id,
    title: event?.title || "",
    date: event?.date || new Date().toISOString().slice(0, 10),
    time: event?.time || "",
    location: event?.location || "",
    description: event?.description || "",
    tag: event?.tag || "",
    status: event?.status || "live"
  });
  const set = (k, v) => setForm((f) => ({ ...f, [k]: v }));
  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <h3>{isEdit ? "Edit event" : "New event"}</h3>
          <button className="close-x" onClick={onClose}><Icon name="x" size={18} /></button>
        </div>
        <div className="modal-body">
          <div className="form-grid">
            <div className="field full"><label>Event title</label>
              <input value={form.title} onChange={(e) => set("title", e.target.value)} placeholder="e.g. Summer Sidewalk Sale" autoFocus /></div>
            <div className="field"><label>Date</label>
              <input type="date" value={form.date} onChange={(e) => set("date", e.target.value)} /></div>
            <div className="field"><label>Time</label>
              <input value={form.time} onChange={(e) => set("time", e.target.value)} placeholder="11:00 AM – 6:00 PM" /></div>
            <div className="field full"><label>Location</label>
              <input value={form.location} onChange={(e) => set("location", e.target.value)} placeholder="Out front, weather permitting" /></div>
            <div className="field"><label>Tag</label>
              <select value={form.tag} onChange={(e) => set("tag", e.target.value)}>
                <option value="">(none)</option>
                <option value="Sale">Sale</option>
                <option value="Social">Social</option>
                <option value="Consignment">Consignment</option>
                <option value="Appraisal">Appraisal</option>
                <option value="Demo">Demo</option>
              </select>
            </div>
            <div className="field"><label>Status</label>
              <select value={form.status} onChange={(e) => set("status", e.target.value)}>
                <option value="live">Live (visible on home)</option>
                <option value="draft">Draft (hidden)</option>
              </select>
            </div>
            <div className="field full"><label>Description</label>
              <textarea value={form.description} onChange={(e) => set("description", e.target.value)}
              placeholder="A short note about what's happening — what to expect, who to call, etc." /></div>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn btn-ghost" onClick={onClose}>Cancel</button>
          <button className="btn btn-primary" onClick={() => onSave(form)} disabled={!form.title || !form.date}>
            {isEdit ? "Save changes" : "Create event"}
          </button>
        </div>
      </div>
    </div>);

}

// Resize/compress an image file in the browser, returns a JPEG data URL.
function resizeImageToDataUrl(file, maxDim, quality) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onerror = () => reject(new Error("Could not read the file"));
    reader.onload = () => {
      const img = new Image();
      img.onerror = () => reject(new Error("That file isn't a readable image"));
      img.onload = () => {
        let w = img.width, h = img.height;
        if (w > maxDim || h > maxDim) {
          if (w >= h) { h = Math.round((h * maxDim) / w); w = maxDim; }
          else { w = Math.round((w * maxDim) / h); h = maxDim; }
        }
        const canvas = document.createElement("canvas");
        canvas.width = w;
        canvas.height = h;
        canvas.getContext("2d").drawImage(img, 0, 0, w, h);
        resolve(canvas.toDataURL("image/jpeg", quality));
      };
      img.src = reader.result;
    };
    reader.readAsDataURL(file);
  });
}

function ItemEditorModal({ item, vendors, onClose, onSaved }) {
  const isEdit = !!(item && item.id);
  const [form, setForm] = useStateI({
    id: item && item.id,
    name: (item && item.name) || "",
    vendor: (item && item.vendor) || "",
    category: (item && item.category) || "furniture",
    price: item && item.price != null ? item.price : "",
    era: (item && item.era) || "",
    origin: (item && item.origin) || "",
    dims: (item && item.dims) || "",
    condition: (item && item.condition) || "",
    description: (item && item.description) || "",
    status: (item && item.status) || "live",
    featured: item && item.featured ? 1 : 0,
    quantity: item && item.quantity != null ? item.quantity : 1,
    weight_lbs: item && item.weight_lbs != null ? item.weight_lbs : "",
    length_in: item && item.length_in != null ? item.length_in : "",
    width_in: item && item.width_in != null ? item.width_in : "",
    height_in: item && item.height_in != null ? item.height_in : "",
    images: (item && Array.isArray(item.images) && item.images.length)
      ? item.images
      : (item && item.image_url) ? [item.image_url] : [],
  });
  const [busy, setBusy] = useStateI(false);
  const [uploading, setUploading] = useStateI(false);
  const [err, setErr] = useStateI("");
  const set = (k, v) => setForm((f) => ({ ...f, [k]: v }));
  const token = () => sessionStorage.getItem("dom-admin-token") || "";

  // Options for the vendor dropdown: the saved vendors, plus this item's
  // current vendor if it isn't in the saved list (so editing preserves it).
  const vendorNames = (() => {
    const names = (vendors || []).map((v) => v.name).filter(Boolean);
    if (form.vendor && !names.includes(form.vendor)) names.unshift(form.vendor);
    return names;
  })();

  const handleFile = async (e) => {
    const files = Array.from(e.target.files || []);
    e.target.value = "";
    if (!files.length) return;
    setErr("");
    setUploading(true);
    try {
      for (const file of files) {
        const dataUrl = await resizeImageToDataUrl(file, 1400, 0.82);
        const res = await fetch("/api/upload", {
          method: "POST",
          headers: { "Content-Type": "application/json", Authorization: "Bearer " + token() },
          body: JSON.stringify({ filename: file.name, contentType: "image/jpeg", dataBase64: dataUrl }),
        });
        const data = await res.json().catch(() => ({}));
        if (!res.ok) throw new Error(data.error || "Upload failed");
        setForm((f) => ({ ...f, images: [...f.images, data.url] }));
      }
    } catch (e2) {
      setErr("Photo upload failed: " + (e2.message || "please try again"));
    } finally {
      setUploading(false);
    }
  };

  const removeImage = (idx) => setForm((f) => ({ ...f, images: f.images.filter((_, i) => i !== idx) }));
  const makeCover = (idx) => setForm((f) => {
    if (idx === 0) return f;
    const next = [...f.images];
    const [pick] = next.splice(idx, 1);
    next.unshift(pick);
    return { ...f, images: next };
  });

  const save = async () => {
    setErr("");
    if (!form.name.trim()) { setErr("Please enter an item name."); return; }
    setBusy(true);
    const payload = {
      name: form.name.trim(),
      price: Number(form.price) || 0,
      vendor: form.vendor.trim(),
      category: form.category,
      era: form.era,
      origin: form.origin,
      dims: form.dims,
      condition: form.condition,
      description: form.description,
      status: form.status,
      featured: form.featured ? 1 : 0,
      quantity: Math.max(0, parseInt(form.quantity, 10) || 0),
      weight_lbs: form.weight_lbs === "" ? null : Math.max(0, Number(form.weight_lbs) || 0),
      length_in: form.length_in === "" ? null : Math.max(0, Number(form.length_in) || 0),
      width_in: form.width_in === "" ? null : Math.max(0, Number(form.width_in) || 0),
      height_in: form.height_in === "" ? null : Math.max(0, Number(form.height_in) || 0),
      images: form.images,
      image_url: form.images[0] || "",
    };
    try {
      const res = await fetch(
        isEdit ? "/api/products?id=" + encodeURIComponent(form.id) : "/api/products",
        {
          method: isEdit ? "PUT" : "POST",
          headers: { "Content-Type": "application/json", Authorization: "Bearer " + token() },
          body: JSON.stringify(payload),
        }
      );
      const data = await res.json().catch(() => ({}));
      if (!res.ok) throw new Error(data.error || "Save failed");
      onSaved();
    } catch (e3) {
      setErr(e3.message || "Could not save. Please try again.");
      setBusy(false);
    }
  };

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <h3>{isEdit ? "Edit item" : "New item"}</h3>
          <button className="close-x" onClick={onClose}><Icon name="x" size={18} /></button>
        </div>
        <div className="modal-body">
          <div className="field" style={{ marginBottom: 16 }}>
            <label>Photos</label>
            <div className="item-photos">
              {form.images.map((url, i) =>
              <div key={url + i} className="item-photo">
                  <img src={url} alt="" />
                  {i === 0 && <span className="item-photo-cover">Cover</span>}
                  {i !== 0 &&
                  <button type="button" className="item-photo-star" title="Make cover photo" onClick={() => makeCover(i)}>★</button>}
                  <button type="button" className="item-photo-remove" title="Remove" onClick={() => removeImage(i)}>
                    <Icon name="x" size={12} />
                  </button>
                </div>
              )}
              <label className="item-photo-add">
                <Icon name="upload" size={20} />
                <span>{uploading ? "Uploading…" : "Add photo"}</span>
                <input type="file" accept="image/*" multiple onChange={handleFile} style={{ display: "none" }} />
              </label>
            </div>
            <p className="muted" style={{ fontSize: 12, marginTop: 6 }}>The first photo is the cover. Add several — buyers can flip through them.</p>
          </div>

          <div className="field" style={{ marginBottom: 12 }}>
            <label>Item name</label>
            <input value={form.name} onChange={(e) => set("name", e.target.value)} placeholder="e.g. Walnut Tambour Desk" autoFocus />
          </div>
          <div className="form-grid" style={{ marginBottom: 12 }}>
            <div className="field"><label>Vendor</label>
              <select value={form.vendor} onChange={(e) => set("vendor", e.target.value)}>
                <option value="">— No vendor —</option>
                {vendorNames.map((n) => <option key={n} value={n}>{n}</option>)}
              </select>
              {vendorNames.length === 0 &&
              <p className="muted" style={{ fontSize: 12, marginTop: 4 }}>Add vendors in the Vendors tab to pick them here.</p>}
            </div>
            <div className="field"><label>Category</label>
              <select value={form.category} onChange={(e) => set("category", e.target.value)}>
                {window.CATEGORIES.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}
              </select>
            </div>
          </div>

          <div className="form-grid">
            <div className="field"><label>Price ($)</label>
              <input value={form.price} onChange={(e) => set("price", e.target.value)} type="number" min="0" /></div>
            <div className="field"><label>Quantity available</label>
              <input value={form.quantity} onChange={(e) => set("quantity", e.target.value)} type="number" min="0" step="1" />
              <p className="muted" style={{ fontSize: 12, marginTop: 4 }}>How many of this exact piece are in stock. It only shows as sold once they're all gone.</p>
            </div>
            <div className="field"><label>Status</label>
              <select value={form.status} onChange={(e) => set("status", e.target.value)}>
                <option value="live">Available</option>
                <option value="draft">Draft (hidden)</option>
                <option value="sold">Sold</option>
              </select>
            </div>
            <div className="field"><label>Era</label><input value={form.era} onChange={(e) => set("era", e.target.value)} placeholder="c. 1940" /></div>
            <div className="field"><label>Origin</label><input value={form.origin} onChange={(e) => set("origin", e.target.value)} placeholder="USA" /></div>
            <div className="field full"><label>Dimensions</label><input value={form.dims} onChange={(e) => set("dims", e.target.value)} placeholder="e.g. 48 x 21 x 64 inches" /></div>
            <div className="field full"><label>Condition</label><input value={form.condition} onChange={(e) => set("condition", e.target.value)} placeholder="Excellent — original hardware" /></div>
            <div className="field full"><label>Description</label><textarea value={form.description} onChange={(e) => set("description", e.target.value)} /></div>
            <div className="field full">
              <label style={{ display: "flex", alignItems: "center", gap: 8, cursor: "pointer" }}>
                <input type="checkbox" checked={!!form.featured} onChange={(e) => set("featured", e.target.checked ? 1 : 0)} style={{ width: "auto" }} />
                Feature this piece on the home page
              </label>
            </div>
          </div>

          <div style={{ marginTop: 18, paddingTop: 16, borderTop: "1px solid var(--line-soft)" }}>
            <label style={{ fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--ink-muted)", display: "block", marginBottom: 10 }}>
              Shipping size & weight
            </label>
            <div className="form-grid">
              <div className="field"><label>Weight (lb)</label>
                <input value={form.weight_lbs} onChange={(e) => set("weight_lbs", e.target.value)} type="number" min="0" step="0.1" placeholder="e.g. 12" /></div>
              <div className="field"><label>Length (in)</label>
                <input value={form.length_in} onChange={(e) => set("length_in", e.target.value)} type="number" min="0" step="0.1" placeholder="e.g. 24" /></div>
              <div className="field"><label>Width (in)</label>
                <input value={form.width_in} onChange={(e) => set("width_in", e.target.value)} type="number" min="0" step="0.1" placeholder="e.g. 18" /></div>
              <div className="field"><label>Height (in)</label>
                <input value={form.height_in} onChange={(e) => set("height_in", e.target.value)} type="number" min="0" step="0.1" placeholder="e.g. 30" /></div>
            </div>
            <p className="muted" style={{ fontSize: 12, marginTop: 6 }}>Used to calculate live shipping rates at checkout. Fill these in for anything that ships.</p>
          </div>
          {err && <p style={{ color: "var(--terracotta)", fontSize: 13, marginTop: 8 }}>{err}</p>}
        </div>
        <div className="modal-foot">
          <button className="btn btn-ghost" onClick={onClose} disabled={busy}>Cancel</button>
          <button className="btn btn-primary" onClick={save} disabled={busy || uploading}>
            {busy ? "Saving…" : isEdit ? "Save changes" : "Create item"}
          </button>
        </div>
      </div>
    </div>);

}

function AdminVendors({ products, vendors, vendorsErr, reloadVendors }) {
  const [name, setName] = useStateI("");
  const [busy, setBusy] = useStateI(false);
  const [err, setErr] = useStateI("");
  const token = () => sessionStorage.getItem("dom-admin-token") || "";

  // Item counts per vendor name, from the products.
  const counts = {};
  (products || []).forEach((p) => {
    const n = (p.vendor && p.vendor.trim()) || "";
    if (!n) return;
    if (!counts[n]) counts[n] = { total: 0, live: 0, sold: 0 };
    counts[n].total++;
    if (p.status === "sold") counts[n].sold++;
    else if (p.status === "live") counts[n].live++;
  });

  const add = async (e) => {
    e.preventDefault();
    setErr("");
    const v = name.trim();
    if (!v) return;
    setBusy(true);
    try {
      const r = await fetch("/api/vendors", {
        method: "POST",
        headers: { "Content-Type": "application/json", Authorization: "Bearer " + token() },
        body: JSON.stringify({ name: v }),
      });
      const data = await r.json().catch(() => ({}));
      if (!r.ok) { setErr(data.error || "Could not add the vendor."); return; }
      setName("");
      reloadVendors();
    } catch (e2) {
      setErr("Could not reach the server. Please try again.");
    } finally {
      setBusy(false);
    }
  };

  const remove = async (vendor) => {
    const c = counts[vendor.name];
    const msg = c && c.total ?
    "Remove \"" + vendor.name + "\"? Its " + c.total + " item(s) keep their label but it leaves your saved vendor list." :
    "Remove \"" + vendor.name + "\"?";
    if (!confirm(msg)) return;
    try {
      await fetch("/api/vendors?id=" + encodeURIComponent(vendor.id), {
        method: "DELETE",
        headers: { Authorization: "Bearer " + token() },
      });
      reloadVendors();
    } catch (e3) {}
  };

  return (
    <>
      <div className="admin-head">
        <div>
          <span className="eyebrow">Booths & dealers</span>
          <h1 className="serif italic">Vendors</h1>
        </div>
      </div>

      <form onSubmit={add} style={{ display: "flex", gap: 10, alignItems: "flex-end", marginBottom: "var(--s-4)", flexWrap: "wrap" }}>
        <div className="field" style={{ flex: 1, minWidth: 220 }}>
          <label>Add a vendor</label>
          <input value={name} onChange={(e) => setName(e.target.value)} placeholder="e.g. Jane's Finds — Booth 12" />
        </div>
        <button className="btn btn-primary" type="submit" disabled={busy || !name.trim()}>
          {busy ? "Adding…" : "Add vendor"}
        </button>
      </form>
      {err && <p style={{ color: "var(--terracotta)", fontSize: 13, marginTop: -4, marginBottom: 12 }}>{err}</p>}

      {vendorsErr ?
      <div className="admin-table"><div style={{ padding: 28, color: "var(--ink-muted)", fontSize: 14, lineHeight: 1.7 }}>
          Couldn't load vendors — the <code>vendors</code> table may not exist yet. Create it in Supabase (one-time setup), then refresh this page.
        </div></div> :

      <div className="admin-table admin-table--vendors">
        <table>
          <thead><tr><th>Vendor</th><th>Items</th><th>Available</th><th>Sold</th><th></th></tr></thead>
          <tbody>
            {(vendors || []).length === 0 &&
            <tr><td colSpan="5" style={{ textAlign: "center", padding: 40, color: "var(--ink-muted)" }}>
                No vendors yet. Add your dealers above, then choose them when posting an item.
              </td></tr>
            }
            {(vendors || []).map((v) => {
              const c = counts[v.name] || { total: 0, live: 0, sold: 0 };
              return (
                <tr key={v.id}>
                  <td style={{ color: "var(--ink)", fontWeight: 500 }}>{v.name}</td>
                  <td data-label="Items">{c.total}</td>
                  <td data-label="Available">{c.live}</td>
                  <td data-label="Sold">{c.sold}</td>
                  <td style={{ textAlign: "right" }}>
                    <button className="btn btn-ghost btn-sm" onClick={() => remove(v)}>Remove</button>
                  </td>
                </tr>);

            })}
          </tbody>
        </table>
      </div>
      }
    </>);

}

function AdminOrders() {
  const [orders, setOrders] = useStateI(null);
  const [busy, setBusy] = useStateI(null);
  const [page, setPage] = useStateI(0);

  const token = () => sessionStorage.getItem("dom-admin-token") || "";

  const load = () => {
    fetch("/api/orders", { headers: { Authorization: "Bearer " + token() } }).
    then((r) => (r.ok ? r.json() : [])).
    then((d) => { setOrders(Array.isArray(d) ? d : []); setPage(0); }).
    catch(() => setOrders([]));
  };
  useEffectI(load, []);

  const remove = async (o) => {
    const ref = "DOM-" + String(o.id).slice(0, 8).toUpperCase();
    if (!confirm("Delete order " + ref + "? This removes it permanently and puts its item(s) back up for sale.")) return;
    setBusy(o.id);
    try {
      await fetch("/api/orders?id=" + encodeURIComponent(o.id), {
        method: "DELETE",
        headers: { Authorization: "Bearer " + token() },
      });
      load();
    } finally {
      setBusy(null);
    }
  };

  const allOrders = orders || [];
  const totalPages = Math.max(1, Math.ceil(allOrders.length / SALES_PAGE_SIZE));
  const pageOrders = allOrders.slice(page * SALES_PAGE_SIZE, (page + 1) * SALES_PAGE_SIZE);

  return (
    <>
      <div className="admin-head">
        <div>
          <span className="eyebrow">Sales</span>
          <h1 className="serif italic">Orders</h1>
        </div>
        {totalPages > 1 && (
          <span style={{ fontSize: 13, color: "var(--ink-muted)" }}>{page + 1} / {totalPages}</span>
        )}
      </div>
      <div className="admin-table">
        <table>
          <thead><tr><th>Order</th><th>Customer</th><th>Items</th><th>Fulfillment</th><th>Total</th><th></th></tr></thead>
          <tbody>
            {orders === null &&
            <tr><td colSpan="6" style={{ textAlign: "center", padding: 40, color: "var(--ink-muted)" }}>Loading…</td></tr>}
            {orders && allOrders.length === 0 &&
            <tr><td colSpan="6" style={{ textAlign: "center", padding: 40, color: "var(--ink-muted)" }}>
                No orders yet. Online orders will appear here as they come in.
              </td></tr>}
            {orders && pageOrders.map((o) =>
            <tr key={o.id}>
                <td>
                  <div style={{ fontWeight: 500, color: "var(--ink)" }}>DOM-{String(o.id).slice(0, 8).toUpperCase()}</div>
                  <div style={{ fontSize: 12, color: "var(--ink-muted)" }}>{new Date(o.created_at).toLocaleDateString()}</div>
                </td>
                <td>
                  <div style={{ color: "var(--ink)" }}>{o.customer_name || "—"}</div>
                  <div style={{ fontSize: 12, color: "var(--ink-muted)" }}>{o.customer_email}</div>
                  {o.customer_phone && <div style={{ fontSize: 12, color: "var(--ink-muted)" }}>{o.customer_phone}</div>}
                  {o.fulfillment === "ship" && o.shipping_address &&
                  <div style={{ fontSize: 12, color: "var(--ink-muted)", marginTop: 2 }}>{o.shipping_address}</div>}
                </td>
                <td>{(o.items || []).map((it) => it.name + (it.qty > 1 ? " ×" + it.qty : "")).join(", ")}</td>
                <td>{o.fulfillment === "pickup" ? "Pickup" : "Ship"}</td>
                <td style={{ fontWeight: 500, color: "var(--ink)" }}>
                  ${Number(o.total || 0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
                </td>
                <td style={{ textAlign: "right", whiteSpace: "nowrap" }}>
                  <button className="btn btn-ghost btn-sm" disabled={busy === o.id} onClick={() => remove(o)}>
                    <Icon name="trash" size={13} />
                  </button>
                </td>
              </tr>
            )}
          </tbody>
        </table>
        {orders && totalPages > 1 && (
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "var(--s-4) var(--s-5)", borderTop: "1px solid var(--line-soft)" }}>
            <button className="btn btn-ghost btn-sm" disabled={page === 0} onClick={() => setPage((p) => p - 1)}>
              ← Previous
            </button>
            <span style={{ fontSize: 13, color: "var(--ink-muted)" }}>
              {page * SALES_PAGE_SIZE + 1}–{Math.min((page + 1) * SALES_PAGE_SIZE, allOrders.length)} of {allOrders.length}
            </span>
            <button className="btn btn-ghost btn-sm" disabled={page >= totalPages - 1} onClick={() => setPage((p) => p + 1)}>
              Next →
            </button>
          </div>
        )}
      </div>
    </>);

}

function AdminSubscribers() {
  const [subs, setSubs] = useStateI(null);
  const [busy, setBusy] = useStateI(null);

  const token = () => sessionStorage.getItem("dom-admin-token") || "";

  const load = () => {
    fetch("/api/subscribers", { headers: { Authorization: "Bearer " + token() } }).
    then((r) => (r.ok ? r.json() : [])).
    then((d) => setSubs(Array.isArray(d) ? d : [])).
    catch(() => setSubs([]));
  };
  useEffectI(load, []);

  const setStatus = async (id, status) => {
    setBusy(id);
    try {
      await fetch("/api/subscribers?id=" + encodeURIComponent(id), {
        method: "PATCH",
        headers: { "Content-Type": "application/json", Authorization: "Bearer " + token() },
        body: JSON.stringify({ status: status }),
      });
      load();
    } finally {
      setBusy(null);
    }
  };

  const remove = async (id, email) => {
    if (!confirm('Remove "' + email + '" from the list permanently?')) return;
    setBusy(id);
    try {
      await fetch("/api/subscribers?id=" + encodeURIComponent(id), {
        method: "DELETE",
        headers: { Authorization: "Bearer " + token() },
      });
      load();
    } finally {
      setBusy(null);
    }
  };

  const exportCsv = () => {
    if (!subs || subs.length === 0) return;
    const header = "email,phone,joined,status\n";
    const rows = subs.map((s) =>
    [s.email, s.phone || "", new Date(s.created_at).toISOString(), s.status].join(",")).
    join("\n");
    const blob = new Blob([header + rows], { type: "text/csv" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "decades-subscribers.csv";
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  };

  const active = (subs || []).filter((s) => s.status === "subscribed");

  return (
    <>
      <div className="admin-head">
        <div>
          <span className="eyebrow">Mailing list</span>
          <h1 className="serif italic">Subscribers</h1>
        </div>
        <button className="btn btn-outline btn-sm" onClick={exportCsv} disabled={!subs || subs.length === 0}>
          Export CSV
        </button>
      </div>

      <div className="stat-grid">
        <StatCard label="Total" value={(subs || []).length} />
        <StatCard label="Active" value={active.length} />
        <StatCard label="Unsubscribed" value={(subs || []).length - active.length} />
      </div>

      <div className="admin-table admin-table--subscribers">
        <table>
          <thead><tr><th>Email</th><th>Joined</th><th>Status</th><th></th></tr></thead>
          <tbody>
            {subs === null &&
            <tr><td colSpan="4" style={{ textAlign: "center", padding: 40, color: "var(--ink-muted)" }}>Loading…</td></tr>}
            {subs && subs.length === 0 &&
            <tr><td colSpan="4" style={{ textAlign: "center", padding: 40, color: "var(--ink-muted)" }}>
                No subscribers yet. Sign-ups from the home page will appear here.
              </td></tr>}
            {subs && subs.map((s) =>
            <tr key={s.id}>
                <td style={{ color: "var(--ink)" }}>
                  {s.email}
                  {s.phone && <div style={{ fontSize: 12, color: "var(--ink-muted)" }}>{s.phone}</div>}
                </td>
                <td>{new Date(s.created_at).toLocaleDateString()}</td>
                <td><span className={"status-pill " + (s.status === "subscribed" ? "live" : "draft")}>{s.status}</span></td>
                <td style={{ textAlign: "right", whiteSpace: "nowrap" }}>
                  {s.status === "subscribed" ?
                <button className="btn btn-ghost btn-sm" disabled={busy === s.id} onClick={() => setStatus(s.id, "unsubscribed")}>
                      Unsubscribe
                    </button> :
                <button className="btn btn-ghost btn-sm" disabled={busy === s.id} onClick={() => setStatus(s.id, "subscribed")}>
                      Resubscribe
                    </button>}
                  <button className="btn btn-ghost btn-sm" disabled={busy === s.id} onClick={() => remove(s.id, s.email)}>
                    <Icon name="trash" size={13} />
                  </button>
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
    </>);

}

function AdminNewsletter() {
  const [subject, setSubject] = useStateI("");
  const [message, setMessage] = useStateI("");
  const [busy, setBusy] = useStateI(false);
  const [result, setResult] = useStateI(null);
  const [err, setErr] = useStateI("");
  const [activeCount, setActiveCount] = useStateI(null);

  const token = () => sessionStorage.getItem("dom-admin-token") || "";

  useEffectI(() => {
    fetch("/api/subscribers", { headers: { Authorization: "Bearer " + token() } }).
    then((r) => (r.ok ? r.json() : [])).
    then((d) => {
      const arr = Array.isArray(d) ? d : [];
      setActiveCount(arr.filter((s) => s.status === "subscribed").length);
    }).
    catch(() => setActiveCount(0));
  }, []);

  const send = async (mode) => {
    setErr("");
    setResult(null);
    if (!subject.trim() || !message.trim()) {
      setErr("Please add a subject and a message.");
      return;
    }
    if (mode === "all") {
      const n = activeCount || 0;
      if (n === 0) { setErr("No active subscribers."); return; }
      if (!confirm("Send to " + n + " active subscriber" + (n === 1 ? "" : "s") + "? This cannot be undone.")) return;
    }
    setBusy(true);
    try {
      const r = await fetch("/api/newsletter", {
        method: "POST",
        headers: { "Content-Type": "application/json", Authorization: "Bearer " + token() },
        body: JSON.stringify({ subject: subject, message: message, mode: mode }),
      });
      const d = await r.json().catch(() => ({}));
      if (!r.ok) {
        setErr(d.error || "Could not send. Please try again.");
        setBusy(false);
        return;
      }
      setResult({ ...d, mode: mode });
      setBusy(false);
      if (mode === "all") { setSubject(""); setMessage(""); }
    } catch (e) {
      setErr("Something went wrong. Please try again.");
      setBusy(false);
    }
  };

  return (
    <>
      <div className="admin-head">
        <div>
          <span className="eyebrow">Decades Dispatch</span>
          <h1 className="serif italic">Newsletter</h1>
        </div>
      </div>

      <div className="form-grid" style={{ maxWidth: 720, gridTemplateColumns: "1fr" }}>
        <div className="field full">
          <label>Subject</label>
          <input value={subject} onChange={(e) => setSubject(e.target.value)} placeholder="What's the email about?" />
        </div>
        <div className="field full">
          <label>Message</label>
          <textarea value={message} onChange={(e) => setMessage(e.target.value)} rows={14}
            placeholder={"Write your newsletter here. Line breaks become paragraphs.\n\nThe Decades on Main logo and an unsubscribe link are added automatically."} />
        </div>
        <div className="field full" style={{ display: "flex", gap: 12, alignItems: "center", flexWrap: "wrap" }}>
          <button className="btn btn-outline" onClick={() => send("test")} disabled={busy || !subject.trim() || !message.trim()}>
            {busy ? "Sending…" : "Send test to me"}
          </button>
          <button className="btn btn-primary" onClick={() => send("all")}
            disabled={busy || !subject.trim() || !message.trim() || activeCount === 0}>
            {busy ? "Sending…" :
            activeCount === null ? "Send to subscribers" :
            "Send to " + activeCount + " subscriber" + (activeCount === 1 ? "" : "s")}
          </button>
        </div>
        {err &&
        <div className="field full" style={{ color: "var(--terracotta)", fontSize: 13 }}>{err}</div>}
        {result &&
        <div className="field full" style={{ color: "var(--sage-dark)", fontSize: 13, lineHeight: 1.6 }}>
            ✓ {result.mode === "test" ? "Test sent" : "Sent"} to {result.sent} of {result.total} by email{result.failed > 0 ? " (" + result.failed + " failed)" : ""}.
            {(result.smsSent > 0 || result.smsFailed > 0) &&
            <span> Texted {result.smsSent}{result.smsFailed > 0 ? " (" + result.smsFailed + " failed)" : ""}.</span>}
            {result.sampleError && <span style={{ display: "block", color: "var(--terracotta)", marginTop: 4 }}>First error: {String(result.sampleError).slice(0, 240)}</span>}
          </div>}
      </div>

      <div style={{ marginTop: "var(--s-7)", padding: "var(--s-5)", background: "var(--bg-alt)", border: "1px solid var(--line-soft)", borderRadius: 8, fontSize: 13, color: "var(--ink-soft)", lineHeight: 1.7, maxWidth: 720 }}>
        <strong style={{ color: "var(--ink)" }}>How sending works</strong><br />
        Emails go through Resend. Each one wraps your message in a Decades on Main template and includes an unsubscribe link at the bottom. Use <em>Send test to me</em> to preview how it looks in your inbox before sending to the whole list. Until a custom domain is verified, Resend only delivers to your own admin email — real subscribers will receive emails once the domain is connected.
      </div>
    </>);

}

const SALES_PAGE_SIZE = 15;

function AdminSales() {
  const [data, setData] = useStateI(null);
  const [loading, setLoading] = useStateI(true);
  const [err, setErr] = useStateI("");
  const [page, setPage] = useStateI(0);

  useEffectI(() => {
    setLoading(true);
    setErr("");
    fetch("/api/sales?days=30", {
      headers: { Authorization: "Bearer " + (sessionStorage.getItem("dom-admin-token") || "") },
    })
      .then((r) => r.json())
      .then((d) => {
        if (d.error) { setErr(d.error); setData(null); }
        else { setData(d); setPage(0); }
      })
      .catch(() => setErr("Could not load sales data."))
      .finally(() => setLoading(false));
  }, []);

  const fmt = (n) => "$" + Number(n || 0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  const avg = data && data.count > 0 ? data.total / data.count : 0;
  const orders = data ? data.orders : [];
  const totalPages = Math.max(1, Math.ceil(orders.length / SALES_PAGE_SIZE));
  const pageOrders = orders.slice(page * SALES_PAGE_SIZE, (page + 1) * SALES_PAGE_SIZE);

  return (
    <>
      <div className="admin-head">
        <div>
          <span className="eyebrow">Reporting</span>
          <h1 className="serif italic">Sales</h1>
        </div>
      </div>

      {loading && (
        <div style={{ padding: "var(--s-7)", color: "var(--ink-muted)", fontSize: 14 }}>Loading…</div>
      )}

      {!loading && err && (
        <div className="admin-table" style={{ padding: "var(--s-7) var(--s-5)", textAlign: "center" }}>
          <p style={{ color: "var(--terracotta)", fontSize: 14, lineHeight: 1.6, maxWidth: 500, margin: "0 auto" }}>{err}</p>
        </div>
      )}

      {!loading && data && (
        <>
          <div className="stat-grid">
            <StatCard label="Gross sales" value={fmt(data.total)} />
            <StatCard label="Orders" value={data.count} />
            <StatCard label="Avg order" value={fmt(avg)} />
          </div>

          <div className="admin-table">
            <div style={{ padding: "var(--s-4) var(--s-5)", borderBottom: "1px solid var(--line-soft)", display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12 }}>
              <h3 className="serif italic" style={{ fontSize: 22, fontWeight: 400, margin: 0 }}>
                Orders — last 30 days
              </h3>
              {totalPages > 1 && (
                <span style={{ fontSize: 13, color: "var(--ink-muted)", whiteSpace: "nowrap" }}>
                  {page + 1} / {totalPages}
                </span>
              )}
            </div>
            {orders.length === 0 ? (
              <div style={{ padding: "var(--s-7) var(--s-5)", textAlign: "center", color: "var(--ink-muted)", fontSize: 14 }}>
                No completed orders in this period.
              </div>
            ) : (
              <>
                <table>
                  <thead>
                    <tr>
                      <th style={{ textAlign: "left" }}>Date</th>
                      <th style={{ textAlign: "left" }}>Source</th>
                      <th style={{ textAlign: "right" }}>Items</th>
                      <th style={{ textAlign: "right" }}>Total</th>
                    </tr>
                  </thead>
                  <tbody>
                    {pageOrders.map((o) => (
                      <tr key={o.id}>
                        <td>
                          <div style={{ fontWeight: 500, color: "var(--ink)" }}>
                            {new Date(o.created_at).toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" })}
                          </div>
                          <div style={{ fontSize: 11, color: "var(--ink-muted)", letterSpacing: "0.04em" }}>
                            {new Date(o.created_at).toLocaleTimeString(undefined, { hour: "numeric", minute: "2-digit" })}
                          </div>
                        </td>
                        <td style={{ color: "var(--ink-soft)", fontSize: 13 }}>{o.source}</td>
                        <td style={{ textAlign: "right", color: "var(--ink-soft)", fontSize: 13 }}>{o.item_count}</td>
                        <td style={{ textAlign: "right", fontWeight: 500, color: "var(--ink)" }}>{fmt(o.total)}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
                {totalPages > 1 && (
                  <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "var(--s-4) var(--s-5)", borderTop: "1px solid var(--line-soft)" }}>
                    <button className="btn btn-ghost btn-sm" disabled={page === 0} onClick={() => setPage((p) => p - 1)}>
                      ← Previous
                    </button>
                    <span style={{ fontSize: 13, color: "var(--ink-muted)" }}>
                      {page * SALES_PAGE_SIZE + 1}–{Math.min((page + 1) * SALES_PAGE_SIZE, orders.length)} of {orders.length}
                    </span>
                    <button className="btn btn-ghost btn-sm" disabled={page >= totalPages - 1} onClick={() => setPage((p) => p + 1)}>
                      Next →
                    </button>
                  </div>
                )}
              </>
            )}
          </div>
        </>
      )}
    </>
  );
}

function AdminSettings() {
  return (
    <>
      <div className="admin-head">
        <div>
          <span className="eyebrow">Configuration</span>
          <h1 className="serif italic">Settings</h1>
        </div>
      </div>
      <div className="admin-settings-grid">
        <div className="stat-card" style={{ padding: "var(--s-6)" }}>
          <h3 className="serif italic" style={{ fontSize: 24, fontWeight: 400, marginBottom: 12 }}>Store information</h3>
          <div className="form-grid">
            <div className="field full"><label>Store name</label><input defaultValue="Decades on Main" /></div>
            <div className="field full"><label>Address</label><input defaultValue="18559 High Springs Main St." /></div>
            <div className="field"><label>City</label><input defaultValue="High Springs" /></div>
            <div className="field"><label>State / Zip</label><input defaultValue="FL 32643" /></div>
            <div className="field full"><label>Phone</label><input defaultValue="(352) 575-3633" /></div>
          </div>
        </div>
        <div className="stat-card" style={{ padding: "var(--s-6)" }}>
          <h3 className="serif italic" style={{ fontSize: 24, fontWeight: 400, marginBottom: 12 }}>Payments & shipping</h3>
          <div className="form-grid">
            <div className="field full"><label>Payment processor</label><input value="Square" readOnly /></div>
            <div className="field full"><label>Default shipping ($)</label><input defaultValue="35" type="number" /></div>
            <div className="field full"><label>Free shipping over ($)</label><input defaultValue="500" type="number" /></div>
            <div className="field full"><label>Tax rate (%)</label><input defaultValue="7" type="number" /></div>
          </div>
        </div>
      </div>
    </>);

}

Object.assign(window, {
  AboutPage, ContactPage, ConsultPage, SellingPage,
  AdminLogin, AdminDashboard
});