// scenes.jsx — Scene components for the TR Grading video

// ── Brand tokens ────────────────────────────────────────────────────────────
const TR = {
  bg: '#0a0e12',
  bgDeep: '#05070a',
  ink: '#f3f6f4',
  inkDim: 'rgba(243, 246, 244, 0.58)',
  inkFaint: 'rgba(243, 246, 244, 0.28)',
  line: 'rgba(243, 246, 244, 0.10)',
  green: '#00e576',
  cyan: '#00d4ff',
  amber: '#ffb547',
  warn: '#ff7a47',
  gradient: 'linear-gradient(90deg, #00e576 0%, #00d4ff 100%)',
  mono: "'JetBrains Mono', ui-monospace, SFMono-Regular, monospace",
  sans: "'Inter', system-ui, -apple-system, sans-serif",
};

// ── Shared atoms ────────────────────────────────────────────────────────────

// Big animated ring behind the phone, pulses + rotates
function HaloRing({ x, y, size = 720, color = TR.green, color2 = TR.cyan, opacity = 0.35 }) {
  const { localTime, progress } = useSprite();
  const rot = localTime * 8; // slow rotate
  const breath = 1 + Math.sin(localTime * 1.2) * 0.015;
  const appear = Easing.easeOutCubic(clamp(localTime / 0.8, 0, 1));
  return (
    <div style={{
      position: 'absolute',
      left: x - size / 2, top: y - size / 2,
      width: size, height: size,
      opacity: appear * opacity,
      transform: `rotate(${rot}deg) scale(${breath})`,
      pointerEvents: 'none',
    }}>
      <div style={{
        position: 'absolute', inset: 0,
        borderRadius: '50%',
        background: `conic-gradient(from 0deg, ${color} 0deg, ${color2} 120deg, transparent 200deg, ${color} 360deg)`,
        filter: 'blur(60px)',
      }}/>
      <div style={{
        position: 'absolute', inset: '18%',
        borderRadius: '50%',
        border: `1px solid ${color}40`,
      }}/>
      <div style={{
        position: 'absolute', inset: '26%',
        borderRadius: '50%',
        border: `1px dashed ${color2}30`,
      }}/>
    </div>
  );
}

// Grid background — subtle, fades in
function GridBG() {
  const t = useTime();
  const fade = Easing.easeOutCubic(clamp(t / 1.2, 0, 1));
  return (
    <div style={{
      position: 'absolute', inset: 0,
      opacity: fade * 0.5,
      backgroundImage: `
        linear-gradient(${TR.line} 1px, transparent 1px),
        linear-gradient(90deg, ${TR.line} 1px, transparent 1px)
      `,
      backgroundSize: '80px 80px',
      maskImage: 'radial-gradient(ellipse at center, black 30%, transparent 85%)',
      WebkitMaskImage: 'radial-gradient(ellipse at center, black 30%, transparent 85%)',
    }}/>
  );
}

// Noise overlay — film grain for warmth
function NoiseBG() {
  return (
    <div style={{
      position: 'absolute', inset: 0,
      opacity: 0.04,
      mixBlendMode: 'overlay',
      pointerEvents: 'none',
      backgroundImage: `url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)' opacity='0.9'/></svg>")`,
    }}/>
  );
}

// TR logo mark rendered in SVG so we can animate stroke
function LogoMark({ size = 120, progress = 1 }) {
  const dash = 2 * Math.PI * 90;
  const drawn = dash * clamp(progress, 0, 1);
  return (
    <svg viewBox="0 0 200 200" width={size} height={size} style={{ display: 'block' }}>
      <defs>
        <linearGradient id="tr-grad" x1="0" y1="0" x2="1" y2="0.2">
          <stop offset="0%" stopColor={TR.green}/>
          <stop offset="100%" stopColor={TR.cyan}/>
        </linearGradient>
      </defs>
      <circle cx="100" cy="100" r="90" fill="none" stroke="url(#tr-grad)" strokeWidth="7"
        strokeLinecap="round"
        strokeDasharray={`${drawn} ${dash}`}
        transform="rotate(-90 100 100)" />
      {/* T */}
      <g opacity={clamp((progress - 0.5) * 2, 0, 1)}>
        <rect x="42" y="56" width="75" height="14" fill="url(#tr-grad)"/>
        <rect x="72" y="56" width="14" height="92" fill="url(#tr-grad)"/>
      </g>
      {/* R */}
      <g opacity={clamp((progress - 0.6) * 2.5, 0, 1)}>
        <path d="M108 56 h26 a20 20 0 0 1 0 40 h-26 z M108 90 h26 l22 58 h-16 l-18 -46 h-14 v46 h-14 v-92 h14 z" fill="url(#tr-grad)"/>
      </g>
    </svg>
  );
}

// Tiny label chip
function Chip({ children, color = TR.green, x, y }) {
  const { localTime } = useSprite();
  const t = Easing.easeOutBack(clamp(localTime / 0.5, 0, 1));
  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      transform: `translateY(${(1 - t) * 10}px)`,
      opacity: t,
      display: 'inline-flex', alignItems: 'center', gap: 8,
      padding: '8px 14px',
      border: `1px solid ${color}`,
      borderRadius: 999,
      background: `${color}14`,
      color: color,
      fontFamily: TR.mono,
      fontSize: 13,
      letterSpacing: '0.16em',
      textTransform: 'uppercase',
      fontWeight: 500,
    }}>
      <span style={{
        width: 6, height: 6, borderRadius: '50%', background: color,
        boxShadow: `0 0 12px ${color}`,
      }}/>
      {children}
    </div>
  );
}

// Scan line that sweeps across the phone during inspection
function ScanLine({ x, y, width, height, delay = 0, duration = 1.4, color = TR.green }) {
  const { localTime } = useSprite();
  const t = clamp((localTime - delay) / duration, 0, 1);
  if (t <= 0 || t >= 1) return null;
  const eased = Easing.easeInOutCubic(t);
  const opacity = Math.sin(t * Math.PI);
  return (
    <div style={{
      position: 'absolute',
      left: x, top: y + eased * height - 2,
      width, height: 4,
      background: `linear-gradient(90deg, transparent, ${color}, transparent)`,
      boxShadow: `0 0 24px ${color}, 0 0 48px ${color}80`,
      opacity,
      pointerEvents: 'none',
      borderRadius: 2,
    }}/>
  );
}

// Tiny hotspot marker that pops onto the phone
function Hotspot({ x, y, delay = 0, label, color = TR.amber }) {
  const { localTime } = useSprite();
  const t = clamp((localTime - delay) / 0.5, 0, 1);
  if (t <= 0) return null;
  const s = Easing.easeOutBack(t);
  const pulse = 1 + Math.sin((localTime - delay) * 3) * 0.1;
  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      transform: `translate(-50%, -50%) scale(${s})`,
      opacity: t,
      pointerEvents: 'none',
    }}>
      <div style={{
        position: 'absolute', left: -22, top: -22,
        width: 44, height: 44,
        borderRadius: '50%',
        border: `1.5px solid ${color}`,
        transform: `scale(${pulse})`,
        opacity: 0.6,
      }}/>
      <div style={{
        width: 10, height: 10, borderRadius: '50%',
        background: color,
        boxShadow: `0 0 16px ${color}`,
      }}/>
      {label && (
        <div style={{
          position: 'absolute', left: 18, top: -9,
          whiteSpace: 'nowrap',
          fontFamily: TR.mono,
          fontSize: 12,
          color: color,
          letterSpacing: '0.08em',
          textTransform: 'uppercase',
        }}>
          {label}
        </div>
      )}
    </div>
  );
}

// Staggered text reveal (word by word)
function WordReveal({ text, x, y, size = 72, color = TR.ink, weight = 700, delay = 0, stagger = 0.08, font = TR.sans, letterSpacing = '-0.03em', lineHeight = 1.02 }) {
  const { localTime } = useSprite();
  const words = text.split(' ');
  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      fontFamily: font,
      fontSize: size,
      fontWeight: weight,
      color,
      letterSpacing,
      lineHeight,
      display: 'flex', flexWrap: 'wrap', gap: '0.25em',
      maxWidth: 920,
    }}>
      {words.map((w, i) => {
        const t = clamp((localTime - delay - i * stagger) / 0.5, 0, 1);
        const e = Easing.easeOutCubic(t);
        return (
          <span key={i} style={{
            display: 'inline-block',
            transform: `translateY(${(1 - e) * 30}px)`,
            opacity: e,
            willChange: 'transform, opacity',
          }}>
            {w}
          </span>
        );
      })}
    </div>
  );
}

// A checklist item that ticks in
function CheckItem({ x, y, label, delay = 0, color = TR.green, neg = false, idx = 0 }) {
  const { localTime } = useSprite();
  const t = clamp((localTime - delay - idx * 0.15) / 0.5, 0, 1);
  const e = Easing.easeOutCubic(t);
  const drawT = clamp((localTime - delay - idx * 0.15 - 0.15) / 0.35, 0, 1);

  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      display: 'flex', alignItems: 'center', gap: 16,
      transform: `translateX(${(1 - e) * -16}px)`,
      opacity: e,
      fontFamily: TR.sans,
      fontSize: 22,
      fontWeight: 400,
      color: TR.ink,
      letterSpacing: '-0.01em',
    }}>
      <div style={{
        width: 28, height: 28, borderRadius: 8,
        border: `1.5px solid ${color}`,
        background: `${color}1a`,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        flexShrink: 0,
      }}>
        <svg viewBox="0 0 24 24" width="20" height="20" fill="none">
          {neg ? (
            <path d="M6 6 L18 18 M18 6 L6 18"
              stroke={color} strokeWidth="2.5" strokeLinecap="round"
              strokeDasharray="30" strokeDashoffset={30 - 30 * drawT} />
          ) : (
            <path d="M5 12 L10 17 L19 7"
              stroke={color} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"
              strokeDasharray="30" strokeDashoffset={30 - 30 * drawT} />
          )}
        </svg>
      </div>
      <span>{label}</span>
    </div>
  );
}

// Animated counter
function Counter({ x, y, from = 0, to = 100, suffix = '', size = 140, delay = 0, duration = 1.2, color = TR.ink }) {
  const { localTime } = useSprite();
  const t = clamp((localTime - delay) / duration, 0, 1);
  const v = from + (to - from) * Easing.easeOutCubic(t);
  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      fontFamily: TR.sans,
      fontSize: size,
      fontWeight: 700,
      color,
      letterSpacing: '-0.04em',
      lineHeight: 1,
      fontVariantNumeric: 'tabular-nums',
    }}>
      {Math.round(v)}{suffix}
    </div>
  );
}

// Big gradient "A", "A/B", "B/C" grade mark rendered large
function GradeMark({ x, y, label, size = 340, delay = 0 }) {
  const { localTime } = useSprite();
  const t = clamp((localTime - delay) / 0.7, 0, 1);
  const e = Easing.easeOutBack(t);
  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      fontFamily: TR.sans,
      fontSize: size,
      fontWeight: 900,
      lineHeight: 1,
      letterSpacing: '-0.06em',
      background: TR.gradient,
      WebkitBackgroundClip: 'text',
      WebkitTextFillColor: 'transparent',
      backgroundClip: 'text',
      transform: `scale(${0.6 + 0.4 * e})`,
      transformOrigin: 'left top',
      opacity: t,
      filter: `drop-shadow(0 8px 40px ${TR.green}40)`,
    }}>
      {label}
    </div>
  );
}

// Small caps meta label (eyebrow)
function Eyebrow({ x, y, text, color = TR.inkDim, delay = 0 }) {
  const { localTime } = useSprite();
  const t = clamp((localTime - delay) / 0.5, 0, 1);
  const e = Easing.easeOutCubic(t);
  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      transform: `translateY(${(1 - e) * 10}px)`,
      opacity: e,
      fontFamily: TR.mono,
      fontSize: 13,
      letterSpacing: '0.28em',
      color,
      textTransform: 'uppercase',
      fontWeight: 500,
      display: 'flex', alignItems: 'center', gap: 12,
    }}>
      <span style={{ width: 32, height: 1, background: color, display: 'inline-block' }}/>
      {text}
    </div>
  );
}

// Price chip with animated percentage discount
function PriceBlock({ x, y, newPrice, oldPrice, savePct, delay = 0 }) {
  const { localTime } = useSprite();
  const t1 = clamp((localTime - delay) / 0.5, 0, 1);
  const t2 = clamp((localTime - delay - 0.3) / 0.6, 0, 1);
  const e1 = Easing.easeOutCubic(t1);
  const e2 = Easing.easeOutCubic(t2);
  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      opacity: e1,
      transform: `translateY(${(1 - e1) * 16}px)`,
    }}>
      <div style={{
        fontFamily: TR.mono,
        fontSize: 12,
        letterSpacing: '0.2em',
        color: TR.inkDim,
        textTransform: 'uppercase',
        marginBottom: 8,
      }}>
        Ab Preis
      </div>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 16 }}>
        <div style={{
          fontFamily: TR.sans,
          fontSize: 84,
          fontWeight: 800,
          color: TR.ink,
          letterSpacing: '-0.04em',
          lineHeight: 1,
        }}>
          {newPrice}€
        </div>
        <div style={{
          fontFamily: TR.sans,
          fontSize: 24,
          fontWeight: 500,
          color: TR.inkFaint,
          textDecoration: 'line-through',
          textDecorationColor: TR.inkFaint,
        }}>
          {oldPrice}€
        </div>
      </div>
      <div style={{
        opacity: e2,
        marginTop: 10,
        display: 'inline-flex', alignItems: 'center', gap: 8,
        padding: '6px 12px',
        background: `${TR.green}1a`,
        border: `1px solid ${TR.green}`,
        borderRadius: 6,
        color: TR.green,
        fontFamily: TR.mono,
        fontSize: 13,
        fontWeight: 500,
        letterSpacing: '0.08em',
      }}>
        −{savePct}% GESPART
      </div>
    </div>
  );
}

Object.assign(window, {
  TR, HaloRing, GridBG, NoiseBG, LogoMark, Chip, ScanLine, Hotspot,
  WordReveal, CheckItem, Counter, GradeMark, Eyebrow, PriceBlock,
});
