import React, { useEffect, useState, useRef } from "react";
import { assetsPath } from "./Common";
import "./Bird.css";

const birdAngles = 12;
const frames = [0, 0, 1, 2, 3, 3, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

const useAnimationFrame = (callback: (t: number) => void) => {
  const requestRef = useRef<number | null>(null);
  const animate = (time: number) => {
    callback(time);
    requestRef.current = requestAnimationFrame(animate);
  };
  useEffect(() => {
    requestRef.current = requestAnimationFrame(animate);
    return () => {
      if (requestRef.current !== null) {
        cancelAnimationFrame(requestRef.current);
      }
    };
  }, []);
};

const Bird: React.FC<{ radius: number; speed: number; size: number; style?: React.CSSProperties }> = ({
  radius,
  speed,
  size,
  style,
}) => {
  const [time, setTime] = useState(0);
  const [angle, setAngle] = useState(Math.random() * 360);
  const [rotation] = useState((Math.PI * 2 * radius) / 5);
  const [direction, setDirection] = useState(Math.floor((birdAngles * (angle ? angle : 0)) / 360));
  const [cell, setCell] = useState(0);
  const previousTimeRef = useRef<number | undefined>();

  useAnimationFrame((t) => {
    if (previousTimeRef.current !== undefined) {
      const deltaTime = t - previousTimeRef.current;
      setTime(deltaTime);
    } else {
      previousTimeRef.current = t;
    }
  });

  useEffect(() => {
    const alpha = (time % speed) / speed;
    const frame = Math.floor(frames.length * alpha);
    const newAngle = (angle + rotation) % 360;
    setAngle(newAngle);
    setCell(frames[Math.floor(frame)]);
    setDirection(Math.floor((birdAngles * newAngle) / 360));
  }, [time, speed, rotation]);

  return (
    <div
      className={`Bird`}
      style={{
        top: `${50 + 100 * radius * Math.sin((2 * Math.PI * (180 + angle)) / 360)}%`,
        left: `${50 + 100 * radius * Math.cos((2 * Math.PI * (180 + angle)) / 360)}%`,
        width: `${size * 64}px`,
        height: `${size * 64}px`,
        backgroundImage: `url(${assetsPath}/gfx/birds.png)`,
        backgroundPositionX: `${(100 * direction) / 11}%`,
        backgroundPositionY: `${(100 * cell) / 3}%`,
        transformOrigin: `50% 50%`,
        transform: `translate(-50%, -50%) rotate(${angle % 30}deg)`,
        ...style,
      }}
    />
  );
};

const Flock: React.FC<{ count: number; style?: React.CSSProperties }> = ({ count, style }) => {
  const [birds, setBirds] = useState<React.ReactNode[]>([]);
  useEffect(() => {
    const tmp: React.ReactNode[] = [];
    for (let i = 0; i < count; i++) {
      const scalar = Math.random();
      tmp.push(<Bird speed={2000 + 250 * scalar} size={0.2 + scalar * 0.25} radius={0.1 + scalar * 0.35} key={i} />);
    }
    setBirds(tmp);
  }, [count]);
  return (
    <div className="Flock" style={style}>
      {birds}
    </div>
  );
};

export { Bird, Flock };
