// v2-ui.jsx — shared primitives for the luxury redesign

const { useState: useUiState, useEffect: useUiEffect, useRef: useUiRef } = React;

// ── Reveal — JS-driven entrance, settles to plain final styles ──
// (capture/print-safe: after the animation window, transition is
//  removed entirely so static renderers always see the final state)
function Reveal({ children, delay = 0, as = "div", style, className, auto = false }) {
  const ref = useUiRef(null);
  const [state, setState] = useUiState("hidden"); // hidden → shown → settled
  useUiEffect(() => {
    if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
      setState("settled");
      return;
    }
    let revealed = false;
    let iv = null;
    const timers = [];
    const cleanup = () => {
      window.removeEventListener("scroll", check);
      window.removeEventListener("resize", check);
      if (iv) clearInterval(iv);
    };
    const show = () => {
      if (revealed) return;
      revealed = true;
      cleanup();
      setState("shown");
      timers.push(setTimeout(() => setState("settled"), delay + 1400));
    };
    const check = () => {
      const el = ref.current;
      if (!el) return;
      const r = el.getBoundingClientRect();
      if (r.top < window.innerHeight * 0.92 && r.bottom > 0) show();
    };
    if (auto) {
      timers.push(setTimeout(show, 30));
    } else {
      check();
      window.addEventListener("scroll", check, { passive: true });
      window.addEventListener("resize", check);
      iv = setInterval(check, 700);
    }
    return () => {cleanup();timers.forEach(clearTimeout);};
  }, []);
  const Tag = as;
  const hidden = state === "hidden";
  const settled = state === "settled";
  return (
    <Tag ref={ref} className={className} style={{
      ...style,
      opacity: hidden ? 0 : 1,
      transform: hidden ? "translateY(28px)" : "none",
      transition: settled ? "none" : `opacity 1100ms var(--ease) ${delay}ms, transform 1100ms var(--ease) ${delay}ms`
    }}>
      {children}
    </Tag>);

}

// ── Small-caps label ───────────────────────────────────────────
function Tag2({ children, tone = "dark", style }) {
  return (
    <span className="label" style={{
      color: tone === "dark" ? "var(--w-3)" : "var(--b-3)",
      ...style
    }}>{children}</span>);

}

// ── Quiet text CTA — small caps + long arrow, underline grows ──
function LineLink({ children, tone = "dark", onClick, style }) {
  return (
    <button type="button" className={`line-link ${tone}`} onClick={onClick} style={style}>
      <span className="label" style={{ letterSpacing: ".22em" }}>{children}</span>
      <svg width="34" height="10" viewBox="0 0 34 10" fill="none" aria-hidden="true">
        <path d="M0 5h32M28 1l4 4-4 4" stroke="currentColor" strokeWidth="1" />
      </svg>
    </button>);

}

// ── Gold CTA — the loud, magnetic one ───────────────────────
function GoldLink({ children, onClick, small = false, onLight = false, disabled = false, type = "button", style }) {
  return (
    <button
      type={type}
      className={`cta-gold ${small ? "sm" : ""} ${onLight ? "on-light" : ""} ${disabled ? "disabled" : ""}`}
      onClick={onClick}
      disabled={disabled}
      style={style}>

      <span className="label">{children}</span>
      <svg width="30" height="10" viewBox="0 0 34 10" fill="none" aria-hidden="true">
        <path d="M0 5h32M28 1l4 4-4 4" stroke="currentColor" strokeWidth="1.2" />
      </svg>
    </button>);

}

// ── Boxed CTA — 1px hairline, slow ink fill ────────────────────
function BoxLink({ children, tone = "dark", onClick, style }) {
  return (
    <button type="button" className={`box-link ${tone}`} onClick={onClick} style={style}>
      <span className="label" style={{ letterSpacing: ".24em" }}>{children}</span>
    </button>);

}

// ── Architectural image placeholder ────────────────────────────
// Neutral, photographic gradients — awaiting the studio's real renders.
const PLATE_VARIANTS = {
  dusk: `radial-gradient(ellipse 90% 70% at 75% 12%, rgba(214,178,140,.30) 0%, rgba(214,178,140,0) 55%),
         linear-gradient(178deg, rgba(255,255,255,.05) 0%, rgba(8,8,9,.6) 60%, rgba(5,5,6,.92) 100%),
         linear-gradient(180deg, #232126 0%, #0c0b0d 100%)`,
  noon: `radial-gradient(ellipse 80% 60% at 30% 18%, rgba(245,238,225,.5) 0%, rgba(245,238,225,0) 60%),
         linear-gradient(180deg, #b8b2a6 0%, #6f6a60 70%, #4a463f 100%)`,
  fog: `radial-gradient(ellipse 80% 55% at 60% 25%, rgba(225,228,232,.55) 0%, rgba(225,228,232,0) 60%),
         linear-gradient(180deg, #9aa0a8 0%, #5c6168 75%, #3c4046 100%)`,
  ember: `radial-gradient(ellipse 75% 60% at 22% 80%, rgba(196,120,66,.34) 0%, rgba(196,120,66,0) 60%),
         radial-gradient(ellipse 60% 45% at 80% 15%, rgba(255,214,170,.22) 0%, rgba(255,214,170,0) 55%),
         linear-gradient(180deg, #2a211c 0%, #100c0a 100%)`,
  night: `radial-gradient(ellipse 70% 55% at 70% 20%, rgba(170,190,215,.2) 0%, rgba(170,190,215,0) 55%),
         linear-gradient(180deg, #14171d 0%, #08090c 100%)`
};

function Plate({ variant = "dusk", ratio = "4/5", tag, style, children }) {
  return (
    <div className="plate" style={{ aspectRatio: ratio, ...style }}>
      <div className="plate-img" style={{ background: PLATE_VARIANTS[variant] || PLATE_VARIANTS.dusk }} />
      <div className="plate-grain" aria-hidden="true"></div>
      {tag && <span className="plate-tag">{tag}</span>}
      {children}
    </div>);

}

// ── Underline form field ───────────────────────────────────────
function Field2({ label, value, onChange, type = "text", multiline = false, tone = "light" }) {
  const [focus, setFocus] = useUiState(false);
  const up = focus || value && value.length > 0;
  return (
    <label className={`field2 ${tone}`} data-up={up ? "true" : "false"}>
      <span className="field2-label">{label}</span>
      {multiline ?
      <textarea
        className="field2-input" rows={4} value={value}
        onChange={(e) => onChange(e.target.value)}
        onFocus={() => setFocus(true)} onBlur={() => setFocus(false)}>
      </textarea> :

      <input
        className="field2-input" type={type} value={value}
        onChange={(e) => onChange(e.target.value)}
        onFocus={() => setFocus(true)} onBlur={() => setFocus(false)} />

      }
    </label>);

}

// ── Checkbox — square hairline ─────────────────────────────────
function Check2({ checked, onChange, children, tone = "light" }) {
  return (
    <button type="button" className={`check2 ${tone}`} data-on={checked ? "true" : "false"} onClick={() => onChange(!checked)}>
      <span className="check2-box">
        <svg viewBox="0 0 12 12" fill="none" aria-hidden="true"><path d="M2 6.2 5 9l5-6" stroke="currentColor" strokeWidth="1.4" /></svg>
      </span>
      <span className="check2-text">{children}</span>
    </button>);

}

// ── Section index line:  ( 01 )  STUDIO ───────────────────────
function IndexLine({ n, children, tone = "dark", style }) {
  return (
    <div className="index-line" style={{ ...style, fontSize: "64px", fontFamily: "\"Cormorant Garamond\"" }}>
      <span className="label" style={{ color: "var(--accent)" }}>{n}</span>
      <span className="index-rule" style={{ background: tone === "dark" ? "var(--line-d)" : "var(--line-l)" }}></span>
      <span className="label" style={{ color: tone === "dark" ? "var(--w-3)" : "var(--b-3)" }}>{children}</span>
    </div>);

}

// ── Lightbox ───────────────────────────────────────────────────
// Listens for window 'obx:open' CustomEvent { detail: { images:[id], index } }
function Lightbox() {
  const [state, setState] = useUiState(null); // { images, index } | null
  useUiEffect(() => {
    const open = (e) => setState({ images: e.detail.images, index: e.detail.index || 0 });
    window.addEventListener("obx:open", open);
    return () => window.removeEventListener("obx:open", open);
  }, []);
  useUiEffect(() => {
    if (!state) return;
    const onKey = (e) => {
      if (e.key === "Escape") setState(null);else
      if (e.key === "ArrowRight") setState((s) => ({ ...s, index: (s.index + 1) % s.images.length }));else
      if (e.key === "ArrowLeft") setState((s) => ({ ...s, index: (s.index - 1 + s.images.length) % s.images.length }));
    };
    window.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => {window.removeEventListener("keydown", onKey);document.body.style.overflow = "";};
  }, [state]);
  if (!state) return null;
  const { images, index } = state;
  const go = (d) => setState((s) => ({ ...s, index: (s.index + d + images.length) % images.length }));
  return (
    <div className="obx" onClick={() => setState(null)} role="dialog" aria-modal="true" aria-label="Image viewer">
      <button type="button" className="obx-close" onClick={() => setState(null)} aria-label="Close">
        <svg width="22" height="22" viewBox="0 0 20 20" fill="none"><path d="M3 3l14 14M17 3L3 17" stroke="currentColor" strokeWidth="1.2" /></svg>
      </button>
      {images.length > 1 &&
      <>
          <button type="button" className="obx-nav prev" onClick={(e) => {e.stopPropagation();go(-1);}} aria-label="Previous">
            <svg width="22" height="12" viewBox="0 0 34 10" fill="none" style={{ transform: "scaleX(-1)" }}><path d="M0 5h32M28 1l4 4-4 4" stroke="currentColor" strokeWidth="1" /></svg>
          </button>
          <button type="button" className="obx-nav next" onClick={(e) => {e.stopPropagation();go(1);}} aria-label="Next">
            <svg width="22" height="12" viewBox="0 0 34 10" fill="none"><path d="M0 5h32M28 1l4 4-4 4" stroke="currentColor" strokeWidth="1" /></svg>
          </button>
        </>
      }
      <img className="obx-img" src={DRIVE_IMG(images[index], 2400)} alt="" onClick={(e) => e.stopPropagation()} />
      {images.length > 1 &&
      <span className="obx-count">{String(index + 1).padStart(2, "0")} / {String(images.length).padStart(2, "0")}</span>
      }
    </div>);

}
const openLightbox = (images, index = 0) =>
window.dispatchEvent(new CustomEvent("obx:open", { detail: { images, index } }));

Object.assign(window, { Reveal, Tag2, LineLink, BoxLink, GoldLink, Plate, Field2, Check2, IndexLine, Lightbox, openLightbox, PLATE_VARIANTS });