import { useEffect, useState } from 'react';
import ReactConfetti from 'react-confetti';

type ConfettiPosition = {
  x: number;
  y: number;
  w: number;
  h: number;
};

type ConfettiProps = {
  pieces?: number;
  element?: HTMLElement | null;
  onDone?: () => void;
};

export function Confetti(props: ConfettiProps) {
  const { element = document.body, onDone = () => null, pieces = 40 } = props;

  const [confettiPos, setConfettiPos] = useState<
    undefined | ConfettiPosition
  >();

  function populateConfettiPosition(element: HTMLElement) {
    const elRect = element.getBoundingClientRect();

    // set confetti position, keeping in mind the scroll values
    setConfettiPos({
      x: elRect?.x || 0,
      y: (elRect?.y || 0) + window.scrollY,
      w: elRect?.width || 0,
      h: elRect?.height || 0,
    });
  }

  useEffect(() => {
    if (!element) {
      setConfettiPos(undefined);
      return;
    }

    populateConfettiPosition(element);
  }, [element]);

  if (!confettiPos) {
    return null;
  }

  return (
    <ReactConfetti
      height={document.body.scrollHeight}
      numberOfPieces={pieces}
      recycle={false}
      onConfettiComplete={(confettiInstance) => {
        setConfettiPos(undefined);
        onDone();
      }}
      initialVelocityX={4}
      initialVelocityY={8}
      tweenDuration={10}
      confettiSource={{
        x: confettiPos.x,
        y: confettiPos.y,
        w: confettiPos.w,
        h: confettiPos.h,
      }}
    />
  );
}