/* TruckKun procedural logo — isolated for easier iteration.
   Loaded by index.astro as:
     <script type="text/babel" is:inline src="/assets/truckkun-logo.jsx"></script>
   Babel standalone transpiles this file and runs it in global scope.
   The Hero component is attached to window.Hero so the inline Page script
   can render <Hero /> without needing a bundler/import system. */

(function () {
  const { useEffect, useRef } = React;

  /* ---------- static geometry (viewBox 0 0 460 440) ----------
     Tuned to match apps/web/public/assets/truckkun-logo-front.png:
       - body is OCTAGONAL: widest at the middle, chamfered on all four corners
       - BOTTOM chamfers are 50w×44h (strongly tapered); TOP chamfers are 30w×24h (subtle)
       - top tab is ~22% of body width with small 6×4 chamfers on its top corners
       - face bezel ~200 wide × 130 tall, centered
       - cable exits from the bottom-right chamfer (angled surface)
     Everything is centered on body-center x=220. */
  const EYE_L = { cx: 180, cy: 197 };
  const EYE_R = { cx: 260, cy: 197 };
  const CABLE_START = { x: 330, y: 312 };   // lands on the bottom-right chamfer
  const CABLE_END   = { x: 420, y: 382 };

  const BODY_D =
    "M 85 134 L 115 110 H 190 V 94 L 196 90 H 244 L 250 94 V 110 H 325 L 355 134 " +
    "V 290 L 305 334 H 135 L 85 290 Z";

  function Hero() {
    const hostRef    = useRef(null);
    const shellRef   = useRef(null);
    const stripesRef = useRef(null);
    const faceRef    = useRef(null);
    const chinRef    = useRef(null);
    const tabRef     = useRef(null);
    const shadowRef  = useRef(null);
    const eyeLRef    = useRef(null);
    const eyeRRef    = useRef(null);
    const pupilLRef  = useRef(null);
    const pupilRRef  = useRef(null);
    const cableRef   = useRef(null);
    const telRef     = useRef(null);

    useEffect(() => {
      const host = hostRef.current;
      if (!host) return;

      const p = {
        bodyStiff: 0.055, bodyDamp: 0.84,
        faceStiff: 0.075, faceDamp: 0.82,
        tabStiff:  0.11,  tabDamp:  0.78,
        pupilStiff:0.09,  pupilDamp:0.80,
        parallaxBodyX: 12,  parallaxBodyY: 9,
        parallaxFaceX: 3.5, parallaxFaceY: 2.5,
        parallaxTabX:  2.0, parallaxTabY:  1.2,
        pupilRange: 7.5,
        headTiltDeg: 1.8,
      };

      const s = {
        tx: 0, ty: 0, nx: 0, ny: 0,
        bx: 0, by: 0, bvx: 0, bvy: 0,
        fx: 0, fy: 0, fvx: 0, fvy: 0,
        tbx: 0, tby: 0, tbvx: 0, tbvy: 0,
        ex: 0, ey: 0, evx: 0, evy: 0,
        saccadeX: 0, saccadeY: 0, saccadeTargetX: 0, saccadeTargetY: 0, nextSaccade: 0,
        blink: 1, blinkUntil: 0, nextBlink: 1800, doubleBlinkPending: false,
        t0: performance.now(), t: 0,
        awake: false, cursorInside: false,
        stillness: 0, lastTx: 0, lastTy: 0,
        clickBobUntil: 0, clickBobStart: 0,
        _telTick: -1,
      };

      const onMove = (e) => {
        const r = host.getBoundingClientRect();
        s.tx = e.clientX - (r.left + r.width / 2);
        s.ty = e.clientY - (r.top  + r.height / 2);
        s.nx = Math.max(-1, Math.min(1, s.tx / Math.max(1, r.width  * 0.5)));
        s.ny = Math.max(-1, Math.min(1, s.ty / Math.max(1, r.height * 0.5)));
        s.awake = true;
        s.cursorInside = e.clientX >= r.left && e.clientX <= r.right
                      && e.clientY >= r.top  && e.clientY <= r.bottom;
      };
      const onDown = () => {
        const tMs = performance.now() - s.t0;
        s.blinkUntil    = tMs + 220;
        s.clickBobUntil = tMs + 320;
        s.clickBobStart = tMs;
      };
      window.addEventListener("mousemove", onMove, { passive: true });
      host.addEventListener("mousedown", onDown);

      let raf;
      const applyTransform = (node, x, y, rotate = 0) => {
        if (!node) return;
        node.style.transform =
          `translate(${x.toFixed(2)}px, ${y.toFixed(2)}px) rotate(${rotate.toFixed(3)}deg)`;
      };
      // Scale an SVG group around a local pivot — needed because CSS
      // transform-box: fill-box isn't reliable across browsers for <g>.
      const applyEyeBlink = (node, cx, cy, sy) => {
        if (!node) return;
        node.setAttribute('transform',
          `translate(${cx} ${cy}) scale(1 ${sy.toFixed(3)}) translate(${-cx} ${-cy})`);
      };

      const tick = (now) => {
        const tMs = now - s.t0;
        s.t = tMs / 1000;
        const hostScale = (host.clientWidth || 440) / 440;

        /* body spring */
        const btx = s.nx * p.parallaxBodyX;
        const bty = s.ny * p.parallaxBodyY;
        s.bvx = (s.bvx + (btx - s.bx) * p.bodyStiff) * p.bodyDamp;
        s.bvy = (s.bvy + (bty - s.by) * p.bodyStiff) * p.bodyDamp;
        s.bx += s.bvx; s.by += s.bvy;

        /* face spring (slightly faster → floats inside the shell) */
        const ftx = s.nx * p.parallaxFaceX;
        const fty = s.ny * p.parallaxFaceY;
        s.fvx = (s.fvx + (ftx - s.fx) * p.faceStiff) * p.faceDamp;
        s.fvy = (s.fvy + (fty - s.fy) * p.faceStiff) * p.faceDamp;
        s.fx += s.fvx; s.fy += s.fvy;

        /* tab spring (snappiest, antenna-wobble feel) */
        const ttx = s.nx * p.parallaxTabX;
        const tty = s.ny * p.parallaxTabY;
        s.tbvx = (s.tbvx + (ttx - s.tbx) * p.tabStiff) * p.tabDamp;
        s.tbvy = (s.tbvy + (tty - s.tby) * p.tabStiff) * p.tabDamp;
        s.tbx += s.tbvx; s.tby += s.tbvy;

        const breath = Math.sin(s.t * 0.95) * 1.6;
        const idleSway = Math.sin(s.t * 0.55) * 0.35;
        let bob = 0;
        if (tMs < s.clickBobUntil) {
          bob = -Math.sin(((tMs - s.clickBobStart) / 320) * Math.PI) * 6.0;
        }
        const headTilt = s.bx * (p.headTiltDeg / p.parallaxBodyX) + idleSway;

        const bodyY = s.by + breath + bob;
        const bxPx = s.bx * hostScale;
        const byPx = bodyY * hostScale;

        applyTransform(shellRef.current,   bxPx, byPx, headTilt);
        applyTransform(stripesRef.current, bxPx, byPx, headTilt);
        applyTransform(faceRef.current,    (s.bx + s.fx) * hostScale, (bodyY + s.fy) * hostScale, headTilt * 1.1);
        applyTransform(chinRef.current,    bxPx * 0.94, byPx * 0.96 + Math.max(0, bob * 0.15) * hostScale, headTilt * 0.5);
        applyTransform(tabRef.current,     (s.bx + s.tbx) * hostScale, (bodyY + s.tby) * hostScale, headTilt + s.tbx * 0.25);
        if (shadowRef.current) {
          const sq = 1 - Math.max(0, -bob) * 0.018;
          shadowRef.current.style.transform =
            `translate(${(bxPx * 0.28).toFixed(2)}px, 0) scale(${sq.toFixed(3)}, ${(0.4 + sq * 0.6).toFixed(3)})`;
        }

        /* pupil spring + stillness relaxation */
        const dxm = s.tx - s.lastTx, dym = s.ty - s.lastTy;
        s.lastTx = s.tx; s.lastTy = s.ty;
        if (Math.hypot(dxm, dym) < 0.5) s.stillness = Math.min(1, s.stillness + 0.004);
        else                            s.stillness = Math.max(0, s.stillness - 0.06);

        const dist = Math.hypot(s.nx, s.ny);
        const deadZone = 0.04;
        const effDist = Math.max(0, dist - deadZone);
        const falloff = effDist / (effDist + 0.55);
        const attentionScale = (s.cursorInside || s.awake) ? 1 : 0.25;
        const relax = 1 - s.stillness * 0.78;
        const ptx = (dist > 0 ? s.nx / dist : 0) * falloff * p.pupilRange * attentionScale * relax;
        const pty = (dist > 0 ? s.ny / dist : 0) * falloff * p.pupilRange * attentionScale * relax;

        s.evx = (s.evx + (ptx - s.ex) * p.pupilStiff) * p.pupilDamp;
        s.evy = (s.evy + (pty - s.ey) * p.pupilStiff) * p.pupilDamp;
        s.ex += s.evx; s.ey += s.evy;

        /* micro-saccades */
        if (tMs > s.nextSaccade) {
          s.saccadeTargetX = (Math.random() - 0.5) * 1.6;
          s.saccadeTargetY = (Math.random() - 0.5) * 1.1;
          s.nextSaccade = tMs + 700 + Math.random() * 1500;
        }
        s.saccadeX += (s.saccadeTargetX - s.saccadeX) * 0.08;
        s.saccadeY += (s.saccadeTargetY - s.saccadeY) * 0.08;

        const totalPX = s.ex + s.saccadeX;
        const totalPY = s.ey + s.saccadeY;

        /* blink — periodic with ~22% chance of a double-blink */
        let blink = 1;
        if (tMs > s.nextBlink) {
          s.blinkUntil = tMs + 220;
          s.doubleBlinkPending = Math.random() < 0.22;
          s.nextBlink  = tMs + 2800 + Math.random() * 2800;
        }
        if (s.blinkUntil && tMs < s.blinkUntil) {
          const prog = 1 - (s.blinkUntil - tMs) / 220;
          const eased = prog < 0.5
            ? 2 * prog * prog
            : 1 - Math.pow(-2 * prog + 2, 2) / 2;
          blink = eased < 0.5 ? 1 - eased * 2 : (eased - 0.5) * 2;
        } else if (s.doubleBlinkPending && tMs >= s.blinkUntil + 140) {
          s.blinkUntil = tMs + 200;
          s.doubleBlinkPending = false;
        }
        const eyeScaleY = Math.max(0.06, blink);
        s.blink = blink;

        applyTransform(pupilLRef.current, totalPX, totalPY + (1 - blink) * 1.2);
        applyTransform(pupilRRef.current, totalPX, totalPY + (1 - blink) * 1.2);
        applyEyeBlink(eyeLRef.current, EYE_L.cx, EYE_L.cy, eyeScaleY);
        applyEyeBlink(eyeRRef.current, EYE_R.cx, EYE_R.cy, eyeScaleY);

        /* dynamic cable — start follows body, connector end is fixed.
           The cable group has no body transform applied, so we move the
           start point manually to stay glued to the exit. */
        if (cableRef.current) {
          const sx = CABLE_START.x + s.bx;
          const sy = CABLE_START.y + bodyY;
          const ex = CABLE_END.x, ey = CABLE_END.y;
          const c1x = sx + (ex - sx) * 0.35;
          const c1y = sy + 18;
          const c2x = ex - (ex - sx) * 0.25;
          const c2y = ey - 22;
          cableRef.current.setAttribute('d',
            `M${sx.toFixed(1)} ${sy.toFixed(1)} C${c1x.toFixed(1)} ${c1y.toFixed(1)}, ${c2x.toFixed(1)} ${c2y.toFixed(1)}, ${ex} ${ey}`
          );
        }

        /* telemetry (throttled to ~8fps) */
        const tick120 = Math.floor(tMs / 120);
        if (telRef.current && tick120 !== s._telTick) {
          s._telTick = tick120;
          const [tTime, tX, tY, tStatus] = telRef.current.children;
          if (tTime)   tTime.textContent   = `T+${s.t.toFixed(2).padStart(6, "0")}`;
          if (tX)      tX.textContent      = `X ${(s.tx|0).toString().padStart(4, " ")}`;
          if (tY)      tY.textContent      = `Y ${(s.ty|0).toString().padStart(4, " ")}`;
          if (tStatus) tStatus.textContent = s.cursorInside ? "FOCUS" : (s.awake ? "TRACK" : "IDLE");
        }

        raf = requestAnimationFrame(tick);
      };
      raf = requestAnimationFrame(tick);

      return () => {
        cancelAnimationFrame(raf);
        window.removeEventListener("mousemove", onMove);
        host.removeEventListener("mousedown", onDown);
      };
    }, []);

    return (
      <div ref={hostRef} className="kun" style={{ cursor: "pointer" }}>
        {/* subtle static ring behind the logo */}
        <svg viewBox="-200 -200 400 400" aria-hidden="true" style={{ pointerEvents: "none" }}>
          <circle r="185" fill="none" stroke="var(--line)" strokeWidth="1" strokeDasharray="1 5" opacity="0.55" />
          {[[0,-185],[185,0],[0,185],[-185,0]].map(([x, y], i) => (
            <circle key={i} cx={x} cy={y} r="2" fill="var(--ink-3)" opacity="0.5" />
          ))}
        </svg>

        <svg
          className="logo-svg"
          viewBox="0 0 460 440"
          role="img"
          aria-label="TruckKun"
          style={{ pointerEvents: "none" }}
        >
          <defs>
            <clipPath id="tk-eye-l-clip"><circle cx={EYE_L.cx} cy={EYE_L.cy} r="18" /></clipPath>
            <clipPath id="tk-eye-r-clip"><circle cx={EYE_R.cx} cy={EYE_R.cy} r="18" /></clipPath>
            <clipPath id="tk-body-clip"><path d={BODY_D} /></clipPath>
            <linearGradient id="tk-body-fill" x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%"  stopColor="#10385a" />
              <stop offset="100%" stopColor="#082a48" />
            </linearGradient>
            <linearGradient id="tk-face-fill" x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%"  stopColor="#0e395d" />
              <stop offset="100%" stopColor="#0a2f51" />
            </linearGradient>
            <linearGradient id="tk-olive-fill" x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%"  stopColor="#68783f" />
              <stop offset="100%" stopColor="#516332" />
            </linearGradient>
          </defs>

          {/* ground shadow */}
          <g ref={shadowRef} className="logo-piece">
            <ellipse cx="220" cy="354" rx="110" ry="9" fill="rgba(27,42,68,0.13)" />
          </g>

          {/* cable — drawn first so it appears to exit from behind the body */}
          <g className="logo-piece" opacity="0.92">
            <path
              ref={cableRef}
              d="M330 312 C362 332, 396 362, 420 382"
              fill="none"
              stroke="#1b2a44"
              strokeWidth="2.6"
              strokeLinecap="round"
              strokeOpacity="0.78"
            />
            <rect x="410" y="372" width="20" height="20" rx="2.5" fill="#1b2a44" />
            <rect x="414" y="376" width="12" height="12" rx="1" fill="none" stroke="rgba(242,235,217,0.45)" strokeWidth="1" />
            <text x="420" y="410" textAnchor="middle"
                  fill="#8891a1"
                  style={{ font: '8px "JetBrains Mono", monospace', letterSpacing: '0.12em' }}>
              HOST
            </text>
          </g>

          {/* top tab — wider base (60w × 20h above body) with small 6×4 chamfers */}
          <g ref={tabRef} className="logo-piece">
            <path d="M 190 110 V 94 L 196 90 H 244 L 250 94 V 110 Z" fill="url(#tk-body-fill)" />
            <line x1="208" y1="94" x2="232" y2="94" stroke="rgba(255,255,255,0.14)" strokeWidth="1.2" strokeLinecap="round" />
          </g>

          {/* body shell */}
          <g ref={shellRef} className="logo-piece">
            <path d={BODY_D} fill="url(#tk-body-fill)" />
            {/* tiny top-edge highlight on either side of the tab */}
            <path
              d="M 115 110 H 190 M 250 110 H 325"
              fill="none"
              stroke="rgba(255,255,255,0.08)"
              strokeWidth="1.2"
              strokeLinecap="round"
            />
          </g>

          {/* side stripes — LEFT slopes \, RIGHT slopes / (chevrons pointing inward-down,
              matching the PNG reference). Clipped to the body so they sit flush with the edge. */}
          <g ref={stripesRef} className="logo-piece" clipPath="url(#tk-body-clip)">
            {/* left ear: \  (outer-upper → inner-lower) */}
            <path d="M 80 178 L 130 214 L 130 228 L 80 192 Z" fill="url(#tk-olive-fill)" />
            <path d="M 80 206 L 130 242 L 130 256 L 80 220 Z" fill="url(#tk-olive-fill)" />
            {/* right ear: /  (outer-upper → inner-lower), mirrored */}
            <path d="M 360 178 L 310 214 L 310 228 L 360 192 Z" fill="url(#tk-olive-fill)" />
            <path d="M 360 206 L 310 242 L 310 256 L 360 220 Z" fill="url(#tk-olive-fill)" />
          </g>

          {/* face — cream bezel rim + inner navy screen + eyes.
              Outer bezel 200×130 centered on (220, 197), ~14 px rim thickness. */}
          <g ref={faceRef} className="logo-piece">
            <path
              d="M 120 146 L 134 132 H 306 L 320 146 V 248 L 306 262 H 134 L 120 248 Z
                 M 134 158 L 146 146 H 294 L 306 158 V 236 L 294 248 H 146 L 134 236 Z"
              fill="#f7f2e6"
              fillRule="evenodd"
            />
            <path
              d="M 134 158 L 146 146 H 294 L 306 158 V 236 L 294 248 H 146 L 134 236 Z"
              fill="url(#tk-face-fill)"
            />
            <path d="M 146 146 H 294 L 306 158" fill="none" stroke="rgba(255,255,255,0.08)" strokeWidth="1.2" />
            <path d="M 142 242 H 298" fill="none" stroke="rgba(0,0,0,0.14)" strokeWidth="1.3" strokeLinecap="round" />

            {/* left eye */}
            <g ref={eyeLRef}>
              <circle cx={EYE_L.cx} cy={EYE_L.cy} r="18" fill="#f7f2e6" />
              <g ref={pupilLRef} clipPath="url(#tk-eye-l-clip)" style={{ willChange: "transform" }}>
                <circle cx={EYE_L.cx} cy={EYE_L.cy} r="9.8" fill="#08243f" />
                {/* large offset highlight produces the PNG's moon-shape reflection */}
                <circle cx={EYE_L.cx + 3.6} cy={EYE_L.cy - 3.2} r="4.6" fill="#f7f2e6" />
              </g>
            </g>

            {/* right eye */}
            <g ref={eyeRRef}>
              <circle cx={EYE_R.cx} cy={EYE_R.cy} r="18" fill="#f7f2e6" />
              <g ref={pupilRRef} clipPath="url(#tk-eye-r-clip)" style={{ willChange: "transform" }}>
                <circle cx={EYE_R.cx} cy={EYE_R.cy} r="9.8" fill="#08243f" />
                <circle cx={EYE_R.cx + 3.6} cy={EYE_R.cy - 3.2} r="4.6" fill="#f7f2e6" />
              </g>
            </g>
          </g>

          {/* chin — regular trapezoid (/--\ shape), narrower at top and flaring out
              toward the body floor. Gap between face bezel bottom (y=262) and chin
              top (y=292) = 30px of navy body showing through. */}
          <g ref={chinRef} className="logo-piece">
            <path d="M 188 292 H 252 L 272 330 H 168 Z" fill="url(#tk-olive-fill)" />
          </g>
        </svg>

        <div ref={telRef} className="telemetry" aria-hidden="true">
          <span className="tl">T+000.00</span>
          <span className="tr">X    0</span>
          <span className="bl">Y    0</span>
          <span className="br">IDLE</span>
        </div>
      </div>
    );
  }

  window.Hero = Hero;
})();
