import React, { useEffect, useRef, useState } from "react";
import "./GenresDisk.css";
import { fetchAudioUrl, getClipTitlesAndIDsByGenre } from "../utils/audioUtils";
import { capitalizeGenre } from "../utils/utils";

type GenreData = {
  genre: string;
  angle: number;
  radius: number;
  width: number;
  height: number;
  x: number;
  y: number;
  color: string;
};

type GenresDiskProps = {
  data: GenreData[];
  onGenreSelect: (genre: string, audioUrl: string, color: string) => void;
  selectedGenreName?: string;
  isPlaying?: boolean;
  onSwipeStart?: () => void;
};

const GenresDisk: React.FC<GenresDiskProps> = ({
  data,
  onGenreSelect,
  selectedGenreName,
  isPlaying,
  onSwipeStart,
}) => {
  const isMobileDevice = () => {
    return window.innerWidth <= 768;
  };

  // Need this to ensure animation does not pause when switching pages:
  const [animationKey, setAnimationKey] = useState(0);

  useEffect(() => {
    const restartAnimation = () => {
      setAnimationKey((prevKey) => prevKey + 1);
    };

    restartAnimation();

    const handleVisibilityChange = () => {
      if (document.visibilityState === "visible") {
        restartAnimation();
      }
    };

    document.addEventListener("visibilitychange", handleVisibilityChange);

    return () => {
      document.removeEventListener("visibilitychange", handleVisibilityChange);
    };
  }, [data]);
  //**************************************************************************

  const [hoveredGenre, setHoveredGenre] = useState<number | null>(null);

  const diskRef = useRef<HTMLDivElement | null>(null);

  const [rotation, setRotation] = useState(() => Math.random() * 360);

  const [audioURL, setAudioURL] = useState("");

  // const [startX, setStartX] = useState(0);
  // const [startY, setStartY] = useState(0);

  // const handleTouchStart = useCallback((e: any) => {
  //   if (!diskRef.current || !diskRef.current.contains(e.target)) {
  //     return;
  //   }
  //   setIsInteracting(true);

  //   // e.preventDefault();
  //   setStartX(e.touches[0].clientX);
  //   setStartY(e.touches[0].clientY);
  // }, []);

  // const handleTouchEnd = useCallback(
  //   (e: any) => {
  //     if (!diskRef.current || !diskRef.current.contains(e.target)) {
  //       return;
  //     }

  //     // e.preventDefault();
  //     const endX = e.changedTouches[0].clientX;
  //     const endY = e.changedTouches[0].clientY;
  //     const deltaX = endX - startX;
  //     const deltaY = endY - startY;
  //     const distance = Math.sqrt(deltaX ** 2 + deltaY ** 2);

  //     if (distance > 10) {
  //       e.preventDefault();
  //       setRotation((prevRotation) => (prevRotation + deltaX * 0.5) % 360);
  //     }

  //     if (onSwipeStart) {
  //       onSwipeStart();
  //     }
  //     setIsInteracting(false);
  //   },
  //   [startX, startY]
  // );

  // useEffect(() => {
  //   const handleTouchStartWrapper = (e: any) => handleTouchStart(e);
  //   const handleTouchEndWrapper = (e: any) => handleTouchEnd(e);

  //   window.addEventListener("touchstart", handleTouchStartWrapper, {
  //     passive: false,
  //   });
  //   window.addEventListener("touchend", handleTouchEndWrapper, {
  //     passive: false,
  //   });

  //   return () => {
  //     window.removeEventListener("touchstart", handleTouchStartWrapper);
  //     window.removeEventListener("touchend", handleTouchEndWrapper);
  //   };
  // }, [handleTouchStart, handleTouchEnd]);

  // ***************SCROLL EVENTS FOR DESKTOP AND ROTATION:***************
  const [isInteracting, setIsInteracting] = useState(false);

  useEffect(() => {
    if (isInteracting) {
      return;
    }

    const rotateInterval = setInterval(() => {
      const rotationIncrement = isMobileDevice() ? 0.4 : 0.3;
      setRotation((prevRotation) => (prevRotation + rotationIncrement) % 360);
    }, 500);

    return () => clearInterval(rotateInterval);
  }, [isInteracting]);

  useEffect(() => {
    const handleWheel = (event: any) => {
      // event.preventDefault();
      setIsInteracting(true);

      const scrollAmount = event.deltaY;
      const rotationChange = -scrollAmount * 0.1;

      setRotation((prevRotation) => {
        const newRotation = (prevRotation + rotationChange) % 360;
        return newRotation;
      });

      setTimeout(() => {
        setIsInteracting(false);
      }, 100);
    };

    window.addEventListener("wheel", handleWheel, { passive: false });

    return () => window.removeEventListener("wheel", handleWheel);
  }, []);

  useEffect(() => {
    if (diskRef.current) {
      diskRef.current.style.transform = `rotate(${rotation}deg)`;
    }
  }, [rotation]);

  // ***********************************************************************

  useEffect(() => {
    if (selectedGenreName) {
      setIsInteracting(true);

      const genreData = data.find(
        (item) => item.genre.toLowerCase() === selectedGenreName.toLowerCase()
      );
      if (genreData) {
        let targetRotation = 360 - genreData.angle;

        const currentRotationNormalized = ((rotation % 360) + 360) % 360;
        let rotationDifference = targetRotation - currentRotationNormalized;
        rotationDifference = ((rotationDifference + 540) % 360) - 180;

        targetRotation = currentRotationNormalized + rotationDifference;

        setRotation(targetRotation);

        setTimeout(() => {
          setIsInteracting(false);
        }, 1000);
      }
    }
  }, [selectedGenreName, data]);

  const handleGenreClick = async (genre: string, color: string) => {
    const clipTitlesAndIDsByGenre = getClipTitlesAndIDsByGenre();
    const normalizedGenre = genre.toLowerCase().trim();
    const clipsForGenre = clipTitlesAndIDsByGenre[normalizedGenre];

    if (clipsForGenre && clipsForGenre.length > 0) {
      const [firstSongTitle, firstClipId] = clipsForGenre[0];
      const firstSongUrl = await fetchAudioUrl(firstClipId);

      if (firstSongUrl) {
        const capitalizedGenre = capitalizeGenre(genre);
        onGenreSelect(capitalizedGenre, firstSongUrl, color);
        setAudioURL(firstSongUrl);

        // Comment back in for changing URL to include genre and song title:
        // const formattedGenre = genre.replace(/\s+/g, "_");
        // const formattedSongTitle = firstSongTitle?.replace(/\s+/g, "_");
        // const newHash = `${encodeURIComponent(
        //   formattedGenre
        // )}_${encodeURIComponent(formattedSongTitle as string)}`;
        // window.location.hash = `${newHash}`;
      } else {
        console.error(
          `Audio URL for clip ID ${firstClipId} could not be fetched.`
        );
      }
    } else {
      console.error(`No clips found for genre: ${genre}`);
    }
  };

  return (
    <div className="diskContainer">
      <div
        className="disk"
        key={animationKey}
        ref={diskRef}
        style={{
          transform: `rotate(${rotation}deg)`,
          // transform: `rotate(${specificRotation + continuousRotation}deg)`,
          transformOrigin: "center",
          transition: "transform 1s ease-out",
        }}
        tabIndex={0}
      >
        {data.map((item, index) => {
          const isHighlighted =
            selectedGenreName?.trim().toLowerCase() ===
            item.genre.trim().toLowerCase();

          return (
            <div
              key={index}
              className="genreItem"
              onClick={() => handleGenreClick(item.genre, item.color)}
              style={{
                position: "absolute",
                width: `${item.width + 90}px`,
                height: `${item.height}px`,
                transform: `translate(-50%, -50%) rotate(${item.angle}deg) translate(${item.radius}px)`,
                fontFamily: "PP Neue Montreal",
                textAlign: "center",
                cursor: "pointer",
                transition: "all 0.3s ease",
                fontSize: isHighlighted ? "18px" : "14px",
                lineHeight: `${item.height}px`,
                color: isHighlighted ? "white" : item.color,
                backgroundColor: isHighlighted ? item.color : "transparent",
                borderRadius: isHighlighted ? "20px" : "",
                padding: isHighlighted ? "5px" : "",
                zIndex: isHighlighted ? 10000 : 1,
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
              }}
              onMouseEnter={(e) => {
                if (
                  item.genre.trim().toLowerCase() !==
                  selectedGenreName?.trim().toLowerCase()
                ) {
                  e.currentTarget.style.fontSize = "18px";
                  e.currentTarget.style.backgroundColor = item.color;
                  e.currentTarget.style.borderRadius = "20px";
                  e.currentTarget.style.padding = "5px";
                  e.currentTarget.style.color = "white";
                  e.currentTarget.style.position = "absolute";
                  e.currentTarget.style.zIndex = "10000";
                  e.currentTarget.style.backgroundColor = item.color;
                  e.currentTarget.style.whiteSpace = "nowrap";
                  e.currentTarget.style.overflow = "hidden";
                  e.currentTarget.style.textOverflow = "ellipsis";
                }
              }}
              onMouseLeave={(e) => {
                if (
                  item.genre.trim().toLowerCase() !==
                  selectedGenreName?.trim().toLowerCase()
                ) {
                  e.currentTarget.style.backgroundColor = "transparent";
                  e.currentTarget.style.fontSize = "14px";
                  e.currentTarget.style.backgroundColor = "";
                  e.currentTarget.style.borderRadius = "";
                  e.currentTarget.style.padding = "";
                  e.currentTarget.style.color = item.color;
                  e.currentTarget.style.zIndex = "1";
                }
              }}
            >
              {isHighlighted && isPlaying && (
                <div style={{ marginRight: "12px" }}>
                  <svg
                    width="12"
                    height="13"
                    viewBox="0 0 12 13"
                    fill="none"
                    xmlns="http://www.w3.org/2000/svg"
                  >
                    <rect
                      className="bar bar1"
                      x="3.26929"
                      y="0.445496"
                      width="2"
                      height="12"
                      transform="rotate(-1.76 3.26929 0.445496)"
                      fill="white"
                    />
                    <rect
                      className="bar bar2"
                      x="6.41528"
                      y="5.15097"
                      width="2"
                      height="7.2"
                      transform="rotate(-1.76 6.41528 5.15097)"
                      fill="white"
                    />
                    <rect
                      className="bar bar3"
                      x="9.34033"
                      y="2.66003"
                      width="2"
                      height="9.6"
                      transform="rotate(-1.76 9.34033 2.66003)"
                      fill="white"
                    />
                    <rect
                      className="bar bar4"
                      x="0.528809"
                      y="8.93362"
                      width="2"
                      height="3.6"
                      transform="rotate(-1.76 0.528809 8.93362)"
                      fill="white"
                    />
                  </svg>
                </div>
              )}

              {item.genre}
            </div>
          );
        })}
      </div>
    </div>
  );
};

export default GenresDisk;
