function BuyButton({ painting }) {
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState("");
  const disabled = !painting.available || !Number(painting.price);

  const go = async () => {
    if (disabled || busy) return;
    setBusy(true);
    setErr("");
    try {
      await window.lf.startCheckout(painting.id);
      // browser is now redirecting to Stripe
    } catch (e) {
      console.error(e);
      setBusy(false);
      setErr((e && e.message) || "Could not start checkout. Please try again.");
    }
  };

  return (
    <div>
      <button
        className="btn btn-primary"
        style={{ width: "100%", justifyContent: "center", opacity: busy ? 0.7 : 1 }}
        onClick={go}
        disabled={disabled || busy}
      >
        {!painting.available
          ? "SOLD"
          : busy
          ? "Opening Stripe…"
          : <>Acquire This Painting <Icon.ArrowR /></>}
      </button>
      {err && (
        <div style={{ marginTop: 10, fontSize: 12, color: "#8C4034" }}>{err}</div>
      )}
      {painting.available && (() => {
        const ship = (painting.shipping === undefined || painting.shipping === null || painting.shipping === "")
          ? 160
          : Math.max(0, Number(painting.shipping) || 0);
        const shipLabel = ship === 0 ? "complimentary shipping" : `$${ship.toLocaleString()} insured shipping`;
        return (
          <div style={{ marginTop: 8, fontSize: 11.5, color: "var(--ink-mute)", letterSpacing: "0.04em" }}>
            Secure checkout via Stripe · ${(painting.price || 0).toLocaleString()} CAD + {shipLabel}
          </div>
        );
      })()}
    </div>
  );
}

function ArtworkPage({ id, navigate, addToCart, openArtwork }) {
  const p = window.PAINTINGS.find((x) => x.id === id);
  const [view, setView] = useState(0); // 0=detail painting, 1=framed, 2=close-up, 3=room, 4=corner
  const [qty] = useState(1);
  const [zoomed, setZoomed] = useState(false);

  // Per-artwork SEO + Schema.org VisualArtwork structured data so this page
  // ranks for the painting's title and surfaces a rich product card.
  if (p) {
    const heroImage = (p.images && p.images[0]) || "https://larissaart.com/assets/about/04.jpg";
    const canonical = `https://larissaart.com/artwork?id=${encodeURIComponent(p.id)}`;
    const ttl = `${p.title} — Original Oil Painting by Larissa`;
    const desc = `${p.short || p.story || `Original oil painting "${p.title}" — ${p.dims}, ${p.medium}.`} Hand-signed, one of one, shipped worldwide.`;
    window.useSeo({
      title: ttl,
      description: desc,
      canonical,
      image: heroImage,
      jsonLd: {
        "@context": "https://schema.org",
        "@type": "VisualArtwork",
        "name": p.title,
        "image": heroImage,
        "description": p.story || p.short || "",
        "artMedium": p.medium,
        "artworkSurface": "Canvas",
        "artform": "Painting",
        "width": p.dims,
        "dateCreated": String(p.year || ""),
        "creator": {
          "@type": "Person",
          "name": "Larissa Svinoukhova",
          "url": "https://larissaart.com/about",
        },
        "offers": {
          "@type": "Offer",
          "url": canonical,
          "priceCurrency": "CAD",
          "price": String(p.price || 0),
          "availability": p.available === false
            ? "https://schema.org/SoldOut"
            : "https://schema.org/InStock",
          "itemCondition": "https://schema.org/NewCondition",
        },
      },
    });
  }

  if (!p) return null;

  // 3 'shots': detail, framed, closeup
  const shots = [
    { type: "main", label: "The Painting" },
    { type: "framed", label: "Studio Frame" },
    { type: "closeup", label: "Brushwork" },
  ];

  const others = window.PAINTINGS.filter((x) => x.id !== p.id).slice(0, 4);

  return (
    <div className="page-enter" style={{ paddingTop: 110 }}>
      {/* Breadcrumb */}
      <div style={{ maxWidth: 1440, margin: "0 auto", padding: "20px 40px", fontSize: 11.5, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--ink-mute)" }}>
        <a onClick={() => navigate("home")} style={{ cursor: "pointer" }}>Studio</a>
        <span style={{ margin: "0 10px" }}>·</span>
        <a onClick={() => navigate("gallery")} style={{ cursor: "pointer" }}>Gallery</a>
        <span style={{ margin: "0 10px" }}>·</span>
        <span style={{ color: "var(--ink)" }}>{p.title}</span>
      </div>

      {/* MAIN */}
      <section style={{ maxWidth: 1440, margin: "0 auto", padding: "20px 40px 80px",
                        display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 80, alignItems: "start" }}>
        {/* LEFT: Gallery viewer */}
        <div>
          <ShotViewer p={p} view={view} setView={setView} onZoom={() => setZoomed(true)} />
          <div className="lf-keep-grid" style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 16, marginTop: 16 }}>
            {shots.map((s, i) => (
              <button key={i} onClick={() => setView(i)} style={{
                background: "transparent", border: "1px solid " + (view === i ? "var(--gold)" : "var(--line-soft)"),
                padding: 0, cursor: "pointer", aspectRatio: "4/5", position: "relative", overflow: "hidden",
              }}>
                <ShotThumb p={p} type={s.type} />
                <div style={{
                  position: "absolute", left: 0, right: 0, bottom: 0,
                  background: "rgba(46,42,36,0.65)", color: "var(--warm-white)",
                  padding: "5px 8px", fontSize: 9.5, letterSpacing: "0.18em", textTransform: "uppercase",
                }}>{s.label}</div>
              </button>
            ))}
          </div>
        </div>

        {/* RIGHT: Sticky details */}
        <div style={{ position: "sticky", top: 110 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12, color: "var(--gold-deep)" }}>
            <span className="gold-rule" />
            <span style={{ fontSize: 11, letterSpacing: "0.32em", textTransform: "uppercase" }}>{p.category} · {p.year}</span>
          </div>
          <h1 className="h-display" style={{ fontSize: "clamp(40px, 4.6vw, 64px)", marginTop: 16, marginBottom: 0 }}>
            <em style={{ fontStyle: "italic" }}>{p.title}</em>
          </h1>
          <div className="h-script" style={{ fontSize: 26, color: "var(--gold-deep)", marginTop: 12 }}>
            painted in the spring studio.
          </div>

          <div style={{ marginTop: 32, padding: "24px 0", borderTop: "1px solid var(--line)", borderBottom: "1px solid var(--line)" }}>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", rowGap: 18, columnGap: 24 }}>
              {[
                ["Medium", p.medium],
                ["Dimensions", p.dims],
                ["Year", String(p.year)],
                ["Edition", "Original · 1 of 1"],
                ["Signed", "Front, lower right"],
              ].map(([k, v]) => (
                <div key={k}>
                  <div style={{ fontSize: 10, letterSpacing: "0.24em", textTransform: "uppercase", color: "var(--ink-mute)" }}>{k}</div>
                  <div style={{ fontFamily: "var(--serif)", fontSize: 18, marginTop: 4 }}>{v}</div>
                </div>
              ))}
            </div>
          </div>

          {p.available ? (
            <div style={{ marginTop: 24, display: "flex", alignItems: "baseline", justifyContent: "space-between", gap: 16 }}>
              <div>
                <div style={{ fontSize: 11, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--ink-mute)" }}>Price</div>
                <div style={{ fontFamily: "var(--serif)", fontSize: 40, marginTop: 2 }}>${p.price.toLocaleString()}<span style={{ fontSize: 14, color: "var(--ink-mute)", marginLeft: 8 }}>CAD</span></div>
                <div style={{ fontSize: 12, color: "var(--ink-soft)", marginTop: 4 }}>
                  Insured shipping included worldwide
                </div>
              </div>
            </div>
          ) : (
            <div style={{ marginTop: 24 }}>
              <div style={{ fontSize: 11, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--ink-mute)" }}>Status</div>
              <div style={{ fontFamily: "var(--serif)", fontSize: 32, marginTop: 6, color: "var(--gold-deep)", letterSpacing: "0.06em" }}>Sold</div>
              <div style={{ fontSize: 12, color: "var(--ink-soft)", marginTop: 8, fontStyle: "italic" }}>
                This painting has found its home. Write to the studio if you'd like to commission something similar.
              </div>
            </div>
          )}

          <div className="lf-buy-row" style={{ marginTop: 28, display: "flex", gap: 12, alignItems: "stretch" }}>
            <div style={{ flex: "1 1 auto", minWidth: 0 }}>
              <BuyButton painting={p} />
            </div>
            <button className="btn btn-ghost lf-fav-btn" aria-label="Save">
              <Icon.Heart />
            </button>
          </div>

          {/* Story */}
          {(p.story || p.short) && (
            <div style={{ marginTop: 44 }}>
              <div className="eyebrow">The Story</div>
              {p.story && (
                <p style={{ marginTop: 14, fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 19, lineHeight: 1.55, color: "var(--ink)" }}>
                  "{p.story}"
                </p>
              )}
              {p.short && p.short.trim() !== (p.story || "").trim() && (
                <p style={{ marginTop: 14, fontSize: 14.5, lineHeight: 1.7, color: "var(--ink-soft)" }}>
                  {p.short}
                </p>
              )}
            </div>
          )}

          {/* Trust strip */}
          <div style={{ marginTop: 36, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
            {[
              ["✓", "Signed Original — Not a Print"],
              ["✓", "Museum-Quality Packaging"],
              ["✓", "Hand-Crated in the Studio"],
              ["✓", "Painted in Highlands, Ontario"],
            ].map(([m, t]) => (
              <div key={t} style={{ display: "flex", gap: 10, alignItems: "flex-start", fontSize: 12.5, color: "var(--ink-soft)" }}>
                <span style={{ color: "var(--gold-deep)", fontWeight: 600, marginTop: 1 }}><Icon.Check /></span>
                {t}
              </div>
            ))}
          </div>

          {/* Shipping accordions */}
          <div style={{ marginTop: 36 }}>
            <Accordion title="Shipping & Arrival">
              <p>Ships from Highlands, Ontario within 5 business days. Crated by hand in archival materials.
                 Canada: 5–10 business days. United States: 7–12 days. International: 10–18 days.
                 We unframe for safer travel; framers in your city can be recommended on request.</p>
            </Accordion>
            <Accordion title="Care">
              <p>Each painting is hand-signed on the front in oil. Hang away from direct sunlight and heat
                 sources. Dust gently with a clean dry sable brush — never water or solvent.</p>
            </Accordion>
            <Accordion title="Studio Visit & Commissions">
              <p>You are warmly invited to visit the studio by appointment, May through October.
                 Larissa also takes a small number of private commissions each year. Please write
                 to <em>hello@larissaart.com</em>.</p>
            </Accordion>
          </div>
        </div>
      </section>

      {/* SIGNATURE STRIP */}
      <section style={{ padding: "100px 40px", maxWidth: 1100, margin: "0 auto", textAlign: "center" }}>
        <div className="h-script" style={{ fontSize: 56, color: "var(--gold-deep)", lineHeight: 0.9 }}>
          Larissa
        </div>
        <p style={{ marginTop: 24, fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 22, color: "var(--ink)", maxWidth: 720, margin: "24px auto 0", lineHeight: 1.5 }}>
          "This painting was made over four mornings in May, with the windows open. I hope it brings the smell of the lake into your home."
        </p>
        <div style={{ marginTop: 18, fontSize: 12, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--ink-mute)" }}>
          A note from the artist
        </div>
      </section>

      {/* RELATED */}
      <section style={{ maxWidth: 1440, margin: "0 auto", padding: "60px 40px 80px" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "end", marginBottom: 32 }}>
          <div>
            <div className="eyebrow">More from the studio</div>
            <h2 className="h-display" style={{ fontSize: "clamp(28px, 3.2vw, 44px)", marginTop: 12, fontStyle: "italic" }}>
              You might also love.
            </h2>
          </div>
          <a className="btn-link" onClick={() => navigate("gallery")}>View All <Icon.ArrowR /></a>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 22 }}>
          {others.map((o) => (
            <div key={o.id} style={{ cursor: "pointer" }} onClick={() => openArtwork(o.id)}>
              <Painting p={o} aspect="4/5" tag={false} />
              <div style={{ marginTop: 12, fontFamily: "var(--serif)", fontSize: 17 }}>{o.title}</div>
              <div style={{ fontSize: 12, color: "var(--ink-mute)" }}>${o.price.toLocaleString()} CAD</div>
            </div>
          ))}
        </div>
      </section>

      {zoomed && <ZoomOverlay p={p} onClose={() => setZoomed(false)} />}
    </div>
  );
}

function ShotViewer({ p, view, setView, onZoom }) {
  const hasImg = (i) => p.images && p.images[i];

  if (view === 0) {
    return (
      <div style={{ position: "relative", background: "var(--paper)", padding: 40, cursor: "zoom-in" }} onClick={onZoom}>
        <Painting p={p} fit="natural" tag={false} className="lift-shadow" />
        <button style={{
          position: "absolute", top: 18, right: 18,
          background: "rgba(251,245,236,0.92)", border: "none",
          width: 38, height: 38, borderRadius: 999, cursor: "pointer",
          display: "inline-flex", alignItems: "center", justifyContent: "center",
        }} aria-label="Zoom"><Icon.Zoom /></button>
      </div>
    );
  }
  if (view === 1) {
    return (
      <div style={{ position: "relative", background: "linear-gradient(180deg, #F4EDE2 0%, #DCCDB3 100%)", padding: 80 }}>
        <Painting p={p} fit="natural" framed tag={false} className="lift-shadow" />
        <div style={{ position: "absolute", left: 28, bottom: 22, fontSize: 11, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--ink-soft)" }}>
          Optional · Hand-finished gold leaf frame (sold separately)
        </div>
      </div>
    );
  }
  if (view === 2) {
    // Brushwork — prefer a dedicated brushwork or close-up slot uploaded by
    // the admin; that image shows at its natural aspect. Otherwise zoom
    // into the main painting (~2.2×) so it reads as a real close-up of the
    // texture, not just a duplicate of "The Painting".
    const hasDistinct = hasImg(2) || hasImg(1);
    const idx = hasImg(2) ? 2 : hasImg(1) ? 1 : 0;
    const src = p.images && p.images[idx];
    return (
      <div style={{ position: "relative", overflow: "hidden", background: "var(--paper)", padding: 40 }}>
        {src ? (
          hasDistinct ? (
            <Painting p={p} fit="natural" tag={false} imageIndex={idx} className="lift-shadow" />
          ) : (
            <div style={{
              aspectRatio: "4/5",
              backgroundImage: `url("${src}")`,
              backgroundSize: "220%",
              backgroundPosition: "center",
              boxShadow: "0 30px 60px -30px rgba(46,42,36,0.22), 0 8px 20px -10px rgba(46,42,36,0.08)",
            }} />
          )
        ) : (
          <>
            <div style={{ aspectRatio: "4/5", background: p.grad, transform: "scale(2.2) translate(-12%, -8%)", transformOrigin: "center" }} />
            <div style={{
              position: "absolute", inset: 0,
              backgroundImage: "repeating-linear-gradient(115deg, rgba(46,42,36,0.06) 0 2px, transparent 2px 8px), repeating-linear-gradient(25deg, rgba(255,255,255,0.10) 0 2px, transparent 2px 6px)",
              mixBlendMode: "soft-light",
            }} />
          </>
        )}
        <div style={{ position: "absolute", left: 28, bottom: 22, fontSize: 11, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--ink)", background: "rgba(251,245,236,0.85)", padding: "6px 12px" }}>
          Brushwork — visible texture and palette
        </div>
      </div>
    );
  }
}

function ShotThumb({ p, type }) {
  // Thumbnails share a fixed 4/5 box so the grid stays uniform. The main
  // and framed thumbs letterbox (no crop). The brushwork thumb zooms into
  // the painting so it reads as a close-up of the texture.
  const img = (i) => p.images && p.images[i];
  if (type === "framed") {
    return <Painting p={p} aspect="4/5" framed fit="contain" tag={false} />;
  }
  if (type === "closeup") {
    const hasDistinct = img(2) || img(1);
    const idx = img(2) ? 2 : img(1) ? 1 : 0;
    const src = img(idx);
    if (!src) return <Painting p={p} aspect="4/5" fit="contain" tag={false} />;
    if (hasDistinct) {
      return <Painting p={p} aspect="4/5" fit="contain" tag={false} imageIndex={idx} />;
    }
    return (
      <div className="painting" style={{
        aspectRatio: "4/5",
        backgroundImage: `url("${src}")`,
        backgroundSize: "220%",
        backgroundPosition: "center",
      }} />
    );
  }
  return <Painting p={p} aspect="4/5" fit="contain" tag={false} imageIndex={0} />;
}

function Accordion({ title, children }) {
  const [open, setOpen] = useState(false);
  return (
    <div style={{ borderTop: "1px solid var(--line)" }}>
      <button onClick={() => setOpen(!open)} style={{
        width: "100%", padding: "18px 0", background: "transparent", border: "none", textAlign: "left",
        display: "flex", justifyContent: "space-between", alignItems: "center", cursor: "pointer",
        fontFamily: "var(--serif)", fontSize: 18, color: "var(--ink)",
      }}>
        {title}
        <span style={{ transform: open ? "rotate(45deg)" : "rotate(0)", transition: "transform 240ms ease" }}>
          <Icon.Plus />
        </span>
      </button>
      <div style={{
        maxHeight: open ? 240 : 0, overflow: "hidden",
        transition: "max-height 320ms ease",
        fontSize: 14, color: "var(--ink-soft)", lineHeight: 1.7,
      }}>
        <div style={{ paddingBottom: 18 }}>{children}</div>
      </div>
    </div>
  );
}

function ZoomOverlay({ p, onClose }) {
  return (
    <div onClick={onClose} style={{
      position: "fixed", inset: 0, zIndex: 400,
      background: "rgba(46,42,36,0.92)",
      display: "flex", alignItems: "center", justifyContent: "center",
      cursor: "zoom-out", animation: "pageFade 240ms ease both",
    }}>
      <div style={{ display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", padding: "5vh 5vw" }}>
        {p.images && p.images[0] ? (
          <img src={p.images[0]} alt={p.title} style={{
            display: "block", maxWidth: "90vw", maxHeight: "82vh",
            width: "auto", height: "auto", objectFit: "contain",
            boxShadow: "0 30px 80px -30px rgba(0,0,0,0.6)",
          }} />
        ) : (
          <div style={{ width: "min(80vw, 720px)" }}>
            <Painting p={p} aspect="4/5" tag={false} />
          </div>
        )}
        <div style={{ textAlign: "center", marginTop: 18, color: "rgba(255,255,255,0.7)", fontSize: 11, letterSpacing: "0.22em", textTransform: "uppercase" }}>
          Click anywhere to close
        </div>
      </div>
    </div>
  );
}

window.ArtworkPage = ArtworkPage;
