import React, { useMemo } from 'react';
import { SeasonalOverlayProps } from '../types';
import {
  animBurst,
  animCoreFlash,
  animShimmer,
  animConfettiFall,
  animConfettiSway,
  animTwinkle,
  animSkyPulse,
} from './NewYear.css';

/**
 * New Year overlay — a midnight celebration. Layered oklch gradients sink the
 * app into a deep navy night; fireworks bloom as expanding spark rings, a
 * champagne-gold shimmer sweeps across, confetti slivers tumble down, and
 * sparkle stars twinkle. All motion is transform/opacity only.
 *
 * Palette (oklch): midnight navy oklch(0.20 0.07 260), champagne gold
 * oklch(0.85 0.13 90), bursts in magenta oklch(0.7 0.22 350), cyan
 * oklch(0.8 0.15 200), and gold.
 *
 * RENDERING CONTRACT: the parent supplies a fixed inset:0 overflow:hidden
 * pointer-events:none container at the right z-index. We only return
 * absolutely-positioned aria-hidden children at low opacity — no z-index,
 * position:fixed, or pointer-events here — kept well below opaque so chat text
 * stays WCAG-AA legible.
 *
 * REDUCED MOTION: when `reduced`, render a static but gorgeous scene (a frozen
 * firework bloom mid-burst, scattered gold confetti, a still shimmer band) with
 * no `animation` at all. The settings preview always passes reduced=true.
 */

const BURST_HUES = [
  // [ring oklch, core oklch]
  ['oklch(0.7 0.22 350)', 'oklch(0.88 0.14 350)'], // magenta
  ['oklch(0.8 0.15 200)', 'oklch(0.92 0.1 200)'], // cyan
  ['oklch(0.85 0.13 90)', 'oklch(0.95 0.09 95)'], // gold
  ['oklch(0.75 0.2 30)', 'oklch(0.9 0.12 40)'], // warm coral
] as const;

const CONFETTI_COLORS = [
  'oklch(0.85 0.13 90)', // champagne gold
  'oklch(0.7 0.22 350)', // magenta
  'oklch(0.8 0.15 200)', // cyan
  'oklch(0.9 0.06 90)', // pale gold
  'oklch(0.78 0.18 30)', // coral
] as const;

type Burst = {
  top: number;
  left: number;
  size: number;
  ring: string;
  core: string;
  duration: number;
  delay: number;
};

type Confetto = {
  left: number;
  w: number;
  h: number;
  color: string;
  round: boolean;
  fallDur: number;
  swayDur: number;
  delay: number;
};

type Star = {
  top: number;
  left: number;
  size: number;
  color: string;
  duration: number;
  delay: number;
};

// Deterministic pseudo-random so the memoized scene is stable across renders.
const rand = (seed: number) => {
  const x = Math.sin(seed * 12.9898 + 78.233) * 43758.5453;
  return x - Math.floor(x);
};

// A four-point sparkle (gleam) as an inline SVG data-URI — CSP-safe, no assets.
const sparkleUri = (color: string) =>
  `url("data:image/svg+xml,${encodeURIComponent(
    `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 0 L14 10 L24 12 L14 14 L12 24 L10 14 L0 12 L10 10 Z' fill='${color}'/></svg>`,
  )}")`;

export function NewYearOverlay({ reduced }: SeasonalOverlayProps) {
  const bursts = useMemo<Burst[]>(
    () =>
      // Bursts cluster in the upper two-thirds of the sky, away from typical text.
      Array.from({ length: 7 }, (_, i) => {
        const hue = BURST_HUES[i % BURST_HUES.length];
        return {
          top: 8 + rand(i + 1) * 48,
          left: 8 + rand(i + 11) * 84,
          size: 130 + Math.floor(rand(i + 21) * 110),
          ring: hue[0],
          core: hue[1],
          duration: 6.5 + rand(i + 31) * 4,
          delay: rand(i + 41) * 9,
        };
      }),
    [],
  );

  const confetti = useMemo<Confetto[]>(
    () =>
      Array.from({ length: 20 }, (_, i) => ({
        left: rand(i + 101) * 100,
        w: 4 + Math.floor(rand(i + 111) * 4),
        h: 7 + Math.floor(rand(i + 121) * 7),
        color: CONFETTI_COLORS[i % CONFETTI_COLORS.length],
        round: i % 4 === 0,
        fallDur: 9 + rand(i + 131) * 7,
        swayDur: 3 + rand(i + 141) * 3,
        delay: rand(i + 151) * 10,
      })),
    [],
  );

  const stars = useMemo<Star[]>(
    () =>
      Array.from({ length: 9 }, (_, i) => ({
        top: 4 + rand(i + 201) * 64,
        left: 4 + rand(i + 211) * 92,
        size: 8 + Math.floor(rand(i + 221) * 10),
        color: i % 2 === 0 ? 'oklch(0.85 0.13 90)' : 'oklch(0.92 0.06 200)',
        duration: 3 + rand(i + 231) * 3,
        delay: rand(i + 241) * 4,
      })),
    [],
  );

  return (
    <>
      {/* Midnight sky — layered oklch gradients for depth, with a faint breathe. */}
      <div
        aria-hidden="true"
        style={{
          position: 'absolute',
          inset: 0,
          contain: 'layout paint style',
          backgroundColor: 'oklch(0.2 0.07 260 / 0.12)',
          backgroundImage: [
            'radial-gradient(120% 90% at 50% -10%, oklch(0.32 0.1 280 / 0.16) 0%, transparent 60%)',
            'radial-gradient(90% 70% at 18% 8%, oklch(0.7 0.22 350 / 0.07) 0%, transparent 55%)',
            'radial-gradient(90% 70% at 84% 4%, oklch(0.8 0.15 200 / 0.07) 0%, transparent 55%)',
            'radial-gradient(140% 120% at 50% 120%, oklch(0.2 0.07 260 / 0.14) 0%, transparent 70%)',
          ].join(','),
          animation: reduced ? 'none' : `${animSkyPulse} 9s ease-in-out infinite`,
        }}
      />

      {/* Champagne-gold shimmer sweep. */}
      <div
        aria-hidden="true"
        style={{
          position: 'absolute',
          top: 0,
          bottom: 0,
          left: 0,
          width: '55%',
          contain: 'layout paint style',
          backgroundImage:
            'linear-gradient(100deg, transparent 0%, oklch(0.85 0.13 90 / 0.05) 38%, oklch(0.95 0.09 95 / 0.1) 50%, oklch(0.85 0.13 90 / 0.05) 62%, transparent 100%)',
          transform: reduced ? 'translate3d(30%, 0, 0) skewX(-12deg)' : undefined,
          opacity: reduced ? 0.45 : undefined,
          animation: reduced ? 'none' : `${animShimmer} 11s ease-in-out infinite`,
        }}
      />

      {/* Fireworks — expanding spark rings + a core flash. In reduced mode we
          freeze the first burst mid-bloom and drop the rest. */}
      {(reduced ? bursts.slice(0, 1) : bursts).map((b, i) => (
        <div
          key={`b${i}`}
          aria-hidden="true"
          style={{
            position: 'absolute',
            top: `${b.top}%`,
            left: `${b.left}%`,
            width: `${b.size}px`,
            height: `${b.size}px`,
            marginLeft: `${-b.size / 2}px`,
            marginTop: `${-b.size / 2}px`,
          }}
        >
          {/* Spark ring */}
          <div
            style={{
              position: 'absolute',
              inset: 0,
              borderRadius: '50%',
              willChange: reduced ? undefined : 'transform, opacity',
              background: `radial-gradient(circle, transparent 56%, ${b.ring} 64%, transparent 74%)`,
              transform: reduced ? 'scale(0.82)' : undefined,
              opacity: reduced ? 0.6 : undefined,
              animation: reduced
                ? 'none'
                : `${animBurst} ${b.duration}s ease-out ${b.delay}s infinite`,
            }}
          />
          {/* Inner secondary ring for a fuller bloom */}
          <div
            style={{
              position: 'absolute',
              inset: '18%',
              borderRadius: '50%',
              background: `radial-gradient(circle, transparent 50%, ${b.ring} 60%, transparent 72%)`,
              transform: reduced ? 'scale(0.7)' : undefined,
              opacity: reduced ? 0.4 : undefined,
              animation: reduced
                ? 'none'
                : `${animBurst} ${b.duration}s ease-out ${b.delay + 0.12}s infinite`,
            }}
          />
          {/* Core flash */}
          <div
            style={{
              position: 'absolute',
              left: '50%',
              top: '50%',
              width: '14%',
              height: '14%',
              marginLeft: '-7%',
              marginTop: '-7%',
              borderRadius: '50%',
              background: `radial-gradient(circle, ${b.core} 0%, transparent 70%)`,
              transform: reduced ? 'scale(0.9)' : undefined,
              opacity: reduced ? 0.85 : undefined,
              animation: reduced
                ? 'none'
                : `${animCoreFlash} ${b.duration}s ease-out ${b.delay}s infinite`,
            }}
          />
        </div>
      ))}

      {/* Twinkling sparkle stars. */}
      {stars.map((s, i) => (
        <div
          key={`s${i}`}
          aria-hidden="true"
          style={{
            position: 'absolute',
            top: `${s.top}%`,
            left: `${s.left}%`,
            width: `${s.size}px`,
            height: `${s.size}px`,
            backgroundImage: sparkleUri(s.color),
            backgroundRepeat: 'no-repeat',
            backgroundSize: 'contain',
            transform: reduced ? 'scale(0.9) rotate(30deg)' : undefined,
            opacity: reduced ? 0.75 : undefined,
            animation: reduced
              ? 'none'
              : `${animTwinkle} ${s.duration}s ease-in-out ${s.delay}s infinite`,
          }}
        />
      ))}

      {/* Falling confetti slivers. In reduced mode, a still scatter at varied
          heights so the static thumbnail reads as a celebration in progress. */}
      {confetti.map((c, i) => {
        const staticTop = reduced ? 6 + rand(i + 301) * 78 : undefined;
        return (
          <div
            key={`c${i}`}
            aria-hidden="true"
            style={{
              position: 'absolute',
              top: reduced ? `${staticTop}%` : 0,
              left: `${c.left}%`,
              willChange: reduced ? undefined : 'transform',
              animation: reduced
                ? 'none'
                : `${animConfettiSway} ${c.swayDur}s ease-in-out ${c.delay}s infinite`,
            }}
          >
            <div
              style={{
                width: `${c.w}px`,
                height: reduced && c.round ? `${c.w}px` : `${c.h}px`,
                borderRadius: c.round ? '50%' : '1px',
                backgroundColor: c.color,
                opacity: reduced ? 0.8 : 0.85,
                transform: reduced ? `rotate(${Math.floor(rand(i + 311) * 360)}deg)` : undefined,
                animation: reduced
                  ? 'none'
                  : `${animConfettiFall} ${c.fallDur}s ease-in ${c.delay}s infinite`,
              }}
            />
          </div>
        );
      })}
    </>
  );
}
