import React, { useMemo } from 'react';
import { SeasonalOverlayProps } from '../types';
import {
  animDoodleFloat,
  animConfettiTumble,
  animWobble,
  animRainbowDrift,
  animGoogly,
  animSparkle,
} from './AprilFools.css';

// Deterministic pseudo-random so the scene is identical on every mount and the
// reduced-motion preview thumbnail is stable. Large primes spread the values.
const rand = (seed: number) => {
  const x = Math.sin(seed * 127.1 + 311.7) * 43758.5453;
  return x - Math.floor(x);
};

// Bright-but-soft pastel rainbow in oklch. Kept luminous and gentle so the
// doodles read as crayon pastel over chat without ever fighting the text.
const PASTELS = [
  'oklch(0.85 0.12 20)', // pink
  'oklch(0.88 0.12 90)', // butter yellow
  'oklch(0.82 0.12 160)', // mint
  'oklch(0.8 0.12 260)', // periwinkle
  'oklch(0.84 0.12 320)', // lilac
  'oklch(0.86 0.11 50)', // peach
];

// Inline-SVG data-URI doodle glyphs, drawn hand-sketch style (round caps,
// open paths). `enc()` keeps them CSP-safe — no external assets, no base64.
const enc = (svg: string) => `url("data:image/svg+xml,${encodeURIComponent(svg)}")`;

// A single rough stroke wrapper helper for the glyph SVGs.
const stroke = (color: string, body: string) =>
  `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' fill='none' ` +
  `stroke='${color}' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'>${body}</svg>`;

// Question mark — the playful "huh?" centerpiece doodle.
const glyphQuestion = (c: string) =>
  stroke(
    c,
    `<path d='M11 11 q0 -6 6 -6 q6 0 6 5 q0 4 -5 6 q-2 1 -2 4'/>` +
      `<circle cx='16' cy='27' r='0.6' fill='${c}'/>`,
  );

// Exclamation / "bang" — a surprised little doodle.
const glyphBang = (c: string) =>
  stroke(c, `<path d='M16 5 L16 20'/><circle cx='16' cy='27' r='0.6' fill='${c}'/>`);

// Squiggle — a loopy scribble that adds whimsy.
const glyphSquiggle = (c: string) => stroke(c, `<path d='M5 18 q4 -10 8 0 t8 0 t8 0'/>`);

// Five-point doodle star (open-stroke, hand-drawn look).
const glyphStar = (c: string) =>
  stroke(
    c,
    `<path d='M16 5 L19.4 13 L28 13.6 L21.4 19.2 L23.5 27.6 L16 22.8 L8.5 27.6 ` +
      `L10.6 19.2 L4 13.6 L12.6 13 Z'/>`,
  );

// A tiny heart doodle for extra grin.
const glyphHeart = (c: string) =>
  stroke(c, `<path d='M16 26 C6 18 7 8 16 12 C25 8 26 18 16 26 Z'/>`);

const GLYPHS = [glyphQuestion, glyphBang, glyphSquiggle, glyphStar, glyphHeart, glyphQuestion];

type Doodle = {
  left: number;
  size: number;
  glyph: string;
  duration: number;
  delay: number;
  startTop: number; // used for the static (reduced) scatter
  opacity: number;
};

type Confetti = {
  left: number;
  size: number;
  color: string;
  duration: number;
  delay: number;
  startTop: number;
  ratio: number; // chip aspect
  round: boolean;
};

type Eye = {
  left: number;
  top: number;
  size: number;
  duration: number;
  delay: number;
};

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

export function AprilFoolsOverlay({ reduced }: SeasonalOverlayProps) {
  // ~16 drifting doodles. Built once; per-element timing creates the variety.
  const doodles = useMemo<Doodle[]>(() => {
    const count = 16;
    const out: Doodle[] = [];
    for (let i = 0; i < count; i += 1) {
      const color = PASTELS[i % PASTELS.length];
      out.push({
        left: rand(i + 0.1) * 96 + 2,
        size: 18 + rand(i + 0.3) * 22,
        glyph: enc(GLYPHS[i % GLYPHS.length](color)),
        duration: 16 + rand(i + 0.5) * 12,
        delay: -rand(i + 0.7) * 26,
        startTop: rand(i + 0.9) * 92 + 4,
        opacity: 0.5 + rand(i + 0.2) * 0.32,
      });
    }
    return out;
  }, []);

  // ~14 confetti chips in a couple of falling bands.
  const confetti = useMemo<Confetti[]>(() => {
    const count = 14;
    const out: Confetti[] = [];
    for (let i = 0; i < count; i += 1) {
      out.push({
        left: rand(i + 3.1) * 98 + 1,
        size: 5 + rand(i + 3.3) * 6,
        color: PASTELS[(i + 2) % PASTELS.length],
        duration: 10 + rand(i + 3.5) * 9,
        delay: -rand(i + 3.7) * 18,
        startTop: rand(i + 3.9) * 96 + 2,
        ratio: 0.45 + rand(i + 3.2) * 0.8,
        round: rand(i + 3.6) > 0.6,
      });
    }
    return out;
  }, []);

  // A few googly eyes peeking from corners/edges — the cheeky surprise.
  const eyes = useMemo<Eye[]>(() => {
    const anchors = [
      { left: 6, top: 12 },
      { left: 90, top: 20 },
      { left: 80, top: 82 },
      { left: 14, top: 74 },
    ];
    return anchors.map((a, i) => ({
      left: a.left,
      top: a.top,
      size: 22 + rand(i + 5.1) * 12,
      duration: 3 + rand(i + 5.3) * 2.5,
      delay: -rand(i + 5.5) * 3,
    }));
  }, []);

  // Sly winking sparkles scattered sparsely.
  const sparks = useMemo<Spark[]>(() => {
    const count = 5;
    const out: Spark[] = [];
    for (let i = 0; i < count; i += 1) {
      out.push({
        left: rand(i + 7.1) * 90 + 5,
        top: rand(i + 7.3) * 84 + 8,
        size: 12 + rand(i + 7.5) * 12,
        color: PASTELS[(i + 1) % PASTELS.length],
        duration: 4 + rand(i + 7.7) * 3,
        delay: -rand(i + 7.9) * 5,
      });
    }
    return out;
  }, []);

  // Four-point glint used for the winking sparkles.
  const sparkGlint = (c: string) =>
    enc(
      `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'>` +
        `<path d='M12 0 C13 8 16 11 24 12 C16 13 13 16 12 24 C11 16 8 13 0 12 C8 11 11 8 12 0 Z' fill='${c}'/></svg>`,
    );

  return (
    <>
      {/* Soft pastel ambient wash — layered oklch radials for depth. Very low
          opacity so chat text keeps WCAG-AA contrast. */}
      <div
        aria-hidden="true"
        style={{
          position: 'absolute',
          inset: 0,
          contain: 'layout paint style',
          backgroundImage: [
            'radial-gradient(110% 70% at 18% -8%, oklch(0.85 0.12 20 / 0.1) 0%, transparent 55%)',
            'radial-gradient(95% 65% at 86% 0%, oklch(0.82 0.12 160 / 0.09) 0%, transparent 58%)',
            'radial-gradient(120% 80% at 50% 112%, oklch(0.8 0.12 260 / 0.1) 0%, transparent 60%)',
            'linear-gradient(180deg, oklch(0.88 0.12 90 / 0.05) 0%, transparent 30%, transparent 78%, oklch(0.84 0.12 320 / 0.06) 100%)',
          ].join(','),
        }}
      />

      {/* Faux wobble layer — a near-invisible pastel haze that gently skews so
          the whole scene feels playfully "tickled". Tiny amplitude = not
          nauseating. backdrop-filter is one cheap layer for a candy bloom. */}
      <div
        aria-hidden="true"
        style={{
          position: 'absolute',
          inset: '-2%',
          contain: 'layout paint style',
          backdropFilter: 'saturate(1.06) brightness(1.01)',
          WebkitBackdropFilter: 'saturate(1.06) brightness(1.01)',
          backgroundImage:
            'radial-gradient(130% 120% at 50% 45%, transparent 60%, oklch(0.86 0.11 50 / 0.05) 80%, oklch(0.8 0.12 260 / 0.08) 100%)',
          transformOrigin: '50% 50%',
          animation: reduced ? 'none' : `${animWobble} 14s ease-in-out infinite`,
          willChange: reduced ? undefined : 'transform',
        }}
      />

      {/* Pastel rainbow aurora high up — soft band of the full palette. */}
      <div
        aria-hidden="true"
        style={{
          position: 'absolute',
          top: '-8%',
          left: '-10%',
          right: '-10%',
          height: '42%',
          contain: 'layout paint style',
          mixBlendMode: 'screen',
          filter: 'blur(30px)',
          opacity: reduced ? 0.6 : undefined,
          backgroundImage: [
            'radial-gradient(50% 100% at 18% 0%, oklch(0.85 0.12 20 / 0.16) 0%, transparent 72%)',
            'radial-gradient(50% 100% at 40% 0%, oklch(0.88 0.12 90 / 0.14) 0%, transparent 72%)',
            'radial-gradient(50% 100% at 62% 0%, oklch(0.82 0.12 160 / 0.14) 0%, transparent 72%)',
            'radial-gradient(50% 100% at 84% 0%, oklch(0.8 0.12 260 / 0.16) 0%, transparent 72%)',
          ].join(','),
          animation: reduced ? 'none' : `${animRainbowDrift} 20s ease-in-out infinite`,
          willChange: reduced ? undefined : 'transform, opacity',
        }}
      />

      {/* Drifting doodles. Motion: rise from below. Reduced: static scatter. */}
      {doodles.map((d, i) => {
        const common: React.CSSProperties = {
          position: 'absolute',
          left: `${d.left}%`,
          width: `${d.size}px`,
          height: `${d.size}px`,
          backgroundImage: d.glyph,
          backgroundRepeat: 'no-repeat',
          backgroundSize: 'contain',
          backgroundPosition: 'center',
          opacity: d.opacity,
          filter: 'drop-shadow(0 1px 1px oklch(0.4 0.05 300 / 0.18))',
        };
        if (reduced) {
          return (
            <div
              key={`doodle-${i}`}
              aria-hidden="true"
              style={{
                ...common,
                top: `${d.startTop}%`,
                transform: `rotate(${(rand(i + 11) - 0.5) * 24}deg)`,
              }}
            />
          );
        }
        return (
          <div
            key={`doodle-${i}`}
            aria-hidden="true"
            style={{
              ...common,
              top: 0,
              animation: `${animDoodleFloat} ${d.duration}s ease-in-out ${d.delay}s infinite`,
              willChange: 'transform, opacity',
            }}
          />
        );
      })}

      {/* Light confetti — tumbling pastel chips. */}
      {confetti.map((c, i) => {
        const common: React.CSSProperties = {
          position: 'absolute',
          left: `${c.left}%`,
          width: `${c.size}px`,
          height: `${c.size * c.ratio}px`,
          background: c.color,
          borderRadius: c.round ? '50%' : '1px',
          opacity: 0.75,
        };
        if (reduced) {
          return (
            <div
              key={`confetti-${i}`}
              aria-hidden="true"
              style={{
                ...common,
                top: `${c.startTop}%`,
                transform: `rotate(${rand(i + 13) * 360}deg)`,
              }}
            />
          );
        }
        return (
          <div
            key={`confetti-${i}`}
            aria-hidden="true"
            style={{
              ...common,
              top: 0,
              animation: `${animConfettiTumble} ${c.duration}s linear ${c.delay}s infinite`,
              willChange: 'transform, opacity',
            }}
          />
        );
      })}

      {/* Googly eyes peeking from the edges — pupil wanders cheekily. */}
      {eyes.map((e, i) => (
        <div
          key={`eye-${i}`}
          aria-hidden="true"
          style={{
            position: 'absolute',
            left: `${e.left}%`,
            top: `${e.top}%`,
            width: `${e.size}px`,
            height: `${e.size}px`,
            marginLeft: `${-e.size / 2}px`,
            marginTop: `${-e.size / 2}px`,
            borderRadius: '50%',
            background:
              'radial-gradient(circle at 38% 32%, oklch(0.99 0.005 90 / 0.85) 0%, oklch(0.95 0.01 90 / 0.7) 62%, oklch(0.75 0.02 90 / 0.6) 100%)',
            boxShadow: 'inset 0 0 0 1.5px oklch(0.45 0.03 300 / 0.35)',
            opacity: 0.6,
          }}
        >
          {/* Pupil */}
          <div
            style={{
              position: 'absolute',
              left: '50%',
              top: '50%',
              width: `${e.size * 0.4}px`,
              height: `${e.size * 0.4}px`,
              marginLeft: `${-e.size * 0.2}px`,
              marginTop: `${-e.size * 0.2}px`,
              borderRadius: '50%',
              background:
                'radial-gradient(circle at 36% 30%, oklch(0.5 0.04 300 / 0.95) 0%, oklch(0.28 0.04 300 / 0.95) 70%)',
              animation: reduced
                ? 'none'
                : `${animGoogly} ${e.duration}s ease-in-out ${e.delay}s infinite`,
              willChange: reduced ? undefined : 'transform',
            }}
          >
            {/* Catchlight */}
            <div
              style={{
                position: 'absolute',
                left: '22%',
                top: '20%',
                width: '28%',
                height: '28%',
                borderRadius: '50%',
                background: 'oklch(0.99 0.005 90 / 0.85)',
              }}
            />
          </div>
        </div>
      ))}

      {/* Sly winking sparkles. Static (reduced) shows them mid-glint. */}
      {sparks.map((s, i) => (
        <div
          key={`spark-${i}`}
          aria-hidden="true"
          style={{
            position: 'absolute',
            left: `${s.left}%`,
            top: `${s.top}%`,
            width: `${s.size}px`,
            height: `${s.size}px`,
            backgroundImage: sparkGlint(s.color),
            backgroundRepeat: 'no-repeat',
            backgroundSize: 'contain',
            backgroundPosition: 'center',
            filter: `drop-shadow(0 0 3px ${s.color.replace(')', ' / 0.5)')})`,
            opacity: reduced ? 0.8 : undefined,
            transform: reduced ? 'scale(0.95) rotate(40deg)' : undefined,
            animation: reduced
              ? 'none'
              : `${animSparkle} ${s.duration}s ease-in-out ${s.delay}s infinite`,
            willChange: reduced ? undefined : 'transform, opacity',
          }}
        />
      ))}
    </>
  );
}
