// ============================================================
// autoclient.io — Penrose (impossible) triangle hero mark
// Pure CSS 3D. Three parallelogram beams with 60° mitred ends
// form an impossible tribar: each beam passes OVER one
// neighbour and UNDER the other (a true 3-cycle). Faces carry
// the brand hues — purple top, pink front, coral end-cap —
// with dark inner seams for depth, on a soft purple-pink glow.
// ============================================================

/*
  Built as ONE "bottom" beam, cloned into three spokes rotated
  0° / 120° / 240° about the centre of a 360×360 box. Rotating
  identical beams forces a symmetric paint order (one beam ends
  up on top of both = an ordinary frame), so the bottom beam's
  end-cap is re-painted last to flip the z-order at that one
  corner and complete the impossible cycle.
*/

// --- beam parameters (the bottom beam, before rotation) ---
const H = 46;                 // front-face thickness
const E = Math.round(H / Math.tan(Math.PI / 3)); // 60° miter shear ≈ 27
const L = 274;                // bottom-edge length (overshoots corners slightly)
const X1 = 46, YB = 302;      // bottom-left anchor
const DX = 27, DY = 27;       // isometric depth offset (up-right) for the top face

// front-face parallelogram corners (slanted 60° ends)
const BL = [X1, YB];
const BR = [X1 + L, YB];
const TR = [X1 + L + E, YB - H];
const TL = [X1 + E, YB - H];
const off = ([x, y]) => [x + DX, y - DY];   // recede up-right

const poly = (...pts) => `polygon(${pts.map(([x, y]) => `${x}px ${y}px`).join(", ")})`;

// structural BODY = top face + front face + their seam line
const BODY = [
  { key: "top", bg: "linear-gradient(116deg, #C4C2FF 0%, #8784FD 56%, #615ED6 100%)",
    clip: poly(TL, TR, off(TR), off(TL)) },
  { key: "front", bg: "linear-gradient(178deg, #FFB2D7 0%, #FF99CC 42%, #DC619C 100%)",
    clip: poly(BL, BR, TR, TL) },
  { key: "seam-tf", bg: "rgba(38,20,44,0.34)",
    clip: poly(TL, TR, [TR[0] - 1.5, TR[1] + 2.5], [TL[0] - 1.5, TL[1] + 2.5]) },
];

// CAP = coral end-cap (the slanted right end, extruded) + its seam.
// Re-paintable on top to complete the impossible 3-cycle.
const CAP = [
  { key: "cap", bg: "linear-gradient(150deg, #FF8A8A 0%, #FF6666 52%, #CD4949 100%)",
    clip: poly(BR, TR, off(TR), off(BR)) },
  { key: "seam-fc", bg: "rgba(38,20,44,0.32)",
    clip: poly(BR, TR, [TR[0] - 2, TR[1]], [BR[0] - 2, BR[1]]) },
];

function Face({ f }) {
  return <div className="pz-face" style={{ clipPath: f.clip, WebkitClipPath: f.clip, background: f.bg }} />;
}
function Beam({ rot, body = true, cap = true }) {
  return (
    <div className="pz-spoke" style={{ transform: `rotate(${rot}deg)` }}>
      {body && BODY.map((f) => <Face key={f.key} f={f} />)}
      {cap && CAP.map((f) => <Face key={f.key} f={f} />)}
    </div>
  );
}

function PenroseTriangle({ size = 340 }) {
  return (
    <div className="pz-stage" style={{ width: size, height: size }} aria-hidden="true">
      <div className="pz-glow" />
      <div className="pz-tri">
        <Beam rot={0} />
        <Beam rot={120} />
        <Beam rot={240} />
        {/* flip z at the bottom beam's corner → true impossible cycle */}
        <Beam rot={0} body={false} cap={true} />
      </div>
    </div>
  );
}

// ============================================================
// LOGO 3D — the REAL autoclient symbol, extruded into a solid.
// We stack N copies of the official mark along Z; the front
// copy is the bright gradient face, deeper copies darken to
// read as extruded side walls. Because it's a genuine solid
// (not the projection-locked Penrose illusion) it can rotate
// freely in 3D and stay correct from any angle.
// ============================================================
const LOGO_SRC = "assets/autoclient-symbol-sm.png";
const LOGO_LAYERS = 12;          // extrusion slices (kept low for smooth compositing)
const LOGO_STEP = 2.6;           // px between slices (× scale) — 12 × 2.6 keeps depth

function Logo3D({ width = 460 }) {
  const N = LOGO_LAYERS;
  const slices = [];
  for (let i = 0; i < N; i++) {
    const t = i / (N - 1);                 // 0 = back, 1 = front
    const z = (i - (N - 1) / 2) * LOGO_STEP;
    const isFace = i === N - 1;
    // deeper slices read darker; only the lit front face gets a filter
    const bright = (0.52 + t * 0.48).toFixed(3);
    slices.push(
      <img key={i} src={LOGO_SRC} alt="" aria-hidden="true" className="logo3d-slice" draggable="false" width="760" height="666"
        style={{
          transform: `translate(-50%,-50%) translateZ(${z}px)`,
          filter: isFace ? "none" : `brightness(${bright})`,
          zIndex: i,
        }} />
    );
  }
  return (
    <div className="logo3d" style={{ width }} aria-hidden="true">
      <div className="logo3d-tilt">
        <div className="logo3d-spin">
          {slices}
        </div>
      </div>
    </div>
  );
}

// ============================================================
// HERO SCENE — immersive 3D environment behind the mark.
// Perspective grid floor + layered depth particles + halo,
// each layer parallaxing off the --px/--py vars the hero sets
// on pointer move. The Penrose mark itself never rotates in
// true 3D (its illusion is projection-locked) — depth comes
// from the environment and parallax translation.
// ============================================================
const HERO_HUES = ["#8784FD", "#FF99CC", "#FF6666", "#CC99FF"];
const HERO_DOTS = Array.from({ length: 16 }).map((_, i) => {
  const far = Math.random();
  return {
    left: (Math.random() * 100).toFixed(2),
    top: (Math.random() * 94).toFixed(2),
    size: +(3 + Math.random() * 6).toFixed(1),
    color: HERO_HUES[i % HERO_HUES.length],
    blur: far > 0.62 ? +(1.5 + Math.random() * 3).toFixed(1) : 0,
    opacity: +(0.22 + (1 - far) * 0.5).toFixed(2),
    dd: (7 + Math.random() * 7).toFixed(1),
    dl: (-Math.random() * 9).toFixed(1),
    near: far < 0.5,
  };
});
const heroPar = (n) => ({ transform: `translate3d(calc(var(--px,0) * ${n}px), calc(var(--py,0) * ${n}px), 0)` });

function HeroDots({ near }) {
  return HERO_DOTS.filter((d) => d.near === near).map((d, i) => (
    <span key={i} className="hero-dot" style={{
      left: d.left + "%", top: d.top + "%", width: d.size, height: d.size,
      background: d.color, opacity: d.opacity,
      filter: d.blur ? `blur(${d.blur}px)` : "none",
      boxShadow: `0 0 ${d.size * 2.2}px ${d.color}`,
      "--dd": d.dd + "s", "--dl": d.dl + "s",
    }} />
  ));
}

function HeroScene() {
  return (
    <div className="hero-scene" aria-hidden="true">
      <div className="hero-layer">
        <div className="hero-grid" />
        <HeroDots near={false} />
      </div>
      <div className="hero-layer">
        <div className="hero-back-glow" />
        <div className="hero-tri-center"><Logo3D width={540} /></div>
      </div>
      <div className="hero-layer">
        <HeroDots near={true} />
      </div>
    </div>
  );
}

function SplineHeroScene() {
  const wrapRef = React.useRef(null);
  React.useEffect(() => {
    const wrap = wrapRef.current;
    if (!wrap) return;
    // The Spline canvas swallows wheel events (scene zoom). Intercept them in
    // the capture phase and hand them back to the page so scrolling works,
    // while pointer-move interaction with the scene stays live.
    // Spline's canvas has a wheel listener that preventDefault()s to zoom the
    // scene. Stop the event from ever reaching it (capture phase) WITHOUT
    // preventing the default — the browser then scrolls the page natively,
    // with real wheel physics. No re-dispatching, no custom animation.
    const onWheel = (e) => {
      e.stopPropagation();
    };
    wrap.addEventListener("wheel", onWheel, { capture: true });
    return () => wrap.removeEventListener("wheel", onWheel, { capture: true });
  }, []);
  return (
    <div ref={wrapRef} className="hero-scene hero-scene-spline" aria-hidden="true">
      <spline-viewer
        url="https://prod.spline.design/0C6BMXpGnlY3Xqw0/scene.splinecode"
        style={{ width: "100%", height: "100%", display: "block" }}
      ></spline-viewer>
    </div>
  );
}

Object.assign(window, { PenroseTriangle, Logo3D, HeroScene, SplineHeroScene });
