/* Samantha Seitz Interiors — site sections.
   Depends on core primitives (window globals). Exports sections to window. */

const { Button, LinkButton, Kicker, SecLabel, Tape, Frame, SectionHead } = window;

/* ---------------------------------------------------------------- Header */
const NAV_PAGES = [
  { label: "Home",      href: "./"          },
  { label: "Portfolio", href: "portfolio/"  },
  { label: "Services",  href: "services/"   },
  { label: "Process",   href: "process/"    },
  { label: "About",     href: "about/"      },
  { label: "Journal",   href: "journal/"    },
];

function Header({ activePage = "" }) {
  const [scrolled, setScrolled] = React.useState(false);
  React.useEffect(function () {
    const fn = () => setScrolled(window.scrollY > 24);
    window.addEventListener("scroll", fn, { passive: true });
    return () => window.removeEventListener("scroll", fn);
  }, []);

  const [menuOpen, setMenuOpen] = React.useState(false);
  const toggleMenu = () => setMenuOpen(o => !o);
  const closeMenu = () => setMenuOpen(false);

  return (
    <header className={"site-header" + (scrolled ? " scrolled" : "") + (menuOpen ? " menu-open" : "")}>
      {/* The dynamic <base> makes a bare "#main-content" resolve against the base
          origin, which would navigate off inner pages. Move focus directly instead. */}
      <a className="skip-link" href="#main-content" onClick={(e) => {
        e.preventDefault();
        const m = document.getElementById("main-content");
        if (m) { m.focus(); m.scrollIntoView(); }
      }}>Skip to content</a>
      <div className="header-inner">
        <a className="brandmark" href="./" onClick={closeMenu}>
          <span className="w">Samantha Seitz</span>
          <span className="s">Interiors</span>
        </a>
        <nav className="nav">
          {NAV_PAGES.map((p) => (
            <a key={p.label}
               className={"nav-link" + (activePage === p.label ? " active" : "")}
               href={p.href}>{p.label}</a>
          ))}
          <a className={"nav-link" + (activePage === "Book" ? " active" : "")} href="book/">Book a Consultation</a>
        </nav>
        <button className="hamburger" onClick={toggleMenu} aria-label="Menu">
          <span className={"hb-icon" + (menuOpen ? " open" : "")}>
            <span></span><span></span><span></span>
          </span>
        </button>
      </div>
      {menuOpen && (
        <div className="mobile-nav">
          {NAV_PAGES.map((p) => (
            <a key={p.label} className={"mobile-nav-link" + (activePage === p.label ? " active" : "")}
               href={p.href} onClick={closeMenu}>{p.label}</a>
          ))}
          <a className="mobile-nav-link mobile-nav-cta" href="book/" onClick={closeMenu}>Book a Consultation</a>
        </div>
      )}
    </header>
  );
}

/* ------------------------------------------------------------------ Hero */
function Hero({ onInquire, onServices }) {
  return (
    <section className="hero" id="top">
      <div className="hero-inner wrap">
      <div className="ss-rise">
        <Kicker>Bergen County, New Jersey</Kicker>
      </div>
      <h1 className="ss-rise" style={{ animationDelay: ".08s" }}>
        Home staging,<br /><em>down to the detail.</em>
      </h1>
      <p className="deck ss-rise" style={{ animationDelay: ".2s" }}>
        Every room edited, every detail considered — so your listing photographs like a magazine<br />and sells like one too.
      </p>
      <div className="cta-row ss-rise" style={{ animationDelay: ".32s" }}>
        <Button variant="primary" onClick={onInquire}>Book a Consultation</Button>
        <a className="btn btn-ghost" href="services/">View Services</a>
      </div>
      </div>
    </section>
  );
}

/* ------------------------------------------------------ Consultation block */
function Consultation({ onInquire }) {
  return (
    <section className="feature" id="consultation">
      <div className="feature-inner">
        <div>
          <div className="tag">Where every project begins</div>
          <h2>The Staging Consultation <span className="price">$300</span></h2>
          <p>A 90-minute in-home walk-through with a written, room-by-room action
          plan: what to edit and rearrange, what I'll bring, and any paint or
          quick-repair recommendations that will move the needle before photos and
          showings. You leave with a clear roadmap — whether you stage with me or
          take it from there yourself.</p>
          <p className="credit">Credited in full toward any staging package booked within 30 days.</p>
          <div style={{ marginTop: 28 }}>
            <a className="btn btn-ghost-light" href="services/">View additional services</a>
          </div>
        </div>
        <div className="feature-side">
          <h4>You leave with</h4>
          <ul>
            <li>A room-by-room action plan</li>
            <li>An edit &amp; rearrange list</li>
            <li>Paint &amp; quick-repair notes</li>
            <li>A clear path to photo-ready</li>
          </ul>
        </div>
      </div>
    </section>
  );
}

/* -------------------------------------------------------------- Services */
function Services({ onInquire }) {
  const pkgs = [
    {
      name: "Key Rooms", price: "$750",
      body: "Editing and restyling your existing furniture, layered with curated accessories, art, and textiles from The Collection — focused on the rooms buyers judge first.",
      rooms: "entry · living room · kitchen · dining room · primary bedroom",
    },
    {
      name: "Full Home", price: "$1,500 flat rate",
      body: "A complete styling of the home — every key room plus the secondary spaces that round out a listing. A full styling day, finished photo-ready.",
      rooms: "Key rooms · additional bedrooms · home office · finished secondary spaces",
    },
  ];
  const enh = [
    ["Additional room", "beyond the five key rooms", "$150 each"],
    ["Extended styling period", "past initial listing window", "monthly, quoted"],

  ];
  return (
    <section className="section" id="services">
      <div className="wrap">
        <SectionHead label="Occupied Home Staging" title="Services & Investment"
          sub={<>Two ways to stage — each drawing from The Collection, the curated inventory of textiles, art, and accessories I bring to every home.<br />Included in both staging rates.</>} />
        <div className="svc-list">
          {pkgs.map((p) => (
            <div className="svc" key={p.name}>
              <div className="top">
                <span className="name">{p.name}</span>
                <span className="price">{p.price}</span>
              </div>
              <p className="body">{p.body}</p>
              <p className="rooms">{p.rooms}</p>
              <div className="inq"><LinkButton onClick={() => onInquire(p.name)}>Inquire about {p.name} →</LinkButton></div>
            </div>
          ))}
        </div>
        <div className="enh-wrap">
          <SecLabel>Enhancements</SecLabel>
          <div style={{ marginTop: 14 }}>
            {enh.map((e) => (
              <div className="enh" key={e[0]}>
                <span className="l"><b>{e[0]}</b> — {e[1]}</span>
                <span className="r">{e[2]}</span>
              </div>
            ))}
          </div>
        </div>
        <div className="enh-wrap" style={{ marginTop: 40, borderTop: "1px solid var(--hair)", paddingTop: 34 }}>
          <SecLabel>For Agents</SecLabel>
          <div style={{ maxWidth: "67ch", marginTop: 16 }}>
            <p className="body" style={{ maxWidth: "none" }}>If you're representing a listing that needs more than a consultation and less than a moving truck, that's the work I do. Most occupied staging works only with what's already in the home — which means the listing photos depend on what the seller happens to own. I don't work that way. I bring The Collection to every project, so a home with tired pillows and bare walls photographs like a home with neither.</p>
            <p className="body" style={{ maxWidth: "none", marginTop: "1.1em" }}>I return calls the same day, I work around your photographer's schedule, and I understand that your name is on the sign. Send me the listing before the photos are scheduled, and I'll tell you honestly whether staging will move the number.</p>
            <div className="inq"><LinkButton onClick={() => onInquire("Still Deciding")}>Inquire →</LinkButton></div>
          </div>
        </div>
      </div>
    </section>
  );
}

/* --------------------------------------------------------------- Process */
function Process() {
  const steps = [
    ["Consultation", "A 90-minute walk-through and a written, room-by-room plan."],
    ["What I Bring", "For staged homes, The Collection arrives with me — pillows and throws, art, ceramics, botanicals."],
    ["In-Home Styling", "Edit, rearrange, and layer in pieces from The Collection with yours."],
    ["Photos", "Onsite styling during staging photos."],
    ["Destaging", "Pieces are moved out 7–10 days prior to closing, by appointment."],
  ];
  return (
    <section className="section" id="process" style={{ background: "var(--ivory-deep)" }}>
      <div className="wrap">
        <SectionHead label="How it works" title="Unhurried, hands-on, and finished to the detail." />
        <div className="process">
          {steps.map((s) => (
            <div className="step" key={s[0]}>
              <div className="st">{s[0]}</div>
              <div className="sd">{s[1]}</div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ------------------------------------------------------------- Portfolio */
/* A single project case study — the Oradell Colonial. */
function Portfolio() {
  return (
    <section className="project" id="portfolio">
      <div className="wrap-narrow project-head">
        <div className="kicker">Selected work · Bergen County</div>
        <h1 className="project-title">Oradell Colonial</h1>
      </div>

      <div className="wrap-narrow project-block project-block-first">
        <div className="project-ba">
          <BeforeAfter before="Fireplace_BA_Before.jpg" after="Fireplace_BA_After.jpg" alt="Living room, before and after — Oradell Colonial" />
        </div>
        <div className="fig-label">Living</div>
      </div>

      <div className="project-intro-band">
        <div className="wrap-narrow">
          <p>Freshly listed. I edited each room down, layered in warmth, and staged
          around the home&rsquo;s best feature — the living-room fireplace — so buyers
          could picture the life the house was built for.</p>
        </div>
      </div>

      <figure className="wrap-narrow project-fig">
        <picture>
          <source srcSet="Living_Oradell_Wide.webp" type="image/webp" />
          <img src="Living_Oradell_Wide.jpg" alt="The restyled living room — Oradell Colonial" loading="lazy" />
        </picture>
        <figcaption className="fig-label">Living</figcaption>
      </figure>

      <figure className="wrap-narrow project-fig">
        <picture>
          <source srcSet="Dining_Room_Oradell2.webp" type="image/webp" />
          <img src="Dining_Room_Oradell2.jpeg" alt="The staged dining room — Oradell Colonial" loading="lazy" style={{objectPosition:"50% 30%"}} />
        </picture>
        <figcaption className="fig-label">Dining</figcaption>
      </figure>

      <figure className="wrap-narrow project-fig">
        <picture>
          <source srcSet="Kitchen_Oradell.webp" type="image/webp" />
          <img src="Kitchen_Oradell.jpg" alt="The staged kitchen — Oradell Colonial" loading="lazy" />
        </picture>
        <figcaption className="fig-label">Kitchen</figcaption>
      </figure>

      <div className="wrap-narrow project-details">
        <div className="project-detail-grid">
          <picture>
            <source srcSet="Detail_Stair_Oradell.webp" type="image/webp" />
            <img src="Detail_Stair_Oradell.jpg" alt="Stair hall vignette — Oradell Colonial" loading="lazy" />
          </picture>
          <picture>
            <source srcSet="Detail_Shelf_Oradell.webp" type="image/webp" />
            <img src="Detail_Shelf_Oradell.jpg" alt="Mantel built-in styling — Oradell Colonial" loading="lazy" />
          </picture>
        </div>
        <div className="fig-label">Details</div>
      </div>
    </section>
  );
}

/* --------------------------------------------------------------- Inquiry */
function Inquiry({ preselect, formRef }) {
  const services = ["Staging Consultation", "Key Rooms", "Full Home", "Still Deciding"];
  const [service, setService] = React.useState(preselect || "Staging Consultation");
  const [form, setForm] = React.useState({ name: "", email: "", address: "", message: "" });
  const [sent, setSent] = React.useState(false);
  const [submitting, setSubmitting] = React.useState(false);
  const [error, setError] = React.useState("");
  React.useEffect(() => { if (preselect) setService(preselect); }, [preselect]);
  const set = (k) => (e) => setForm({ ...form, [k]: e.target.value });

  const submit = async (e) => {
    if (e) e.preventDefault();
    setError("");
    if (!form.name || !form.email) {
      setError("Please add your name and email so I can reply.");
      return;
    }
    setSubmitting(true);
    try {
      const res = await fetch("https://formsubmit.co/ajax/inquire@samanthaseitz.com", {
        method: "POST",
        headers: { "Content-Type": "application/json", "Accept": "application/json" },
        body: JSON.stringify({
          _subject: "New inquiry \u2014 " + service,
          Service: service,
          Name: form.name,
          Email: form.email,
          "Property address": form.address,
          "About the home": form.message,
        }),
      });
      if (res.ok) setSent(true);
      else setError("Something went wrong \u2014 email me directly at inquire@samanthaseitz.com.");
    } catch (e) {
      setError("Something went wrong \u2014 email me directly at inquire@samanthaseitz.com.");
    } finally {
      setSubmitting(false);
    }
  };

  if (sent) {
    return (
      <section className="inquire" id="inquire" ref={formRef}>
        <div className="inquire-inner">
          <SectionHead title="Inquire" />
          <div className="thanks" aria-live="polite">
            <div className="mk">Thank you.</div>
            <h3>Your inquiry is in.</h3>
            <p>I'll be in touch within a day or two to find a time for your
            consultation. In the meantime — it's already in the details.</p>
            <div style={{ marginTop: 28 }}>
              <Button variant="ghost" onClick={() => setSent(false)}>Send another</Button>
            </div>
          </div>
        </div>
      </section>
    );
  }
  return (
    <section className="inquire" id="inquire" ref={formRef}>
      <div className="inquire-inner">
        <SectionHead title="Inquire"
          sub="Tell me about your home — every project begins with a conversation." />
        <div className="svc-picker">
          {services.map((s) => (
            <button key={s} type="button" className={"svc-pick" + (service === s ? " active" : "")}
              onClick={() => setService(s)}>{s}</button>
          ))}
        </div>
        <form onSubmit={submit}>
          <div className="form-grid">
            <div className="field"><label htmlFor="inq-name">Name</label>
              <input id="inq-name" name="name" required autoComplete="name"
                value={form.name} onChange={set("name")} placeholder="Your name" /></div>
            <div className="field"><label htmlFor="inq-email">Email</label>
              <input id="inq-email" name="email" type="email" required autoComplete="email"
                value={form.email} onChange={set("email")} placeholder="you@email.com" /></div>
            <div className="field full"><label htmlFor="inq-address">Property address</label>
              <input id="inq-address" name="address" autoComplete="street-address"
                value={form.address} onChange={set("address")} placeholder="Where is the listing?" /></div>
            <div className="field full"><label htmlFor="inq-message">A little about the home</label>
              <textarea id="inq-message" name="message" rows="3" autoComplete="off"
                value={form.message} onChange={set("message")}
                placeholder="Timeline, the rooms you're most concerned about, anything else…" /></div>
          </div>
          <div className="form-foot">
            <Button variant="primary" type="submit" disabled={submitting}>{submitting ? "Sending…" : "Send inquiry"}</Button>
            <div aria-live="polite">
              {error && <p className="form-error" style={{ marginTop: 16, color: "var(--brick, #a8422f)", fontSize: 15 }}>{error}</p>}
            </div>
          </div>
        </form>
      </div>
    </section>
  );
}

/* ---------------------------------------------------------------- Footer */
function Footer() {
  return (
    <footer className="site-footer">
      <div className="footer-inner">
        <div className="fw">Samantha Seitz</div>
        <div className="fs">Interiors</div>
        <div className="tagline">It's in the details.</div>
        <Tape center />
        <div className="contact" style={{ marginTop: 24 }}>
          <a href="mailto:inquire@samanthaseitz.com" className="footer-email">inquire@samanthaseitz.com</a> <span className="dot">|</span> Bergen County, NJ
        </div>
        <div className="footer-social">
          <a className="footer-ig" href="https://www.instagram.com/samanthaseitzinteriors" target="_blank" rel="noopener" aria-label="Instagram">
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
              <rect x="2" y="2" width="20" height="20" rx="5" ry="5"></rect>
              <circle cx="12" cy="12" r="4"></circle>
              <circle cx="17.5" cy="6.5" r="1" fill="currentColor" stroke="none"></circle>
            </svg>
            Instagram
          </a>
        </div>
        <div className="legal">© {new Date().getFullYear()} Samantha Seitz Interiors LLC · Occupied Home Staging</div>
        <div className="legal legal-privacy"><a className="footer-legal-link" href="privacy/">Privacy</a></div>
      </div>
    </footer>
  );
}

/* ---------------------------------------------------- Before / after slider */
/* Swap a .jpg/.jpeg source for its .webp sibling. Every project photo has one;
   the <img> underneath stays the fallback for browsers without WebP. */
const webp = (src) => src.replace(/\.jpe?g$/i, ".webp");

function BeforeAfter({ before, after, alt }) {
  const START = 0;
  const wrapRef = React.useRef(null);
  const clipRef = React.useRef(null);
  const divRef = React.useRef(null);
  const tagLRef = React.useRef(null);
  const tagRRef = React.useRef(null);
  const handleRef = React.useRef(null);
  const posRef = React.useRef(START);
  const rafRef = React.useRef(0);
  const dragging = React.useRef(false);

  // Write DOM directly (no React re-render) — smooth on mobile.
  const paint = () => {
    rafRef.current = 0;
    const p = posRef.current;
    if (clipRef.current) clipRef.current.style.clipPath = `inset(0 ${100 - p}% 0 0)`;
    if (divRef.current) divRef.current.style.left = p + "%";
    if (tagLRef.current) tagLRef.current.style.opacity = p > 88 ? "1" : "0";
    if (tagRRef.current) tagRRef.current.style.opacity = p < 12 ? "1" : "0";
    if (handleRef.current) {
      // Keep the handle inset from the edges so it reads as a control at rest.
      const w = wrapRef.current ? wrapRef.current.getBoundingClientRect().width : 0;
      const px = (p / 100) * w;
      const inset = 26;
      let shift = 0;
      if (px < inset) shift = inset - px;
      else if (px > w - inset) shift = (w - inset) - px;
      handleRef.current.style.transform = `translate(calc(-50% + ${shift}px), -50%)`;
      handleRef.current.setAttribute("aria-valuenow", String(Math.round(p)));
    }
  };
  const schedule = () => { if (!rafRef.current) rafRef.current = requestAnimationFrame(paint); };
  const setPos = (p) => { posRef.current = Math.max(0, Math.min(100, p)); schedule(); };

  React.useEffect(() => {
    paint();
    // One-time draggable hint: nudge to ~12% and back when scrolled into view.
    let obs;
    const reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const el = wrapRef.current;
    if (el && !reduce && "IntersectionObserver" in window) {
      let played = false;
      const nudge = () => {
        const peak = 12, out = 260, back = 260, t0 = performance.now();
        const easeOut = (x) => 1 - Math.pow(1 - x, 3);
        const step = (now) => {
          if (dragging.current) return;
          const el2 = now - t0;
          if (el2 < out) { posRef.current = peak * easeOut(el2 / out); }
          else if (el2 < out + back) { posRef.current = peak * (1 - easeOut((el2 - out) / back)); }
          else { posRef.current = 0; schedule(); return; }
          schedule();
          requestAnimationFrame(step);
        };
        requestAnimationFrame(step);
      };
      obs = new IntersectionObserver((entries) => {
        entries.forEach((en) => {
          if (en.isIntersecting && !played) { played = true; nudge(); obs.disconnect(); }
        });
      }, { threshold: 0.4 });
      obs.observe(el);
    }
    return () => { if (rafRef.current) cancelAnimationFrame(rafRef.current); if (obs) obs.disconnect(); };
  }, []);

  const setFromClientX = (clientX) => {
    const el = wrapRef.current; if (!el) return;
    const r = el.getBoundingClientRect();
    setPos(((clientX - r.left) / r.width) * 100);
  };
  const onDown = (e) => { dragging.current = true; setFromClientX(e.clientX); if (e.currentTarget.setPointerCapture) e.currentTarget.setPointerCapture(e.pointerId); e.stopPropagation(); };
  const onMove = (e) => { if (dragging.current) { setFromClientX(e.clientX); } };
  const onUp = (e) => { dragging.current = false; if (e && e.currentTarget.releasePointerCapture && e.pointerId != null) { try { e.currentTarget.releasePointerCapture(e.pointerId); } catch (_) {} } };
  const onKey = (e) => {
    if (e.key === "ArrowLeft") { setPos(posRef.current - 2); e.preventDefault(); }
    if (e.key === "ArrowRight") { setPos(posRef.current + 2); e.preventDefault(); }
  };

  return (
    <div className="ba" ref={wrapRef} style={{ touchAction: "none", cursor: "col-resize" }} onPointerDown={onDown} onPointerMove={onMove} onPointerUp={onUp} onPointerCancel={onUp}>
      <picture>
        <source srcSet={webp(after)} type="image/webp" />
        <img className="ba-img" src={after} alt={alt} draggable="false" />
      </picture>
      <div className="ba-clip" ref={clipRef} style={{ clipPath: `inset(0 ${100 - START}% 0 0)` }}>
        <picture>
          <source srcSet={webp(before)} type="image/webp" />
          <img className="ba-img" src={before} alt="" draggable="false" />
        </picture>
        <span className="ba-tag ba-tag-l" ref={tagLRef}>Before</span>
      </div>
      <span className="ba-tag ba-tag-r" ref={tagRRef}>After</span>
      <div className="ba-divider" ref={divRef} style={{ left: `${START}%` }}>
        <div className="ba-handle" ref={handleRef} role="slider" tabIndex="0" aria-label="Slide to reveal before and after" aria-valuenow={START} aria-valuemin="0" aria-valuemax="100" onKeyDown={onKey} onPointerDown={onDown} onPointerMove={onMove} onPointerUp={onUp} onPointerCancel={onUp}>
          <svg width="20" height="12" viewBox="0 0 20 12" aria-hidden="true"><path d="M6 1 1 6l5 5M14 1l5 5-5 5" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>
        </div>
      </div>
    </div>
  );
}

/* --------------------------------------------------------- Case study teaser */
function CaseTease() {
  return (
    <React.Fragment>
      <section className="ct-pair-sec">
        <div className="wrap">
          <div className="ct-pair">
            <figure className="ct-pair-item">
              <picture>
                <source srcSet="Fireplace_BA_Before.webp" type="image/webp" />
                <img src="Fireplace_BA_Before.jpg" alt="Living room before staging — Oradell Colonial"
                     width="1466" height="1600" loading="lazy" />
              </picture>
              <figcaption className="fig-label">Before</figcaption>
            </figure>
            <figure className="ct-pair-item">
              <picture>
                <source srcSet="Fireplace_BA_After.webp" type="image/webp" />
                <img src="Fireplace_BA_After.jpg" alt="Living room after staging — Oradell Colonial"
                     width="1466" height="1600" loading="lazy" />
              </picture>
              <figcaption className="fig-label">After</figcaption>
            </figure>
          </div>
        </div>
      </section>
      <section className="case-tease">
        <div className="wrap">
          <div className="ct-body">
            <Kicker>An Oradell Colonial</Kicker>
            <p className="ct-line">&ldquo;Selling the house we&rsquo;d raised our kids in was harder than I expected, and I braced myself for someone coming in to strip all the personality out. Sam did the opposite &mdash; she made it feel like our home on its best day. When I saw the photos I actually got emotional. And it worked: we had a full-priced offer within 48 hours.&rdquo;</p>
            <p className="ct-attr">Oradell Colonial Homeowner</p>
            <a className="ct-link" href="portfolio/">View the Portfolio →</a>
          </div>
        </div>
      </section>
    </React.Fragment>
  );
}

Object.assign(window, { Header, Hero, BeforeAfter, CaseTease, Consultation, Services, Process, Portfolio, Inquiry, Footer });
