/* Shared atoms — reveal, placeholders, tags, nav, footer */

const { useState, useEffect, useLayoutEffect, useRef, useCallback } = React;
const DATA = window.PORTFOLIO_DATA;

/* ---- Reveal on scroll ---- */
function useReveal() {
  const ref = useRef(null);
  useEffect(() => {
    const els = ref.current ? ref.current.querySelectorAll(".reveal") : [];
    if (!els.length) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add("in"); io.unobserve(e.target); } });
    }, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" });
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  });
  return ref;
}

/* ---- Disciplines, as a readable string ---- */
function disciplineLabel(tagIds) {
  return tagIds.map((id) => DATA.tags[id] ? DATA.tags[id].label : id).join("  ·  ");
}

/* ---- Tag filter button ---- */
function Tag({ id, active, onClick }) {
  const t = DATA.tags[id];
  if (!t) return null;
  return (
    <button className={"tag" + (active ? " active" : "")} onClick={onClick} type="button">{t.label}</button>
  );
}

/* ---- Striped placeholder (drop-in image / video) ---- */
function Placeholder({ aspect = "aspect-16-9", label = "image", kind = "image", dark = false, className = "", src = null, srcset = null, sizes = null }) {
  if (src) {
    return (
      <div className={`ph ${aspect} ${dark ? "dark" : ""} ${className}`}>
        {kind === "video"
          ? <video src={src} className="ph-img" autoPlay loop muted playsInline />
          : <img src={src} srcSet={srcset || undefined} sizes={sizes || undefined} alt={label} className="ph-img" loading="lazy" />
        }
      </div>
    );
  }
  return (
    <div className={`ph ${aspect} ${kind === "video" ? "ph-video" : ""} ${dark ? "dark" : ""} ${className}`}>
      {kind === "video" && <span className="play" />}
      <span className="ph-label">{label}</span>
    </div>
  );
}

/* ---- Navigation (turns light over the dark hero) ---- */
function Nav({ view, go }) {
  const [onDark, setOnDark] = useState(view.name === "home");
  const [menuOpen, setMenuOpen] = useState(false);
  useEffect(() => {
    if (view.name !== "home") { setOnDark(false); return; }
    const onScroll = () => setOnDark(window.scrollY < window.innerHeight * 0.78);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, [view.name]);

  // close the mobile menu whenever the view changes
  useEffect(() => { setMenuOpen(false); }, [view.name, view.id]);

  // easter egg: 5 rapid wordmark clicks → "ow! stop it!"
  const [ouch, setOuch] = useState(false);
  const clickTimes = useRef([]);
  const ouchTimer = useRef(null);
  useEffect(() => () => clearTimeout(ouchTimer.current), []);

  const onWordmark = () => {
    const now = Date.now();
    clickTimes.current = [...clickTimes.current, now].filter((t) => now - t < 3000);
    if (clickTimes.current.length >= 5) {
      clickTimes.current = [];
      setOuch(true);
      clearTimeout(ouchTimer.current);
      ouchTimer.current = setTimeout(() => setOuch(false), 2000);
    }
    nav({ name: "home" });
  };

  const nav = (v) => { setMenuOpen(false); go(v); };

  const links = [
    { name: "home", label: "Work" },
    { name: "manifesto", label: "How I Think" },
    { name: "contact", label: "Contact" },
  ];

  return (
    <nav className={"nav" + (onDark ? " on-dark" : "") + (menuOpen ? " menu-open" : "")}>
      <div className="nav-inner">
        <div className="wordmark" onClick={onWordmark}>
          <b>{DATA.meta.name}</b>
          {ouch && <span className="wordmark-ouch">ow! stop it!</span>}
        </div>
        <div className="nav-links">
          {links.map((l) => (
            <span key={l.name} className={"nav-link" + (view.name === l.name ? " active" : "")} onClick={() => nav({ name: l.name })}>{l.label}</span>
          ))}
        </div>
        <div className="nav-stamp">{DATA.meta.updated}</div>
        <button
          className={"nav-burger" + (menuOpen ? " open" : "")}
          onClick={() => setMenuOpen((o) => !o)}
          aria-label={menuOpen ? "Close menu" : "Open menu"}
          aria-expanded={menuOpen}
          type="button"
        >
          <span /><span /><span />
        </button>
      </div>
      <div className="nav-menu">
        {links.map((l) => (
          <span key={l.name} className={"nav-menu-link" + (view.name === l.name ? " active" : "")} onClick={() => nav({ name: l.name })}>{l.label}</span>
        ))}
      </div>
    </nav>
  );
}

/* ---- Footer ---- */
function Footer({ go }) {
  return (
    <footer className="foot">
      <div className="foot-inner">
        <div>
          <h4> </h4>
          <div className="big">What is design if not <em>experienced</em> by humans?</div>
        </div>
        <div>
          <h4>Navigate</h4>
          <ul>
            <li onClick={() => go({ name: "home" })}>Selected work</li>
            <li onClick={() => go({ name: "manifesto" })}>How I think</li>
          </ul>
        </div>
        <div>
          <h4>Contact</h4>
          <ul>
            <li><a href="mailto:maxtbentley@gmail.com">Email @ maxtbentley@gmail.com</a></li>
            <li><a href="https://www.linkedin.com/in/max-bentley-5351542b4/" target="_blank" rel="noopener">LinkedIn</a></li>
          </ul>
        </div>
      </div>
      <div className="foot-inner" style={{ paddingTop: 0, paddingBottom: 52 }}>
        <div className="foot-stamp">
          
          {DATA.meta.name} — {DATA.meta.role}<br />
          {DATA.meta.location}. {DATA.meta.updated}.
          <p style={{ marginTop: 8 }}>This site was designed and built by me, with React and a lot of love.</p>
        </div>
      </div>
    </footer>
  );
}

Object.assign(window, { useReveal, disciplineLabel, Tag, Placeholder, Nav, Footer, DATA });
