/* global React */
const { useState, useEffect, useRef } = React;

/* ── Frog SVG path data (shared) ── */
const FROG_SVG = `<svg viewBox="0 0 40 40" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
  <ellipse cx="20" cy="24" rx="14" ry="11" fill="currentColor"/>
  <circle cx="13" cy="13" r="6" fill="currentColor"/>
  <circle cx="27" cy="13" r="6" fill="currentColor"/>
  <circle cx="13" cy="13" r="4" fill="#fff"/>
  <circle cx="27" cy="13" r="4" fill="#fff"/>
  <circle cx="13" cy="14" r="1.8" fill="#1a3300"/>
  <circle cx="27" cy="14" r="1.8" fill="#1a3300"/>
  <path d="M12 26 Q20 30 28 26" stroke="#1a3300" stroke-width="1.4" fill="none" stroke-linecap="round"/>
  <circle cx="9" cy="25" r="1.2" fill="rgba(0,0,0,0.2)"/>
  <circle cx="31" cy="25" r="1.2" fill="rgba(0,0,0,0.2)"/>
</svg>`;

/* ── FrogCursor — smooth-following dot cursor ── */
function FrogCursor() {
  const ref = useRef(null);
  const [hover, setHover] = useState(false);
  const [down,  setDown]  = useState(false);

  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let raf = 0;
    let tx = window.innerWidth  / 2;
    let ty = window.innerHeight / 2;
    let x  = tx, y = ty;

    const onMove = (e) => { tx = e.clientX; ty = e.clientY; };
    const onDown = () => setDown(true);
    const onUp   = () => setDown(false);

    const tick = () => {
      x += (tx - x) * 0.25;
      y += (ty - y) * 0.25;
      el.style.left = x + "px";
      el.style.top  = y + "px";
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);

    const sel = "a, button, [role='button'], .nav-item, .work-row, .journal-entry, [data-cursor='hover']";
    const onOver = (e) => { if (e.target.closest(sel)) setHover(true);  };
    const onOut  = (e) => { if (e.target.closest(sel)) setHover(false); };

    window.addEventListener("mousemove",  onMove);
    window.addEventListener("mousedown",  onDown);
    window.addEventListener("mouseup",    onUp);
    document.addEventListener("mouseover",  onOver);
    document.addEventListener("mouseout",   onOut);

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("mousemove",  onMove);
      window.removeEventListener("mousedown",  onDown);
      window.removeEventListener("mouseup",    onUp);
      document.removeEventListener("mouseover",  onOver);
      document.removeEventListener("mouseout",   onOut);
    };
  }, []);

  return (
    <div
      ref={ref}
      className={"frog-cursor" + (hover ? " is-hover" : "") + (down ? " is-down" : "")}
      aria-hidden="true"
    >
      <svg viewBox="0 0 40 40" width="36" height="36">
        <ellipse cx="20" cy="24" rx="14" ry="11" fill="var(--accent, #9bd34a)" />
        <circle cx="13" cy="13" r="6" fill="var(--accent, #9bd34a)" />
        <circle cx="27" cy="13" r="6" fill="var(--accent, #9bd34a)" />
        <circle cx="13" cy="13" r="4" fill="#fff" />
        <circle cx="27" cy="13" r="4" fill="#fff" />
        <circle cx="13" cy="14" r="1.8" fill="#000" />
        <circle cx="27" cy="14" r="1.8" fill="#000" />
        <path d="M12 26 Q20 30 28 26" stroke="#1a3300" strokeWidth="1.4" fill="none" strokeLinecap="round" />
        <circle cx="9"  cy="25" r="1.2" fill="rgba(0,0,0,0.25)" />
        <circle cx="31" cy="25" r="1.2" fill="rgba(0,0,0,0.25)" />
      </svg>
    </div>
  );
}

/* ── FrogTrail — smudge stamps that appear and fade on mouse move ── */
function FrogTrail() {
  useEffect(() => {
    let lastStampTime = 0;
    let lastX = -999;
    let lastY = -999;

    /* colour options — rotate through a few greens */
    const colours = [
      "#8BAD6E",   /* fern green */
      "#5C7A4E",   /* moss green */
      "#9bd34a",   /* bright lime */
      "#7ab83a",   /* mid green  */
    ];

    const spawnFrog = (x, y) => {
      const el = document.createElement("div");

      /* randomise each stamp for a "smudged rubber-stamp" look */
      const rotation  = (Math.random() - 0.5) * 60;     /* –30 → +30 deg  */
      const scale     = 0.55 + Math.random() * 0.75;    /* 0.55 → 1.3     */
      const blurAmt   = 0.4 + Math.random() * 1.8;      /* 0.4 → 2.2 px   */
      const size      = 22 + Math.random() * 18;        /* 22 → 40 px     */
      const colour    = colours[Math.floor(Math.random() * colours.length)];
      const startOpac = 0.45 + Math.random() * 0.3;     /* 0.45 → 0.75    */

      /* slight random offset so stamps don't stack perfectly */
      const ox = (Math.random() - 0.5) * 14;
      const oy = (Math.random() - 0.5) * 14;

      el.style.cssText = `
        position: fixed;
        left:   ${x + ox}px;
        top:    ${y + oy}px;
        width:  ${size}px;
        height: ${size}px;
        color:  ${colour};
        transform: translate(-50%, -50%) rotate(${rotation}deg) scale(${scale});
        filter: blur(${blurAmt}px);
        pointer-events: none;
        z-index: 9990;
        opacity: ${startOpac};
        transition: opacity 1.8s ease-out, transform 1.8s ease-out;
        will-change: opacity, transform;
      `;

      el.innerHTML = FROG_SVG;
      document.body.appendChild(el);

      /* kick off fade + slight sink on next frame */
      requestAnimationFrame(() => {
        requestAnimationFrame(() => {
          el.style.opacity   = "0";
          el.style.transform = `translate(-50%, -50%) rotate(${rotation}deg) scale(${scale * 0.7})`;
        });
      });

      /* clean up after animation */
      setTimeout(() => {
        if (el.parentNode) el.parentNode.removeChild(el);
      }, 2000);
    };

    const onMove = (e) => {
      const now  = performance.now();
      const dx   = e.clientX - lastX;
      const dy   = e.clientY - lastY;
      const dist = Math.sqrt(dx * dx + dy * dy);

      /* throttle: spawn when enough time + distance have passed */
      if (now - lastStampTime > 120 && dist > 18) {
        spawnFrog(e.clientX, e.clientY);
        lastStampTime = now;
        lastX = e.clientX;
        lastY = e.clientY;
      }
    };

    window.addEventListener("mousemove", onMove);
    return () => window.removeEventListener("mousemove", onMove);
  }, []);

  return null; /* no DOM node needed */
}

window.FrogCursor = FrogCursor;
window.FrogTrail  = FrogTrail;
