// v5 — Earlier Signals (legacy clients, logo wall)
// Org names are rendered as monochrome typographic wordmark "logos" — a
// restrained client-logo treatment. `mark` keys a small generic geometric
// glyph (never a real trademark); `logoClass` tunes the wordmark personality.
// To drop in real, licensed logo files later, set `logoImg` on a signal and
// the component will render the image instead of the wordmark.

const SIGNALS = [
  {
    n: "01",
    name: "Apple",
    logoClass: "is-apple",
    logoImg: "assets/logos/apple.png",
    mark: "dot",
    years: "2015",
    role: "Apple Music · product & experience design",
    taught: "Taste at launch speed.",
    body: "Rapid prototyping for Apple Music creative and product exploration during the platform's early development.",
    work: "src/assets/work/apple-work.png",
    workCaption: "Apple Music · launch identity",
  },
  {
    n: "02",
    name: "Adobe",
    logoClass: "is-adobe",
    logoImg: "assets/logos/adobe.png",
    mark: "triangle",
    years: "2012–14",
    role: "Marketing Cloud · campaign analytics & data visualization",
    taught: "Patented workflow design for data-heavy products.",
    body: "Product design across campaign analytics and marketing intelligence. The work resulted in three granted invention patents in reporting, visualization, and workflow systems.",
    work: "src/assets/work/adobe-work.jpg",
    workCaption: "Marketing Cloud · feed & boards",
  },
  {
    n: "03",
    name: "airbnb",
    logoClass: "is-airbnb",
    logoImg: "assets/logos/airbnb.png",
    mark: "ring",
    years: "2016",
    role: "Airbnb Trips · discovery + experiences",
    taught: "Turning travel into service discovery.",
    body: "Design sprints supporting the launch of Airbnb Trips, helping shape new ways for travelers to discover local experiences beyond lodging.",
    work: "src/assets/work/airbnb-work.webp",
    workCaption: "Airbnb Trips · world of trips",
  },
  {
    n: "04",
    name: "Logitech",
    logoClass: "is-logitech",
    logoImg: "assets/logos/logitech.png",
    mark: "square",
    years: "2017–19",
    role: "Hardware + services ecosystem",
    taught: "Where hardware and software have to behave like one product.",
    body: "Cross-device experience work where physical products, software services, and ecosystem behavior had to feel coherent.",
    work: "src/assets/work/logitech-work.png",
    workCaption: "Logitech G · device + control UI",
  },
  {
    n: "05",
    name: "Target",
    logoClass: "is-target",
    logoImg: "assets/logos/target.png",
    mark: "diamond",
    years: "2017",
    role: "In-store baby registry · service design",
    taught: "Decision architecture in retail.",
    body: "Reframed baby registry bundles around the real moments parents navigate, turning a SKU list into a guide for a life stage.",
    work: "src/assets/work/target-work.webp",
    workCaption: "Target · registry life-stage guide",
  },
  {
    n: "06",
    name: "Disney",
    logoClass: "is-disney",
    logoImg: "assets/logos/disney.png",
    mark: "spark",
    years: "2009–11",
    role: "Social game + platform systems",
    taught: "Designing behavior before the patterns were obvious.",
    body: "Product design for NBA Dynasty, a social gaming platform that connected sports fandom, gameplay systems, visual identity, and online community behavior.",
    work: "src/assets/work/disney-work.jpg",
    workCaption: "NBA Dynasty · social matchup UI",
  },
];

const SignalMark = ({ kind }) => {
  const C = { width: 22, height: 22, viewBox: "0 0 24 24", "aria-hidden": "true", className: "v5-signals-mark-svg" };
  switch (kind) {
    case "dot":      return <svg {...C}><circle cx="12" cy="12" r="5.5" fill="currentColor" /></svg>;
    case "ring":     return <svg {...C}><circle cx="12" cy="12" r="7" fill="none" stroke="currentColor" strokeWidth="2.4" /></svg>;
    case "square":   return <svg {...C}><rect x="5.5" y="5.5" width="13" height="13" rx="2" fill="currentColor" /></svg>;
    case "diamond":  return <svg {...C}><rect x="6" y="6" width="12" height="12" rx="1.5" transform="rotate(45 12 12)" fill="currentColor" /></svg>;
    case "triangle": return <svg {...C}><path d="M12 5 L19 18 L5 18 Z" fill="currentColor" /></svg>;
    case "spark":    return <svg {...C}><path d="M12 4 C12 9 15 12 20 12 C15 12 12 15 12 20 C12 15 9 12 4 12 C9 12 12 9 12 4 Z" fill="currentColor" /></svg>;
    default:         return null;
  }
};

// Cursor-following work preview. Reveals the hovered company's real work as a
// floating "peek" card that trails the pointer (lerped) and flips to the other
// side near the viewport edge so it never clips off-screen.
const WorkPeek = ({ active }) => {
  const cardRef = useRef(null);
  const target = useRef({ x: 0, y: 0 });
  const cur = useRef({ x: 0, y: 0 });
  const raf = useRef(0);
  const seeded = useRef(false);

  useEffect(() => {
    const onMove = (e) => {
      target.current.x = e.clientX;
      target.current.y = e.clientY;
      if (!seeded.current) {
        cur.current.x = e.clientX;
        cur.current.y = e.clientY;
        seeded.current = true;
      }
    };
    window.addEventListener("pointermove", onMove, { passive: true });

    const W = 380, H = 250, PAD = 18, OFF = 26;
    const tick = () => {
      cur.current.x += (target.current.x - cur.current.x) * 0.18;
      cur.current.y += (target.current.y - cur.current.y) * 0.18;
      const card = cardRef.current;
      if (card) {
        const vw = window.innerWidth, vh = window.innerHeight;
        // Prefer right of cursor; flip left if it would overflow.
        let x = cur.current.x + OFF;
        if (x + W + PAD > vw) x = cur.current.x - OFF - W;
        x = Math.max(PAD, Math.min(x, vw - W - PAD));
        let y = cur.current.y - H / 2;
        y = Math.max(PAD, Math.min(y, vh - H - PAD));
        card.style.transform = `translate(${x}px, ${y}px)`;
      }
      raf.current = requestAnimationFrame(tick);
    };
    raf.current = requestAnimationFrame(tick);
    return () => {
      window.removeEventListener("pointermove", onMove);
      cancelAnimationFrame(raf.current);
    };
  }, []);

  return (
    <div className={`v5-peek ${active ? "is-on" : ""}`} ref={cardRef} aria-hidden="true">
      <div className="v5-peek-frame">
        {SIGNALS.map((s) => (
          <img
            key={s.name}
            className={`v5-peek-img ${active === s.name ? "is-shown" : ""}`}
            src={s.work}
            alt=""
            loading="lazy"
            draggable="false" />
        ))}
      </div>
      <div className="v5-peek-cap">
        {SIGNALS.map((s) => (
          <span key={s.name} className={`v5-peek-cap-line ${active === s.name ? "is-shown" : ""}`}>
            <span className="v5-peek-cap-dot"></span>{s.workCaption}
          </span>
        ))}
      </div>
    </div>
  );
};

const V5Signals = () => {
  const [hovered, setHovered] = useState(null);
  return (
    <section className="v5-signals" data-screen-label="Earlier Signals">
      <WorkPeek active={hovered} />
      <div className="v4-container">
        <header className="v5-signals-head v5-signals-head-2col">
          <div>
            <span className="v5-signals-eyebrow">
              <span className="v5-signals-eyebrow-rule"></span>
              <span className="v5-signals-eyebrow-num">01B</span>
              <span>Earlier signals · where the range came from</span>
            </span>
            <h2 className="v5-signals-title" data-cursor="Six places · 20+ yrs">
              <WordReveal text="Six places the practice learned" stagger={50}/>
              <br/>
              <span className="emph"><WordReveal text="how to work." stagger={60} startDelay={500}/></span>
            </h2>
          </div>
          <p className="v5-signals-lede">
            <FadeIn delay={300}>
              The work is old enough that the interfaces are less important than the instincts they produced: rapid prototyping, patented workflow design, service discovery, physical/digital systems, retail decision architecture, and early social platforms.
            </FadeIn>
          </p>
        </header>

        <div className="v5-signals-table">
          {SIGNALS.map((s, i) => (
            <FadeIn as="div" key={s.name} delay={i * 80} className={`v5-signals-row ${s.work ? "has-peek" : ""} ${hovered === s.name ? "is-peeking" : ""}`} data-cursor={`${s.name} · ${s.years}`}
              onMouseEnter={() => s.work && setHovered(s.name)}
              onMouseLeave={() => setHovered((h) => (h === s.name ? null : h))}>
              <span className="v5-signals-n">{s.n}</span>
              <div className="v5-signals-cell v5-signals-cell-name">
                <span className={`v5-signals-logo ${s.logoClass || ""}`} aria-label={s.name}>
                  {s.logoImg
                    ? <img className="v5-signals-logo-img" src={s.logoImg} alt={s.name} />
                    : <React.Fragment>
                        <span className="v5-signals-mark" aria-hidden="true"><SignalMark kind={s.mark} /></span>
                        <span className="v5-signals-logo-text">{s.name}</span>
                      </React.Fragment>}
                </span>
                <span className="v5-signals-years">{s.years}</span>
              </div>
              <div className="v5-signals-cell v5-signals-cell-role">{s.role}</div>
              <div className="v5-signals-cell v5-signals-cell-body">
                <p className="v5-signals-taught"><span className="emph">{s.taught}</span></p>
                <p className="v5-signals-body">{s.body}</p>
              </div>
            </FadeIn>
          ))}
        </div>
      </div>
    </section>
  );
};

Object.assign(window, { V5Signals });
