import React, { useEffect, useRef, useCallback } from 'react';
import styled from 'styled-components';

// Тип для одной частицы
interface Particle {
    x: number;
    y: number;
    vx: number;        // скорость по X
    vy: number;        // скорость по Y
    radius: number;    // начальный радиус
    hue: number;       // оттенок (0–360)
    life: number;      // оставшееся время жизни (в кадрах)
    maxLife: number;   // полное время жизни
}

interface CelebrationCanvasProps {
    /** Включена ли анимация */
    active?: boolean;
    /** Длительность анимации в миллисекундах (по умолчанию 3000) */
    duration?: number;
    /** Количество частиц (по умолчанию 150) */
    particleCount?: number;
    /** Колбэк по окончании анимации */
    onComplete?: () => void;
}

// Стилизованный контейнер – фиксирован на весь экран, поверх всего (z-index: 5),
// но не перехватывает клики (pointer-events: none)
const Container = styled.div`
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100svh;
  z-index: 6;
  pointer-events: none;
`;

const StyledCanvas = styled.canvas`
  display: block;
  width: 100%;
  height: 100%;
  background: transparent; /* прозрачный фон */
z-index: 6;
`;

const CelebrationCanvas: React.FC<CelebrationCanvasProps> = ({
                                                                 active = true,
                                                                 duration = 3000,
                                                                 particleCount = 150,
                                                                 onComplete,
                                                             }) => {
    const canvasRef = useRef<HTMLCanvasElement>(null);
    const particlesRef = useRef<Particle[]>([]);
    const animationRef = useRef<number|undefined>(undefined);
    const startTimeRef = useRef<number>(0);

    // Основной цикл анимации
    const animate = useCallback(
        (timestamp: number) => {
            const canvas = canvasRef.current;
            if (!canvas) return;
            const ctx = canvas.getContext('2d');
            if (!ctx) return;

            const elapsed = timestamp - startTimeRef.current;

            // Завершаем по таймеру
            if (elapsed > duration) {
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                if (onComplete) onComplete();
                return;
            }

            // Очищаем canvas (прозрачный фон)
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            const particles = particlesRef.current;

            // Обновляем и рисуем каждую частицу
            for (let i = particles.length - 1; i >= 0; i--) {
                const p = particles[i];
                p.x += p.vx;
                p.y += p.vy;
                p.life -= 1;

                // Удаляем мёртвые или вышедшие за границы частицы
                if (
                    p.life <= 0 ||
                    p.x < 0 ||
                    p.x > canvas.width ||
                    p.y < 0 ||
                    p.y > canvas.height
                ) {
                    particles.splice(i, 1);
                    continue;
                }

                // Прозрачность и размер зависят от оставшегося времени жизни
                const alpha = Math.min(1, p.life / p.maxLife);
                const radius = p.radius * (0.3 + 0.7 * alpha);

                ctx.beginPath();
                ctx.arc(p.x, p.y, radius, 0, Math.PI * 2);
                ctx.fillStyle = `hsla(${p.hue}, 100%, 60%, ${alpha})`;
                ctx.fill();
            }

            // Если частицы кончились раньше таймера – завершаем
            if (particles.length === 0) {
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                if (onComplete) onComplete();
                return;
            }

            // Продолжаем анимацию
            animationRef.current = requestAnimationFrame(animate);
        },
        [duration, onComplete]
    );

    // Запуск / остановка анимации при изменении active
    useEffect(() => {
        if (!active) {
            // Останавливаем анимацию и очищаем canvas
            if (animationRef.current) {
                cancelAnimationFrame(animationRef.current);
                animationRef.current = undefined;
            }
            const canvas = canvasRef.current;
            if (canvas) {
                const ctx = canvas.getContext('2d');
                if (ctx) ctx.clearRect(0, 0, canvas.width, canvas.height);
            }
            return;
        }

        const canvas = canvasRef.current;
        if (!canvas) return;
        const ctx = canvas.getContext('2d');
        if (!ctx) return;

        // Подгоняем размер canvas под окно
        const resize = () => {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        };
        window.addEventListener('resize', resize);
        resize();

        // Генерируем частицы из центра
        const centerX = canvas.width / 2;
        const centerY = canvas.height / 2;
        const newParticles: Particle[] = [];

        for (let i = 0; i < particleCount; i++) {
            const angle = Math.random() * 2 * Math.PI;
            const speed = 2 + Math.random() * 7;
            const radius = 2 + Math.random() * 4;
            const hue = Math.random() * 360;
            const life = 40 + Math.random() * 80; // количество кадров жизни

            newParticles.push({
                x: centerX,
                y: centerY,
                vx: Math.cos(angle) * speed,
                vy: Math.sin(angle) * speed,
                radius,
                hue,
                life,
                maxLife: life,
            });
        }
        particlesRef.current = newParticles;

        // Запоминаем время старта
        startTimeRef.current = performance.now();

        // Отменяем предыдущий кадр, если был
        if (animationRef.current) {
            cancelAnimationFrame(animationRef.current);
        }
        animationRef.current = requestAnimationFrame(animate);

        // Cleanup при размонтировании или изменении зависимостей
        return () => {
            if (animationRef.current) {
                cancelAnimationFrame(animationRef.current);
                animationRef.current = undefined;
            }
            window.removeEventListener('resize', resize);
        };
    }, [active, particleCount, animate]);

    // Компонент всегда рендерится, но анимация запускается только при active=true
    return (
        <Container>
            <StyledCanvas ref={canvasRef} />
        </Container>
    );
};

export default CelebrationCanvas;