// Shared UI components for the Atelier Koolmees rebuild.

// ── Placeholder ────────────────────────────────────────────────────────────
// Striped SVG placeholder with a monospace caption — used in lieu of real photos.
function Placeholder({ aspect = "4 / 5", tone = "warm", caption, label, dense = false }) {
  // Tone-tinted neutrals so categories feel different without using real color.
  const palettes = {
    warm: { bg: "#efe9df", stripe: "#e2d8c8", text: "#7a6a52" },
    cool: { bg: "#e6e8eb", stripe: "#d3d6db", text: "#6a737d" },
    ink: { bg: "#1a1816", stripe: "#23211e", text: "#c9bfae" }
  };
  const p = palettes[tone] || palettes.warm;
  const stripeId = React.useId();
  return (
    <div style={{
      position: "relative", width: "100%", aspectRatio: aspect,
      background: p.bg, overflow: "hidden",
      border: `0.5px solid ${tone === 'ink' ? 'rgba(255,255,255,.1)' : 'rgba(0,0,0,.06)'}`
    }}>
      <svg width="100%" height="100%" style={{ position: "absolute", inset: 0, display: "block" }}>
        <defs>
          <pattern id={stripeId} width="14" height="14" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
            <line x1="0" y1="0" x2="0" y2="14" stroke={p.stripe} strokeWidth="6" />
          </pattern>
        </defs>
        <rect width="100%" height="100%" fill={`url(#${stripeId})`} opacity="0.5" />
      </svg>
      {(caption || label) &&
      <div style={{
        position: "absolute", inset: 0, display: "flex",
        flexDirection: "column", alignItems: "center", justifyContent: "center",
        gap: 6, color: p.text, fontFamily: "ui-monospace, 'SF Mono', Menlo, monospace",
        fontSize: dense ? 10 : 11, letterSpacing: ".04em", textAlign: "center", padding: 16
      }}>
          {label && <div style={{ textTransform: "uppercase", opacity: .65 }}>{label}</div>}
          {caption && <div style={{ opacity: .85, maxWidth: "80%" }}>{caption}</div>}
        </div>
      }
    </div>);

}

// ── Nav ─────────────────────────────────────────────────────────────────────
function Nav({ route, lang, setLang, onNav, accent, dark }) {
  const c = COPY[lang];
  const linkStyle = (active) => ({
    color: "inherit",
    textDecoration: "none",
    opacity: active ? 1 : 0.55,
    cursor: "pointer",
    fontWeight: 400,
    transition: "opacity .2s ease",
    borderBottom: active ? `1px solid currentColor` : "1px solid transparent",
    paddingBottom: 1
  });
  const onLinkEnter = (active) => (e) => { e.currentTarget.style.opacity = active ? ".55" : "1"; };
  const onLinkLeave = (active) => (e) => { e.currentTarget.style.opacity = active ? "1" : ".55"; };
  const onWerk = () => onNav({ kind: "home" });
  const onOver = () => onNav({ kind: "about" });
  const isHome = route.kind === "home";
  const isAbout = route.kind === "about";

  return (
    <header style={{
      position: "sticky", top: 0, zIndex: 10,
      display: "flex", alignItems: "center", justifyContent: "space-between",
      padding: "16px clamp(20px, 4vw, 56px)",
      background: dark ? "rgba(20,18,16,.78)" : "rgba(250,248,243,.78)",
      backdropFilter: "blur(14px) saturate(150%)",
      WebkitBackdropFilter: "blur(14px) saturate(150%)",
      borderBottom: dark ? "0.5px solid rgba(255,255,255,.07)" : "0.5px solid rgba(0,0,0,.06)"
    }}>
      <a onClick={onWerk}
        onMouseEnter={(e) => e.currentTarget.style.opacity = ".55"}
        onMouseLeave={(e) => e.currentTarget.style.opacity = "1"}
        style={{
        cursor: "pointer", display: "flex", alignItems: "center", gap: 12,
        textDecoration: "none", color: "inherit",
        opacity: 1, transition: "opacity .2s ease"
      }}>
        <img src="assets/pk-logo.svg" alt="PK" width="54" height="48" className="nav-logo-img"
        style={{ display: "block", objectFit: "contain",
          filter: dark ? "invert(1)" : "none" }} />
        <span style={{ display: "flex", flexDirection: "column", gap: 4, lineHeight: 1 }}>
          <span className="nav-name" style={{
            fontFamily: "var(--font-display)",
            fontSize: "clamp(18px, 1.7vw, 21px)", letterSpacing: ".01em",
            fontWeight: 500
          }}>{SITE.artist}</span>
          <span className="nav-tagline" style={{
            fontFamily: "ui-monospace, monospace", fontSize: 11,
            letterSpacing: ".18em", textTransform: "uppercase", opacity: .55
          }}>{c.tagline}</span>
        </span>
      </a>
      <nav className="nav-links" style={{ display: "flex", gap: 28, alignItems: "center", fontSize: 14 }}>
        <a onClick={onWerk}
          onMouseEnter={onLinkEnter(isHome || route.kind === "project")}
          onMouseLeave={onLinkLeave(isHome || route.kind === "project")}
          style={linkStyle(isHome || route.kind === "project")}>{c.werk}</a>
        <a onClick={onOver}
          onMouseEnter={onLinkEnter(isAbout)}
          onMouseLeave={onLinkLeave(isAbout)}
          style={linkStyle(isAbout)}>{c.over}</a>
        <span style={{ width: 1, height: 14, background: "currentColor", opacity: .15, margin: "0 4px" }} />
        <button
          onClick={() => setLang(lang === "nl" ? "en" : "nl")}
          onMouseEnter={(e) => e.currentTarget.style.opacity = "1"}
          onMouseLeave={(e) => e.currentTarget.style.opacity = ".55"}
          style={{
            appearance: "none", background: "transparent", border: 0, color: "inherit",
            cursor: "pointer", fontSize: 12, letterSpacing: ".15em",
            textTransform: "uppercase", opacity: .55, fontFamily: "inherit",
            transition: "opacity .2s ease"
          }}>
          {lang === "nl" ? "EN" : "NL"}
        </button>
      </nav>
    </header>);

}

// ── Footer ──────────────────────────────────────────────────────────────────
function Footer({ dark }) {
  const iconStyle = {
    width: 18, height: 18, opacity: .55, transition: "opacity .15s ease"
  };
  return (
    <footer style={{
      display: "flex", alignItems: "center", justifyContent: "space-between",
      padding: "32px clamp(20px, 4vw, 56px)",
      borderTop: dark ? "0.5px solid rgba(255,255,255,.07)" : "0.5px solid rgba(0,0,0,.06)",
      fontSize: 12, letterSpacing: ".05em", opacity: .7
    }}>
      <div style={{ fontFamily: "ui-monospace, monospace" }}>{SITE.copyright}</div>
      <div style={{ display: "flex", gap: 18, alignItems: "center" }}>
        <a href={`tel:${SITE.phone.replace(/\s/g, '')}`} aria-label="Phone"
        style={{ color: "inherit", display: "inline-flex" }}
        onMouseEnter={(e) => e.currentTarget.style.opacity = "1"}
        onMouseLeave={(e) => e.currentTarget.style.opacity = ""}>
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" style={iconStyle}>
            <path d="M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07 19.5 19.5 0 01-6-6 19.79 19.79 0 01-3.07-8.67A2 2 0 014.11 2h3a2 2 0 012 1.72c.13.96.36 1.9.7 2.81a2 2 0 01-.45 2.11L8.09 9.91a16 16 0 006 6l1.27-1.27a2 2 0 012.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0122 16.92z" />
          </svg>
        </a>
        <a href={`mailto:${SITE.email}`} aria-label="Email" style={{ color: "inherit", display: "inline-flex" }}>
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" style={iconStyle}>
            <rect x="2" y="4" width="20" height="16" rx="2" /><path d="M2 7l10 7 10-7" />
          </svg>
        </a>
        <a href={SITE.instagramUrl} target="_blank" rel="noopener" aria-label="Instagram"
        style={{ color: "inherit", display: "inline-flex" }}>
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" style={iconStyle}>
            <rect x="3" y="3" width="18" height="18" rx="5" />
            <circle cx="12" cy="12" r="4" />
            <circle cx="17.5" cy="6.5" r=".75" fill="currentColor" />
          </svg>
        </a>
      </div>
    </footer>);

}

// ── Project list rows (homepage layouts) ───────────────────────────────────
function ListRow({ project, lang, onClick, layout, hovered, setHovered, index, total }) {
  const t = project.titles[lang];
  const c = COPY[lang];

  if (layout === "grid") {
    return (
      <a onClick={onClick}
      onMouseEnter={() => setHovered(project.slug)}
      onMouseLeave={() => setHovered(null)}
      style={{
        display: "block", cursor: "pointer", color: "inherit",
        textDecoration: "none", transition: "transform .25s ease",
        transform: hovered === project.slug ? "translateY(-2px)" : "none"
      }}>
        <Placeholder aspect="4 / 5" tone={project.placeholder.tone} label={c[`section${cap(project.category)}`]} caption={c.placeholderNote} />
        <div style={{ display: "flex", justifyContent: "space-between", marginTop: 14, fontSize: 14 }}>
          <span style={{ fontFamily: "var(--font-display)" }}>{t}</span>
          <span style={{ opacity: .5, fontVariantNumeric: "tabular-nums" }}>{project.year}</span>
        </div>
      </a>);

  }

  // text-list (default)
  return (
    <a onClick={onClick}
    onMouseEnter={() => setHovered(project.slug)}
    onMouseLeave={() => setHovered(null)}
    style={{
      display: "grid",
      gridTemplateColumns: "60px 1fr auto",
      gap: 24,
      alignItems: "baseline",
      padding: "26px 0",
      borderBottom: "0.5px solid currentColor",
      borderColor: "rgba(0,0,0,.08)",
      color: "inherit", textDecoration: "none", cursor: "pointer",
      opacity: hovered && hovered !== project.slug ? .4 : 1,
      transition: "opacity .2s ease"
    }}>
      <span style={{
        fontFamily: "ui-monospace, monospace", fontSize: 11,
        opacity: .45, letterSpacing: ".08em"
      }}>
        {String(index + 1).padStart(2, "0")} / {String(total).padStart(2, "0")}
      </span>
      <span style={{
        fontFamily: "var(--font-display)",
        fontSize: "clamp(28px, 4vw, 52px)",
        fontWeight: 400, lineHeight: 1.05, letterSpacing: "-.01em"
      }}>
        {t}
      </span>
      <span style={{
        fontFamily: "ui-monospace, monospace", fontSize: 11,
        opacity: .45, letterSpacing: ".08em", whiteSpace: "nowrap"
      }}>
        {project.year}
      </span>
    </a>);

}

function cap(s) {return s.charAt(0).toUpperCase() + s.slice(1);}

// ── Hover preview (for text-list with image-on-hover) ──────────────────────
// Renders ALL project thumbnails up front (preloaded by the browser) and
// fades between them via opacity. No re-mounting → no flash, no layout jump.
function HoverPreview({ projects, hoveredSlug, mouse }) {
  // Smoothed cursor position so the preview doesn't lag/jitter
  const [pos, setPos] = React.useState({ x: mouse.x, y: mouse.y });
  React.useEffect(() => {
    let raf;
    const tick = () => {
      setPos((p) => ({
        x: p.x + (mouse.x - p.x) * 0.18,
        y: p.y + (mouse.y - p.y) * 0.18
      }));
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [mouse.x, mouse.y]);

  return (
    <div style={{
      position: "fixed",
      left: 0, top: 0,
      transform: `translate(${pos.x + 24}px, ${pos.y - 60}px)`,
      width: 280, height: 350,
      pointerEvents: "none", zIndex: 5,
      opacity: hoveredSlug ? 1 : 0,
      transition: "opacity .18s ease",
      boxShadow: "0 20px 60px rgba(0,0,0,.18)",
      background: "#ffffff",
      willChange: "transform, opacity"
    }}>
      {projects.map((p) => (
        <img key={p.slug} src={p.hero} alt=""
          loading="eager" decoding="async"
          style={{
            position: "absolute", inset: 0,
            width: "100%", height: "100%",
            objectFit: "cover", display: "block",
            opacity: hoveredSlug === p.slug ? 1 : 0,
            transition: "opacity .18s ease"
          }} />
      ))}
    </div>);

}

Object.assign(window, {
  Placeholder, Nav, Footer, ListRow, HoverPreview, cap
});