// Collector Vault — scene components
// World: 1080 x 1920 (portrait). Floor line at y=1500. Showcase centered x=540.

const V = {
  W: 1080, H: 1920,
  FLOOR: 1500,
  CARD_W: 320, CARD_H: 541,
  CARD_X: 540,
  CARD_Y0: 950,   // resting center inside case
  CARD_Y1: 760,   // floated center
  GOLD: '#d9a94e',
  GOLD_SOFT: 'rgba(217,169,78,',
};

// deterministic pseudo-random per index
function vrand(i, salt) {
  const x = Math.sin(i * 127.1 + salt * 311.7) * 43758.5453;
  return x - Math.floor(x);
}

// idle clock: accumulates wall-time once playhead passes `threshold`
function useIdleClock(threshold) {
  const { time } = useTimeline();
  const [idle, setIdle] = React.useState(0);
  const activeRef = React.useRef(false);
  activeRef.current = time >= threshold;
  const wasActive = React.useRef(false);
  React.useEffect(() => {
    let raf, last = null;
    const step = (ts) => {
      if (last != null && activeRef.current) {
        setIdle((i) => i + (ts - last) / 1000);
      }
      if (!activeRef.current) setIdle(0);
      last = ts;
      raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, []);
  return time >= threshold ? idle : 0;
}

// ── card rotation profile ───────────────────────────────────────────────────
// 0-6s: tiny presentation drift. 6-10s: velocity ramps 0 -> 42 deg/s. Idle continues at 42.
function cardRotation(t, idle) {
  const drift = 6 * Math.sin(t * 0.5) - 4; // subtle life early on
  if (t < 6) return drift;
  const blend = Math.min(1, (t - 6) / 0.8);
  const base = drift * (1 - blend);
  // integral of velocity ramp: v(u) = 42 * easeInOutSine(u/1.5) for u in [0,1.5], then 42
  const u = t - 6;
  let deg;
  if (u < 1.5) {
    // integral of 42 * (1-cos(pi*u/1.5))/2 du = 21u - 21*(1.5/pi)*sin(pi*u/1.5)
    deg = 21 * u - 21 * (1.5 / Math.PI) * Math.sin((Math.PI * u) / 1.5);
  } else {
    deg = 21 * 1.5 + 42 * (u - 1.5);
  }
  return base + deg + 42 * idle;
}

// ── volumetric beams ────────────────────────────────────────────────────────
function Beams({ time }) {
  const boost = animate({ from: 0, to: 1, start: 7.5, end: 9.5, ease: Easing.easeInOutSine })(time);
  const reveal = animate({ from: 0, to: 1, start: 3.2, end: 5.5, ease: Easing.easeInOutSine })(time);
  const flicker = 0.92 + 0.08 * Math.sin(time * 1.3);
  const o = reveal * (0.5 + 0.5 * boost) * flicker;
  const beam = (x, w, ang, op, blur) => (
    <div style={{
      position: 'absolute', left: x, top: -200, width: w, height: 1750,
      background: `linear-gradient(to bottom, ${V.GOLD_SOFT}${op}) 0%, ${V.GOLD_SOFT}${op * 0.45}) 45%, rgba(217,169,78,0) 88%)`,
      transform: `rotate(${ang}deg)`,
      transformOrigin: '50% 0%',
      filter: `blur(${blur}px)`,
      opacity: o,
    }}></div>
  );
  return (
    <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>
      {beam(180, 130, 14, 0.16, 26)}
      {beam(500, 170, 0, 0.20, 30)}
      {beam(790, 120, -13, 0.15, 26)}
      {/* hot core over the showcase */}
      <div style={{
        position: 'absolute', left: 540 - 240, top: 0, width: 480, height: 1100,
        background: `radial-gradient(ellipse 50% 70% at 50% 0%, ${V.GOLD_SOFT}${0.22 * o}) 0%, rgba(217,169,78,0) 70%)`,
        filter: 'blur(18px)',
      }}></div>
    </div>
  );
}

// ── back wall: niches with glowing displays + bokeh ─────────────────────────
function BokehWall({ time, parallax }) {
  const reveal = animate({ from: 0, to: 1, start: 3.0, end: 5.2, ease: Easing.easeInOutSine })(time);
  const items = [];
  // glowing display niches (soft card-shaped glows, heavily blurred = bokeh)
  const niches = [
    { x: 130, y: 560, s: 0.85, hue: 'rgba(228,184,98,' },
    { x: 880, y: 540, s: 0.9, hue: 'rgba(214,160,84,' },
    { x: 60, y: 1010, s: 0.7, hue: 'rgba(190,150,200,' },
    { x: 960, y: 1030, s: 0.72, hue: 'rgba(228,184,98,' },
  ];
  niches.forEach((n, i) => {
    const tw = 0.8 + 0.2 * Math.sin(time * 0.9 + i * 2.1);
    items.push(
      <div key={'n' + i} style={{
        position: 'absolute', left: n.x - 70 * n.s, top: n.y - 110 * n.s,
        width: 140 * n.s, height: 220 * n.s,
        borderRadius: 14,
        background: `linear-gradient(170deg, ${n.hue}${0.5 * tw}) 0%, ${n.hue}${0.18 * tw}) 100%)`,
        boxShadow: `0 0 90px 36px ${n.hue}${0.22 * tw})`,
        filter: 'blur(13px)',
        opacity: reveal,
      }}></div>
    );
  });
  // round bokeh dots
  for (let i = 0; i < 9; i++) {
    const bx = vrand(i, 1) * 1080;
    const by = 320 + vrand(i, 2) * 900;
    const r = 14 + vrand(i, 3) * 34;
    const tw = 0.5 + 0.5 * Math.sin(time * (0.6 + vrand(i, 4) * 0.8) + i * 1.7);
    items.push(
      <div key={'b' + i} style={{
        position: 'absolute', left: bx - r, top: by - r, width: r * 2, height: r * 2,
        borderRadius: '50%',
        background: `radial-gradient(circle, ${V.GOLD_SOFT}${0.30 * tw}) 0%, rgba(217,169,78,0) 70%)`,
        filter: 'blur(7px)',
        opacity: reveal,
      }}></div>
    );
  }
  return (
    <div style={{ position: 'absolute', inset: 0, transform: `translateX(${parallax}px)` }}>
      {/* wall base */}
      <div style={{
        position: 'absolute', left: -80, top: 0, width: V.W + 160, height: V.FLOOR + 6,
        background: 'linear-gradient(to bottom, #07060a 0%, #0e0b10 42%, #181219 78%, #221a20 100%)',
      }}></div>
      {/* faint wall paneling */}
      <div style={{
        position: 'absolute', left: -80, top: 230, width: V.W + 160, height: 1100,
        background: 'repeating-linear-gradient(90deg, rgba(255,235,200,0.025) 0 2px, rgba(0,0,0,0) 2px 270px)',
        opacity: reveal,
      }}></div>
      {items}
    </div>
  );
}

// ── black marble floor with gold veins + reflections ────────────────────────
function MarbleFloor({ time, cardScreenY, cardRot, floatGlow }) {
  const reveal = animate({ from: 0, to: 1, start: 3.0, end: 5.4, ease: Easing.easeInOutSine })(time);
  return (
    <div style={{ position: 'absolute', left: 0, top: V.FLOOR, width: V.W, height: V.H - V.FLOOR }}>
      {/* marble base */}
      <div style={{
        position: 'absolute', inset: 0,
        background: 'linear-gradient(to bottom, #1c161c 0%, #120d12 30%, #0a070b 100%)',
      }}></div>
      {/* gold veins — thin angled streaks */}
      <div style={{
        position: 'absolute', inset: 0,
        background: [
          'linear-gradient(104deg, rgba(0,0,0,0) 31.5%, rgba(217,169,78,0.20) 32%, rgba(0,0,0,0) 32.6%)',
          'linear-gradient(83deg, rgba(0,0,0,0) 57.5%, rgba(217,169,78,0.13) 58%, rgba(0,0,0,0) 58.7%)',
          'linear-gradient(99deg, rgba(0,0,0,0) 76.5%, rgba(228,190,110,0.16) 77%, rgba(0,0,0,0) 77.8%)',
          'linear-gradient(70deg, rgba(0,0,0,0) 12.5%, rgba(217,169,78,0.10) 13%, rgba(0,0,0,0) 13.9%)',
        ].join(', '),
        filter: 'blur(1.5px)',
        opacity: 0.4 + 0.6 * reveal,
      }}></div>
      {/* polished sheen */}
      <div style={{
        position: 'absolute', inset: 0,
        background: 'radial-gradient(ellipse 60% 90% at 50% 0%, rgba(255,236,200,0.10) 0%, rgba(0,0,0,0) 62%)',
      }}></div>
      {/* spotlight pool under pedestal */}
      <div style={{
        position: 'absolute', left: 540 - 330, top: 30, width: 660, height: 260,
        background: `radial-gradient(ellipse 50% 50% at 50% 50%, ${V.GOLD_SOFT}${0.20 + 0.16 * floatGlow}) 0%, rgba(217,169,78,0) 70%)`,
        filter: 'blur(14px)',
      }}></div>
      {/* card reflection (stylized) */}
      <div style={{
        position: 'absolute', left: 540 - V.CARD_W / 2, top: 60, width: V.CARD_W, height: 360,
        perspective: 1400, opacity: 0.16 * reveal + 0.10 * floatGlow,
        WebkitMaskImage: 'linear-gradient(to bottom, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0) 85%)',
        maskImage: 'linear-gradient(to bottom, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0) 85%)',
        filter: 'blur(9px) brightness(0.85)',
      }}>
        <img src="assets/card-cut.png" alt="" style={{
          width: '100%', display: 'block',
          transform: `scaleY(-1) rotateY(${cardRot}deg)`,
          transformOrigin: '50% 0%',
        }} />
      </div>
    </div>
  );
}

// ── pedestal ────────────────────────────────────────────────────────────────
function Pedestal() {
  return (
    <div style={{ position: 'absolute', left: 540 - 190, top: V.FLOOR - 260, width: 380, height: 260 }}>
      {/* top slab */}
      <div style={{
        position: 'absolute', left: -22, top: 0, width: 424, height: 26, borderRadius: 4,
        background: 'linear-gradient(to bottom, #3a3038 0%, #17121a 100%)',
        boxShadow: '0 6px 18px rgba(0,0,0,0.7)',
      }}></div>
      {/* gold trim */}
      <div style={{
        position: 'absolute', left: -22, top: 25, width: 424, height: 5,
        background: `linear-gradient(90deg, rgba(217,169,78,0.15) 0%, ${V.GOLD} 50%, rgba(217,169,78,0.15) 100%)`,
      }}></div>
      {/* column */}
      <div style={{
        position: 'absolute', left: 0, top: 30, width: 380, height: 230,
        background: 'linear-gradient(90deg, #08060a 0%, #241c26 26%, #322834 50%, #241c26 74%, #08060a 100%)',
      }}></div>
      {/* column veins */}
      <div style={{
        position: 'absolute', left: 0, top: 30, width: 380, height: 230,
        background: 'linear-gradient(108deg, rgba(0,0,0,0) 43.5%, rgba(217,169,78,0.14) 44%, rgba(0,0,0,0) 44.8%)',
        filter: 'blur(1px)',
      }}></div>
    </div>
  );
}

// ── crystal showcase (open vitrine; glass fades as card floats) ─────────────
function GlassCase({ openP }) {
  const gx = 540 - 220, gy = V.FLOOR - 260 - 700, gw = 440, gh = 700;
  const op = 1 - 0.85 * openP;
  return (
    <div style={{ position: 'absolute', left: gx, top: gy, width: gw, height: gh, opacity: op }}>
      {/* glass body */}
      <div style={{
        position: 'absolute', inset: 0,
        background: 'linear-gradient(115deg, rgba(255,255,255,0.10) 0%, rgba(255,255,255,0.015) 28%, rgba(255,255,255,0.05) 47%, rgba(255,255,255,0.01) 62%, rgba(255,255,255,0.09) 100%)',
        border: '1px solid rgba(255,255,255,0.22)',
        borderRadius: 6,
        boxShadow: 'inset 0 0 60px rgba(255,255,255,0.05), 0 30px 70px rgba(0,0,0,0.55)',
      }}></div>
      {/* vertical specular streaks */}
      <div style={{
        position: 'absolute', left: '12%', top: 8, width: 3, height: gh - 16,
        background: 'linear-gradient(to bottom, rgba(255,255,255,0.45) 0%, rgba(255,255,255,0.04) 60%, rgba(255,255,255,0.22) 100%)',
        filter: 'blur(1px)',
      }}></div>
      <div style={{
        position: 'absolute', right: '16%', top: 8, width: 2, height: gh - 16,
        background: 'linear-gradient(to bottom, rgba(255,255,255,0.30) 0%, rgba(255,255,255,0.02) 70%)',
        filter: 'blur(1px)',
      }}></div>
      {/* gold frame edges */}
      <div style={{ position: 'absolute', left: -3, top: -4, width: gw + 6, height: 7, background: `linear-gradient(90deg, #6d5526 0%, ${V.GOLD} 30%, #f3dca0 50%, ${V.GOLD} 70%, #6d5526 100%)`, borderRadius: 3 }}></div>
      <div style={{ position: 'absolute', left: -3, bottom: -2, width: gw + 6, height: 8, background: `linear-gradient(90deg, #59431d 0%, ${V.GOLD} 50%, #59431d 100%)`, borderRadius: 3 }}></div>
      <div style={{ position: 'absolute', left: -3, top: 0, width: 4, height: gh, background: 'linear-gradient(to bottom, #8a6c30, rgba(138,108,48,0.25))' }}></div>
      <div style={{ position: 'absolute', right: -3, top: 0, width: 4, height: gh, background: 'linear-gradient(to bottom, #8a6c30, rgba(138,108,48,0.25))' }}></div>
    </div>
  );
}

// ── golden dust ─────────────────────────────────────────────────────────────
function GoldDust({ time, count, intensity }) {
  const dots = [];
  for (let i = 0; i < count; i++) {
    const speed = 14 + vrand(i, 5) * 26;
    const x0 = vrand(i, 6) * V.W;
    const y0 = vrand(i, 7) * V.H;
    const sway = 16 + vrand(i, 8) * 28;
    const r = 1.4 + vrand(i, 9) * 3.4;
    const depthBlur = vrand(i, 10) < 0.3 ? 2.5 : 0.5;
    const y = ((y0 - time * speed) % (V.H + 80) + (V.H + 80)) % (V.H + 80) - 40;
    const x = x0 + Math.sin(time * 0.7 + i * 2.3) * sway;
    const tw = 0.35 + 0.65 * Math.pow(0.5 + 0.5 * Math.sin(time * (1.1 + vrand(i, 11)) + i * 1.9), 2);
    dots.push(
      <div key={i} style={{
        position: 'absolute', left: x - r, top: y - r, width: r * 2, height: r * 2,
        borderRadius: '50%',
        background: `radial-gradient(circle, rgba(255,228,160,${0.9 * tw * intensity}) 0%, ${V.GOLD_SOFT}${0.5 * tw * intensity}) 45%, rgba(217,169,78,0) 70%)`,
        filter: `blur(${depthBlur}px)`,
      }}></div>
    );
  }
  return <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>{dots}</div>;
}

// ── holographic energy around floating card ─────────────────────────────────
function HoloAura({ time, strength }) {
  if (strength <= 0.01) return null;
  const hue = (time * 40) % 360;
  const pulse = 0.85 + 0.15 * Math.sin(time * 2.2);
  return (
    <div style={{
      position: 'absolute', left: '50%', top: '50%',
      width: V.CARD_W + 220, height: V.CARD_H + 220,
      transform: 'translate(-50%, -50%)',
      borderRadius: '50%',
      background: `radial-gradient(ellipse 50% 50% at 50% 50%, hsla(${hue}, 70%, 75%, ${0.16 * strength * pulse}) 0%, hsla(${(hue + 80) % 360}, 70%, 70%, ${0.07 * strength * pulse}) 45%, rgba(0,0,0,0) 70%)`,
      filter: 'blur(16px)',
      pointerEvents: 'none',
    }}></div>
  );
}

// ── 3D slab ─────────────────────────────────────────────────────────────────
// Single flat element rotated in 3D; front/back content swapped manually at
// the 90° crossings. No preserve-3d / backface-visibility (unreliable across
// renderers).
function Slab3D({ rot, shineT, glowStrength, src = 'assets/card-cut.png', height = V.CARD_H }) {
  const w = V.CARD_W, h = height;
  const rad = (rot * Math.PI) / 180;
  const facing = Math.cos(rad) >= 0;
  const edgeOn = Math.pow(Math.abs(Math.sin(rad)), 10); // bright sliver near 90°/270°
  // shine sweep position across face (repeats)
  const sx = ((shineT % 1.6) / 1.6) * 2.4 - 0.7;
  return (
    <div style={{
      position: 'absolute', left: -w / 2, top: -h / 2, width: w, height: h,
      transform: `rotateY(${rot}deg)`,
      borderRadius: 12, overflow: 'hidden',
      boxShadow: `0 0 ${40 + 50 * glowStrength}px rgba(228,190,110,${0.12 + 0.25 * glowStrength})`,
      background: '#15111b',
    }}>
      {facing ? (
        <div style={{ position: 'absolute', inset: 0 }}>
          <img src={src} alt="" style={{ width: '100%', height: '100%', display: 'block' }} />
          {/* premium reflection sweep */}
          <div style={{
            position: 'absolute', inset: 0,
            background: `linear-gradient(115deg, rgba(255,255,255,0) ${sx * 100 - 14}%, rgba(255,255,255,0.30) ${sx * 100}%, rgba(255,255,255,0) ${sx * 100 + 14}%)`,
          }}></div>
          {/* glass slab specular corner */}
          <div style={{
            position: 'absolute', inset: 0,
            background: 'linear-gradient(160deg, rgba(255,255,255,0.14) 0%, rgba(255,255,255,0) 24%)',
          }}></div>
        </div>
      ) : (
        <div style={{
          position: 'absolute', inset: 0,
          transform: 'scaleX(-1)',
          background: 'linear-gradient(150deg, #2c2733 0%, #16121c 55%, #241e2c 100%)',
          border: '1px solid rgba(255,255,255,0.10)',
          boxSizing: 'border-box',
        }}>
          <div style={{
            position: 'absolute', inset: '14px', borderRadius: 8,
            border: '1px solid rgba(217,169,78,0.30)',
            background: 'radial-gradient(ellipse 60% 45% at 50% 42%, rgba(217,169,78,0.10) 0%, rgba(0,0,0,0) 70%)',
          }}></div>
        </div>
      )}
      {/* edge-on glass sliver highlight */}
      <div style={{
        position: 'absolute', inset: 0,
        background: 'linear-gradient(to bottom, rgba(240,238,250,0.85), rgba(190,188,205,0.55))',
        opacity: edgeOn,
      }}></div>
    </div>
  );
}

Object.assign(window, {
  V, vrand, useIdleClock, cardRotation,
  Beams, BokehWall, MarbleFloor, Pedestal, GlassCase, GoldDust, HoloAura, Slab3D,
});
