// Icons & UI primitives — shared across all sections
const { useState, useEffect, useRef, useCallback } = React;

// ---- Icons (minimal stroke set) ----
const Icon = ({ name, size = 18, className = "", stroke = 1.6 }) => {
  const props = {
    width: size, height: size, viewBox: "0 0 24 24",
    fill: "none", stroke: "currentColor",
    strokeWidth: stroke, strokeLinecap: "round", strokeLinejoin: "round",
    className, "aria-hidden": "true",
  };
  switch (name) {
    case "wave":
      return <svg {...props}><path d="M2 12c2 0 2-2 5-2s3 2 5 2 3-2 5-2 3 2 5 2"/><path d="M2 17c2 0 2-2 5-2s3 2 5 2 3-2 5-2 3 2 5 2"/></svg>;
    case "plane":
      return <svg {...props}><path d="M21 16v-2L13 9V4a1.5 1.5 0 0 0-3 0v5L2 14v2l8-2v5l-2 1.5V22l3-1 3 1v-1.5L12 19v-5l8 2z"/></svg>;
    case "paw":
      return <svg {...props}><circle cx="6" cy="11" r="1.8"/><circle cx="10" cy="7" r="1.8"/><circle cx="14" cy="7" r="1.8"/><circle cx="18" cy="11" r="1.8"/><path d="M8 17.5c0-2.5 1.8-4.5 4-4.5s4 2 4 4.5c0 1.5-1 2.5-2.5 2.5h-3C9 20 8 19 8 17.5z"/></svg>;
    case "fork":
      return <svg {...props}><path d="M7 2v8a3 3 0 0 0 6 0V2"/><path d="M10 14v8"/><path d="M17 2c2 4 2 8 0 10v10"/></svg>;
    case "trend":
      return <svg {...props}><path d="M3 17l6-6 4 4 8-9"/><path d="M14 6h7v7"/></svg>;
    case "key":
      return <svg {...props}><circle cx="8" cy="15" r="4"/><path d="M10.8 13.2L20 4M16 6l3 3M14 8l3 3"/></svg>;
    case "phone":
      return <svg {...props}><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z"/></svg>;
    case "whatsapp":
      return <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" className={className}><path d="M17.5 14.4c-.3-.1-1.7-.8-2-.9-.3-.1-.5-.1-.7.1-.2.3-.7.9-.9 1.1-.2.2-.3.2-.6.1-.3-.1-1.2-.4-2.3-1.4-.9-.8-1.4-1.7-1.6-2-.2-.3 0-.4.1-.6.1-.1.3-.3.4-.5.1-.2.2-.3.3-.5.1-.2 0-.4 0-.5 0-.1-.7-1.6-.9-2.2-.2-.6-.5-.5-.7-.5h-.5c-.2 0-.5.1-.7.3-.3.3-1 1-1 2.4 0 1.4 1 2.8 1.2 3 .1.2 2 3.1 4.8 4.3.7.3 1.2.5 1.6.6.7.2 1.3.2 1.8.1.5-.1 1.7-.7 1.9-1.4.2-.7.2-1.2.2-1.4-.1-.1-.3-.2-.6-.3zM12 2C6.5 2 2 6.5 2 12c0 1.8.5 3.6 1.4 5.1L2 22l4.9-1.3c1.5.8 3.2 1.3 5.1 1.3 5.5 0 10-4.5 10-10S17.5 2 12 2z"/></svg>;
    case "check":
      return <svg {...props}><path d="M5 12l5 5 9-11"/></svg>;
    case "close":
      return <svg {...props}><path d="M6 6l12 12M18 6L6 18"/></svg>;
    case "arrowR":
      return <svg {...props}><path d="M5 12h14M13 5l7 7-7 7"/></svg>;
    case "chevronL":
      return <svg {...props} stroke="currentColor" strokeWidth="2"><path d="M15 18l-6-6 6-6"/></svg>;
    case "chevronR":
      return <svg {...props} stroke="currentColor" strokeWidth="2"><path d="M9 6l6 6-6 6"/></svg>;
    case "alert":
      return <svg {...props}><circle cx="12" cy="12" r="10"/><path d="M12 8v4M12 16h.01"/></svg>;
    case "shield":
      return <svg {...props}><path d="M12 2l9 4v6c0 5-3.5 9-9 10-5.5-1-9-5-9-10V6l9-4z"/></svg>;
    case "spark":
      return <svg {...props}><path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.5 5.5l2 2M16.5 16.5l2 2M5.5 18.5l2-2M16.5 7.5l2-2"/></svg>;
    case "expand":
      return <svg {...props}><path d="M15 3h6v6M21 3l-7 7M9 21H3v-6M3 21l7-7"/></svg>;
    default: return null;
  }
};

// ---- Logo (ROVE wordmark · imagem extraída do book oficial) ----
const Logo = () => (
  <a href="#top" className="logo-rove" aria-label="ROVE Empreendimentos — Campeche Living">
    <img
      className="logo-img"
      src="assets/rove-logo.png"
      alt="ROVE Empreendimentos"
      width="100"
      height="28"
      decoding="async"
    />
    <span className="logo-sub">Campeche Living</span>
  </a>
);

// ---- Placeholder image with editorial style ----
const Placeholder = ({ label, ratio = "4/3", tone = "warm", className = "", style = {} }) => {
  const bg = {
    warm: "var(--sand)",
    cool: "var(--sea-soft)",
    moss: "var(--moss-soft)",
    deep: "oklch(0.30 0.04 240)",
  }[tone] || "var(--sand)";

  const stripe = {
    warm: "oklch(0.90 0.02 75)",
    cool: "oklch(0.85 0.04 220)",
    moss: "oklch(0.85 0.04 145)",
    deep: "oklch(0.35 0.05 240)",
  }[tone];

  return (
    <div
      className={`ph-image ${className}`}
      role="img"
      aria-label={label}
      style={{
        aspectRatio: ratio,
        backgroundColor: bg,
        backgroundImage: `repeating-linear-gradient(135deg, transparent 0, transparent 12px, ${stripe} 12px, ${stripe} 13px)`,
        color: tone === "deep" ? "oklch(0.92 0.01 80)" : "var(--ink-soft)",
        ...style,
      }}
    >
      <span className="ph-image-dim">photo</span>
      <span className="ph-image-label">{label}</span>
    </div>
  );
};

// ---- Reveal-on-scroll wrapper ----
const Reveal = ({ children, delay = 0, as: As = "div", className = "", ...rest }) => {
  const ref = useRef(null);
  const [visible, setVisible] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
      setVisible(true); return;
    }
    // Already-in-viewport elements: reveal immediately with delay
    const rect = ref.current.getBoundingClientRect();
    if (rect.top < window.innerHeight - 40 && rect.bottom > 0) {
      const t = setTimeout(() => setVisible(true), delay + 80);
      return () => clearTimeout(t);
    }
    // Below fold: observe
    const obs = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          setTimeout(() => setVisible(true), delay);
          obs.disconnect();
        }
      });
    }, { threshold: 0.05, rootMargin: "0px 0px -40px 0px" });
    obs.observe(ref.current);
    // Safety fallback: ensure visibility within 2s no matter what
    const fallback = setTimeout(() => setVisible(true), 2000 + delay);
    return () => { obs.disconnect(); clearTimeout(fallback); };
  }, [delay]);
  return (
    <As ref={ref} className={`reveal ${visible ? "is-visible" : ""} ${className}`} {...rest}>
      {children}
    </As>
  );
};

// ---- Tracking helper ----
const track = (eventName, params = {}) => {
  if (typeof window === "undefined") return;
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({ event: eventName, ...params });
  // Mirror to console only in dev — silent in prod
  if (window.__DEV_TRACKING) {
    console.log("[track]", eventName, params);
  }
};

// ---- Scroll to element with offset (sticky header) ----
const scrollToId = (id) => {
  const el = document.getElementById(id);
  if (!el) return;
  const top = el.getBoundingClientRect().top + window.scrollY - 72;
  window.scrollTo({ top, behavior: "smooth" });
};

// Export
Object.assign(window, { Icon, Logo, Placeholder, Reveal, track, scrollToId });
