// Jai Mahal Audio Tour — shared utility components
// Brand mark (logo), Ornamental rule, Chapter chip, ImageCard

const { useEffect, useRef, useState } = React;

// ─── Brand mark (logo SVG wrapper) ──────────────────────────────────
function BrandMark({ size = 22, mono = false, color }) {
  // We use the user-supplied PNG logo. mono=true shows just the lockup wordmark glyph.
  return (
    <img
      src="assets/logo.png"
      alt="Jai Mahal Palace, Jaipur"
      style={{
        height: size,
        width: "auto",
        opacity: mono ? 0.85 : 1,
        filter: color ? `brightness(0) saturate(100%) ${color}` : "none",
        display: "block",
      }}
    />
  );
}

// Compact logo for header use — shows the full mark (crest + wordmark or crest-only).
// We use object-fit:contain to ensure both the elephants AND the arches are visible
// without cropping.
function BrandCrest({ size = 28, opacity = 1, crestOnly = true }) {
  // The source PNG is 1149 × 639. The crest occupies roughly the top 57% (380px wide).
  // For "crestOnly" we crop the bottom wordmark away with a clip-path; for the full
  // lockup we just show the whole thing.
  if (!crestOnly) {
    return (
      <img
        src="assets/logo.png"
        alt="Jai Mahal Palace, Jaipur"
        style={{
          height: size,
          width: "auto",
          opacity,
          display: "block",
        }}
      />
    );
  }
  // Crest only — show the icon portion (top 57% of the image).
  // We render at full width then mask off the lower wordmark band.
  const native = { w: 1149, h: 639 };
  const crestH = 360;            // crest extends from y=0 to ~y=360 in native px
  const crestAspect = native.w / crestH;  // ≈ 3.19, but the crest itself is narrow & centered
  // Easiest reliable approach: use background-image with size set so the crest fits.
  return (
    <div
      role="img"
      aria-label="Jai Mahal Palace crest"
      style={{
        width: size,
        height: size,
        backgroundImage: `url(assets/logo.png)`,
        // Scale the image so its width = size * (1149 / 380) ≈ size * 3.02 (the crest
        // is ~380 native px wide and centered). At this scale the crest fits in `size`.
        backgroundSize: `${size * 3.0}px auto`,
        backgroundPosition: "center top",
        backgroundRepeat: "no-repeat",
        opacity,
      }}
    />
  );
}

// ─── Ornamental hairline ───────────────────────────────────────────
function Rule({ variant = "diamond", color = "var(--gold)", width = 100 }) {
  if (variant === "plain") {
    return <div style={{ width, height: 1, background: color, opacity: 0.45 }} />;
  }
  // diamond: short line — diamond — short line
  return (
    <div style={{ display: "inline-flex", alignItems: "center", gap: 8, color }}>
      <span style={{ display: "block", width: width / 2 - 8, height: 1, background: "currentColor", opacity: 0.4 }} />
      <Icon.Diamond size={6} />
      <span style={{ display: "block", width: width / 2 - 8, height: 1, background: "currentColor", opacity: 0.4 }} />
    </div>
  );
}

// ─── Eyebrow label (small caps, gold) ───────────────────────────────
function Eyebrow({ children, color = "var(--gold-dark)", spacing = 3 }) {
  return (
    <span
      style={{
        fontFamily: "var(--font-sans)",
        fontSize: 11,
        fontWeight: 500,
        letterSpacing: spacing,
        textTransform: "uppercase",
        color,
        display: "inline-block",
      }}
    >
      {children}
    </span>
  );
}

// ─── Horizontal swipeable gallery ───────────────────────────────────
function Gallery({ images, aspect = "4/5", showCaption = true }) {
  const ref = useRef(null);
  const [idx, setIdx] = useState(0);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const onScroll = () => {
      const w = el.clientWidth;
      setIdx(Math.round(el.scrollLeft / w));
    };
    el.addEventListener("scroll", onScroll, { passive: true });
    return () => el.removeEventListener("scroll", onScroll);
  }, []);

  return (
    <div>
      <div
        ref={ref}
        className="gallery-scroll"
        style={{
          display: "flex",
          overflowX: "auto",
          scrollSnapType: "x mandatory",
          gap: 14,
          padding: "0 22px",
          margin: "0 -22px",
          scrollbarWidth: "none",
        }}
      >
        {images.map((img, i) => (
          <figure
            key={i}
            style={{
              flex: "0 0 78%",
              scrollSnapAlign: "center",
              margin: 0,
              display: "flex",
              flexDirection: "column",
              gap: 10,
            }}
          >
            <div
              style={{
                aspectRatio: aspect,
                background: `url(${img.src}) center/cover no-repeat var(--ink-faint)`,
                border: "1px solid var(--border)",
              }}
            />
            {showCaption && (
              <figcaption
                style={{
                  fontFamily: "var(--font-serif)",
                  fontStyle: "italic",
                  fontWeight: 400,
                  fontSize: 13,
                  lineHeight: 1.45,
                  color: "var(--ink-soft)",
                  paddingRight: 8,
                }}
              >
                {img.caption}
              </figcaption>
            )}
          </figure>
        ))}
      </div>
      {/* Dots */}
      <div style={{ display: "flex", gap: 6, justifyContent: "center", marginTop: 14 }}>
        {images.map((_, i) => (
          <span
            key={i}
            style={{
              width: i === idx ? 18 : 5,
              height: 5,
              borderRadius: 3,
              background: i === idx ? "var(--gold-dark)" : "var(--ink-faint-2)",
              transition: "width .25s, background .25s",
            }}
          />
        ))}
      </div>
    </div>
  );
}

// ─── Section header w/ ornamental rule ──────────────────────────────
function SectionHead({ eyebrow, title }) {
  return (
    <div style={{ textAlign: "center", padding: "0 24px 18px" }}>
      <Eyebrow>{eyebrow}</Eyebrow>
      <h2
        style={{
          fontFamily: "var(--font-serif)",
          fontWeight: 400,
          fontStyle: "italic",
          fontSize: 26,
          lineHeight: 1.15,
          margin: "8px 0 14px",
          color: "var(--ink)",
          textWrap: "pretty",
        }}
      >
        {title}
      </h2>
      <Rule width={70} />
    </div>
  );
}

// ─── Primary button ────────────────────────────────────────────────
function PrimaryBtn({ children, onClick, full = true, dark = true }) {
  return (
    <button
      onClick={onClick}
      style={{
        width: full ? "100%" : "auto",
        background: dark ? "var(--ink)" : "var(--gold-dark)",
        color: dark ? "var(--cream)" : "white",
        border: "none",
        padding: "16px 22px",
        fontFamily: "var(--font-sans)",
        fontSize: 12,
        fontWeight: 500,
        letterSpacing: 2.5,
        textTransform: "uppercase",
        cursor: "pointer",
        display: "inline-flex",
        alignItems: "center",
        justifyContent: "center",
        gap: 10,
        borderRadius: 0,
      }}
    >
      {children}
    </button>
  );
}

// ─── Ghost button ──────────────────────────────────────────────────
function GhostBtn({ children, onClick, full = true }) {
  return (
    <button
      onClick={onClick}
      style={{
        width: full ? "100%" : "auto",
        background: "transparent",
        color: "var(--ink)",
        border: "1px solid var(--ink)",
        padding: "15px 22px",
        fontFamily: "var(--font-sans)",
        fontSize: 12,
        fontWeight: 500,
        letterSpacing: 2.5,
        textTransform: "uppercase",
        cursor: "pointer",
        display: "inline-flex",
        alignItems: "center",
        justifyContent: "center",
        gap: 10,
        borderRadius: 0,
      }}
    >
      {children}
    </button>
  );
}

Object.assign(window, { BrandMark, BrandCrest, Rule, Eyebrow, Gallery, SectionHead, PrimaryBtn, GhostBtn, AutoCarousel });

// ─── Auto-cycling photo carousel ────────────────────────────────────
// Crossfades through `images` every `interval` ms. Pure CSS opacity transitions.
// Exposes index via onChange callback for caption sync.
function AutoCarousel({ images, interval = 4500, fade = 1000, paused = false, onIndexChange }) {
  const [idx, setIdx] = useState(0);

  useEffect(() => {
    if (paused || images.length <= 1) return;
    const t = setInterval(() => {
      setIdx((i) => (i + 1) % images.length);
    }, interval);
    return () => clearInterval(t);
  }, [paused, images.length, interval]);

  useEffect(() => {
    onIndexChange && onIndexChange(idx);
  }, [idx]);

  return (
    <div style={{ position: "absolute", inset: 0, overflow: "hidden" }}>
      {images.map((img, i) => {
        const src = typeof img === "string" ? img : img.src;
        const pos = typeof img === "string" ? "center" : img.pos || "center";
        return (
          <img
            key={i}
            src={src}
            alt=""
            style={{
              position: "absolute",
              inset: 0,
              width: "100%",
              height: "100%",
              objectFit: "cover",
              objectPosition: pos,
              opacity: i === idx ? 1 : 0,
              transition: `opacity ${fade}ms ease`,
              willChange: "opacity",
            }}
          />
        );
      })}
    </div>
  );
}
