// Shared components, placeholder art, language hook.
const { useState, useEffect, useRef, useMemo, useCallback } = React;

/* ---------------------- Language ---------------------- */
function useLang() {
  const [lang, setLang] = useState(() => {
    try { return localStorage.getItem("rh.lang") || "en"; } catch (_) { return "en"; }
  });
  const change = useCallback((l) => {
    setLang(l);
    try { localStorage.setItem("rh.lang", l); } catch (_) {}
  }, []);
  return [lang, change];
}

function pick(node, lang) {
  if (node == null) return node;
  if (typeof node === "string") return node;
  if (Array.isArray(node)) return node;
  if (typeof node === "object" && lang in node) return node[lang];
  return node;
}

/* ---------------------- Placeholder art ----------------------
   Soft striped abstract gradient using each project's swatch.
   Renders deterministically per project so previews feel like
   distinct artworks, not generic placeholders.
----------------------------------------------------------------*/
function ProjectArt({ project, label, variant = "card", shape, image }) {
  const [a, b, c] = project.swatch;
  const seed = useMemo(() => {
    let s = 0;
    for (let i = 0; i < project.id.length; i++) s = s * 31 + project.id.charCodeAt(i) >>> 0;
    return s;
  }, [project.id]);

  const imgSrc = image || (variant === "hero" && project.heroImage ? project.heroImage : variant === "preview" && project.previewImage ? project.previewImage : project.image);
  const isVideo = imgSrc && /\.(mp4|webm|mov)$/i.test(imgSrc);
  // If the project has a real video, render it.
  if (isVideo) {
    return (
      <video
        className={`art art-${variant} art-video`}
        src={imgSrc}
        autoPlay
        muted
        loop
        playsInline
        style={{
          position: "absolute",
          inset: 0,
          width: "100%",
          height: "100%",
          objectFit: "cover",
          backgroundColor: a
        }} />);

  }
  // If the project has a real image, render that with a corner mono label.
  if (imgSrc) {
    return (
      <div
        className={`art art-${variant} art-photo`}
        style={{
          position: "absolute",
          inset: 0,
          backgroundImage: `url("${imgSrc}")`,
          backgroundSize: variant === "hero" && project.heroImageFit ? project.heroImageFit : "cover",
          backgroundPosition: "center",
          backgroundRepeat: "no-repeat",
          backgroundColor: variant === "hero" && project.heroBgColor ? project.heroBgColor : "var(--bg)"
        }}>
        {label ?
        <div className="placeholder-art" style={{ position: "absolute", left: 20, bottom: 60, justifyContent: "flex-start", textAlign: "left", color: "rgba(255,255,255,0.9)", mixBlendMode: "difference" }}>
            {label}
          </div> :
        null}
      </div>);
  }

  // Build stripe rotation + offsets from seed for visual variety.
  const r1 = seed % 31 - 15;
  const r2 = (seed >> 4) % 31 - 15;
  const xOff = (seed >> 8) % 40 - 20;
  const yOff = (seed >> 12) % 40 - 20;

  const gradient = `linear-gradient(${130 + r1}deg, ${a} 0%, ${a} 40%, ${b} 100%)`;
  const stripes = `repeating-linear-gradient(${100 + r2}deg, rgba(255,255,255,0.0) 0 18px, rgba(255,255,255,0.05) 18px 19px)`;
  return (
    <div
      className={`art art-${variant}`}
      style={{
        position: "absolute",
        inset: 0,
        backgroundImage: `${stripes}, ${gradient}`,
        backgroundBlendMode: "overlay, normal"
      }}>
      
      {/* big tonal disc */}
      <div
        style={{
          position: "absolute",
          width: "62%",
          height: "62%",
          left: `calc(50% + ${xOff}px)`,
          top: `calc(50% + ${yOff}px)`,
          transform: "translate(-50%, -50%)",
          borderRadius: "50%",
          background: `radial-gradient(circle at 35% 30%, ${c} 0%, ${c}00 70%)`,
          mixBlendMode: "screen",
          opacity: 0.6
        }} />
      
      {/* horizon line */}
      <div
        style={{
          position: "absolute",
          left: "8%",
          right: "8%",
          top: `${52 + yOff / 4}%`,
          height: 1,
          background: "rgba(255,255,255,0.18)"
        }} />
      
      {label ?
      <div className="placeholder-art" style={{ position: "absolute", left: 20, bottom: 60, justifyContent: "flex-start", textAlign: "left" }}>
          {label}
        </div> :
      null}
    </div>);

}

/* ---------------------- BeforeAfterSlider ---------------------- */
function BeforeAfterSlider({ imageBefore, imageAfter, lang }) {
  const [pos, setPos] = useState(50);
  const [dragging, setDragging] = useState(false);
  const containerRef = useRef(null);

  const updatePos = (clientX) => {
    if (!containerRef.current) return;
    const rect = containerRef.current.getBoundingClientRect();
    const pct = Math.max(0, Math.min(100, ((clientX - rect.left) / rect.width) * 100));
    setPos(pct);
  };

  const onMouseDown = (e) => { e.preventDefault(); setDragging(true); };
  const onMouseMove = (e) => { if (dragging) updatePos(e.clientX); };
  const onMouseUp = () => setDragging(false);
  const onTouchMove = (e) => { updatePos(e.touches[0].clientX); };

  useEffect(() => {
    if (dragging) {
      window.addEventListener("mousemove", onMouseMove);
      window.addEventListener("mouseup", onMouseUp);
    }
    return () => {
      window.removeEventListener("mousemove", onMouseMove);
      window.removeEventListener("mouseup", onMouseUp);
    };
  }, [dragging, pos]);

  const beforeLabel = lang === "pt" ? "Antes" : "Before";
  const afterLabel  = lang === "pt" ? "Depois" : "After";

  return (
    <div
      ref={containerRef}
      style={{ position: "absolute", inset: 0, userSelect: "none", cursor: dragging ? "ew-resize" : "col-resize", overflow: "hidden" }}
      onTouchMove={onTouchMove}
      onTouchStart={(e) => updatePos(e.touches[0].clientX)}
    >
      {/* After (full width base) */}
      <img src={imageAfter} alt={afterLabel} style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", objectPosition: "center top", display: "block" }} draggable={false} />

      {/* Before (clipped to left of handle) */}
      <div style={{ position: "absolute", inset: 0, overflow: "hidden", width: `${pos}%` }}>
        <img src={imageBefore} alt={beforeLabel} style={{ position: "absolute", inset: 0, width: `${10000 / pos}%`, height: "100%", objectFit: "cover", objectPosition: "center top", maxWidth: "none", display: "block" }} draggable={false} />
      </div>

      {/* Divider line */}
      <div style={{ position: "absolute", top: 0, bottom: 0, left: `${pos}%`, width: "2px", background: "#ffffff", transform: "translateX(-50%)", pointerEvents: "none" }} />

      {/* Handle */}
      <div
        onMouseDown={onMouseDown}
        style={{
          position: "absolute",
          top: "50%",
          left: `${pos}%`,
          transform: "translate(-50%, -50%)",
          width: 44,
          height: 44,
          borderRadius: "50%",
          background: "#ffffff",
          boxShadow: "0 2px 12px rgba(0,0,0,0.25)",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          cursor: "ew-resize",
          zIndex: 10,
          gap: 4,
        }}
      >
        <svg width="18" height="18" viewBox="0 0 18 18" fill="none">
          <path d="M6 4L2 9L6 14" stroke="#131311" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
          <path d="M12 4L16 9L12 14" stroke="#131311" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      </div>

      {/* Labels */}
      <div style={{ position: "absolute", top: 16, left: 16, background: "rgba(0,0,0,0.55)", color: "#fff", fontSize: 11, fontFamily: "Apercu, sans-serif", letterSpacing: "0.08em", textTransform: "uppercase", padding: "4px 10px", borderRadius: 4, pointerEvents: "none" }}>{beforeLabel}</div>
      <div style={{ position: "absolute", top: 16, right: 16, background: "rgba(0,0,0,0.55)", color: "#fff", fontSize: 11, fontFamily: "Apercu, sans-serif", letterSpacing: "0.08em", textTransform: "uppercase", padding: "4px 10px", borderRadius: 4, pointerEvents: "none" }}>{afterLabel}</div>
    </div>
  );
}

/* ---------------------- Header ---------------------- */
function Header({ route, navigate, lang, setLang }) {
  const [scrolled, setScrolled] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);
  const headerRef = React.useRef(null);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 8);
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  useEffect(() => {
    if (menuOpen) document.body.style.overflow = "hidden";else
    document.body.style.overflow = "";
    return () => {document.body.style.overflow = "";};
  }, [menuOpen]);
  useEffect(() => {
    if (!headerRef.current) return;
    if (menuOpen) {
      headerRef.current.style.setProperty("background", "#ffffff", "important");
      headerRef.current.style.setProperty("color", "#131311", "important");
    } else {
      headerRef.current.style.removeProperty("background");
      headerRef.current.style.removeProperty("color");
    }
  }, [menuOpen]);
  const N = COPY.nav[lang];
  const onWork = route.name === "home" || route.name === "project";
  const goTo = (name) => {setMenuOpen(false);navigate({ name });};
  return (
    <>
      <header
        ref={headerRef}
        className={`site-header ${scrolled ? "is-scrolled" : ""} ${menuOpen ? "menu-open" : ""}`}
        style={{ height: "82.75px" }}>
        <a className="brand" href="#" onClick={(e) => {e.preventDefault();navigate({ name: "home" });}} style={{ fontWeight: "400", display: "flex", alignItems: "center" }}>
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 43.5 22.16" style={{ height: "17.6px", width: "auto", fill: route.name === "about" ? "#f3f1ea" : "#131311", display: "block", overflow: "visible" }} aria-label="Ricardo Hirth">
            <path d="M14.95,10.9c.46-.59.69-1.31.69-2.15,0-1.16-.44-2.07-1.32-2.71-.88-.65-2.1-.97-3.66-.97h-4.01v12.07h2.27v-4.74h1.86l2.79,4.74h2.55l-3.12-5.02c.84-.22,1.49-.62,1.95-1.22ZM10.98,10.53h-2.06v-3.56h2.06c.78,0,1.39.15,1.82.45.43.3.65.72.65,1.25,0,.57-.22,1.02-.65,1.36-.43.34-1.04.5-1.82.5Z"/>
            <path d="M18.86,3.22c-1.01-1.01-2.18-1.8-3.5-2.37-1.32-.57-2.76-.85-4.29-.85s-2.98.28-4.32.85-2.51,1.36-3.52,2.37-1.8,2.19-2.37,3.52c-.57,1.34-.85,2.77-.85,4.32s.28,2.98.85,4.31c.57,1.34,1.36,2.51,2.37,3.52s2.19,1.81,3.52,2.39c1.34.58,2.77.87,4.32.87s2.97-.29,4.29-.87c1.32-.58,2.49-1.38,3.5-2.39,1.01-1.01,1.8-2.19,2.37-3.52.57-1.34.85-2.77.85-4.31s-.28-2.98-.85-4.32c-.57-1.34-1.36-2.51-2.37-3.52ZM18.65,15.46c-.74,1.34-1.76,2.4-3.06,3.2-1.3.8-2.81,1.2-4.54,1.2s-3.25-.4-4.56-1.2c-1.31-.8-2.34-1.86-3.08-3.2-.74-1.34-1.12-2.8-1.12-4.4s.37-3.05,1.12-4.38c.74-1.32,1.77-2.38,3.08-3.16,1.31-.78,2.83-1.17,4.56-1.17s3.24.39,4.54,1.17c1.3.78,2.32,1.84,3.06,3.16.74,1.32,1.11,2.78,1.11,4.38s-.37,3.06-1.11,4.4Z"/>
            <polygon points="39.37 .89 39.37 9.95 28.78 9.95 28.78 .89 26.48 .89 26.48 21.36 28.78 21.36 28.78 12.19 39.37 12.19 39.37 21.36 41.68 21.36 41.68 .89 39.37 .89"/>
          </svg>
        </a>
        <nav className="nav">
          <a href="#" className={onWork ? "active" : ""} onClick={(e) => {e.preventDefault();navigate({ name: "home" });}}>{N.work}</a>
          <a href="#" className={route.name === "about" ? "active" : ""} onClick={(e) => {e.preventDefault();navigate({ name: "about" });}}>{N.about}</a>
          <span className="lang" role="group" aria-label="Language">
            <button className={lang === "en" ? "on" : ""} onClick={() => setLang("en")} aria-pressed={lang === "en"}>EN</button>
            <span className="sep">·</span>
            <button className={lang === "pt" ? "on" : ""} onClick={() => setLang("pt")} aria-pressed={lang === "pt"}>PT</button>
          </span>
        </nav>
        <div className="nav-mobile-right">
          {!menuOpen &&
          <span className="lang" role="group" aria-label="Language">
              <button className={lang === "en" ? "on" : ""} onClick={() => setLang("en")} aria-pressed={lang === "en"}>EN</button>
              <span className="sep">·</span>
              <button className={lang === "pt" ? "on" : ""} onClick={() => setLang("pt")} aria-pressed={lang === "pt"}>PT</button>
            </span>
          }
          <button className="hamburger" aria-label="Menu" aria-expanded={menuOpen} onClick={() => setMenuOpen((o) => !o)}>
            <span className={menuOpen ? "open" : ""}></span>
            <span className={menuOpen ? "open" : ""}></span>
            <span className={menuOpen ? "open" : ""}></span>
          </button>
        </div>
      </header>
      <div className={`mobile-menu ${menuOpen ? "is-open" : ""}`}>
        <nav>
          <a href="#" className={onWork ? "active" : ""} onClick={(e) => {e.preventDefault();goTo("home");}}>{N.work}</a>
          <a href="#" className={route.name === "about" ? "active" : ""} onClick={(e) => {e.preventDefault();goTo("about");}}>{N.about}</a>
        </nav>
      </div>
    </>);

}

/* ---------------------- Footer ---------------------- */
function Footer({ lang }) {
  return (
    <footer className="site-footer">
      <div className="footer-col">
        <a href="mailto:ricardohirth@gmail.com" target="_blank" rel="noreferrer" className="footer-email">→ ricardohirth@gmail.com</a>
      </div>
      <div className="footer-col">
        <a href="https://linkedin.com/in/ricardohirth" target="_blank" rel="noreferrer">LinkedIn</a>
      </div>
      <div className="footer-col">
        <a href="https://instagram.com/ricardohirth" target="_blank" rel="noreferrer">Instagram</a>
      </div>
      <div className="footer-col footer-rights">
        <span>{COPY.footer.rights[lang]}</span>
      </div>
    </footer>);
}

/* expose */
Object.assign(window, { useLang, pick, ProjectArt, BeforeAfterSlider, Header, Footer });