import React, { useState, useEffect, useRef } from "react";
import API_BASE_URL from "../config.js";
import "./MusicPlayer.css";
import MusicComponent from "./MusicComponent";

export function MusicPlayer({ socket, shopId, user, shopOwnerId, isSpotifyNeedLogin, queue }) {
  const [currentTime, setCurrentTime] = useState(0);
  const [trackLength, setTrackLength] = useState(0);
  const [viewing, setViewing] = useState(false); // State for expansion
  const [expanded, setExpanded] = useState(false); // State for expansion

  const [songName, setSongName] = useState("");
  const [debouncedSongName, setDebouncedSongName] = useState(songName);
  const [currentSong, setCurrentSong] = useState([]);
  const [songs, setSongs] = useState([]);
  const [paused, setPaused] = useState([]);

  const [lyrics, setLyrics] = useState([]);
  const [currentLines, setCurrentLines] = useState({
    past: [],
    present: [],
    future: [],
  });
  const [lyric_progress_ms, setLyricProgressMs] = useState(0);

  const [subtitleColor, setSubtitleColor] = useState("black");
  const [subtitleBG, setSubtitleBG] = useState("white");
  const [backgroundImage, setBackgroundImage] = useState("");

  const [clicked, setClicked] = useState(false);


  const [canvaz, setCanvaz] = useState('');
  const [videoSrc, setVideoSrc] = useState('');
  const videoRef = useRef(null);
  const inputRef = useRef(null); // Create a ref to the input field



  useEffect(() => {
    const getDominantColor = async (imageSrc) => {
      return new Promise((resolve, reject) => {
        const img = new Image();
        img.crossOrigin = "Anonymous";
        img.src = imageSrc;

        img.onload = () => {
          const canvas = document.createElement("canvas");
          const ctx = canvas.getContext("2d");

          canvas.width = img.width;
          canvas.height = img.height;
          ctx.drawImage(img, 0, 0);

          const imageData = ctx.getImageData(
            0,
            0,
            canvas.width,
            canvas.height,
          ).data;
          const length = imageData.length;
          let totalR = 0,
            totalG = 0,
            totalB = 0;

          for (let i = 0; i < length; i += 4) {
            totalR += imageData[i];
            totalG += imageData[i + 1];
            totalB += imageData[i + 2];
          }

          const averageR = Math.round(totalR / (length / 4));
          const averageG = Math.round(totalG / (length / 4));
          const averageB = Math.round(totalB / (length / 4));

          resolve({ r: averageR, g: averageG, b: averageB });
        };

        img.onerror = (error) => {
          reject(error);
        };
      });
    };

    const fetchColor = async () => {
      if (
        currentSong &&
        currentSong.image
      ) {
        const imageUrl = currentSong.image;
        try {
          const dominantColor = await getDominantColor(imageUrl);
          // Calculate luminance (YIQ color space) to determine if subtitle should be black or white
          const luminance =
            (0.299 * dominantColor.r +
              0.587 * dominantColor.g +
              0.114 * dominantColor.b) /
            255;
          if (luminance > 0.5) {
            setSubtitleColor("black");
            setSubtitleBG("white");
          } else {
            setSubtitleColor("white");
            setSubtitleBG("black");
          }
          setBackgroundImage(imageUrl);
        } catch (error) {
          console.error("Error fetching or processing image:", error);
        }
      }
    };

    fetchColor();
  }, [currentSong]);

  const convertToMilliseconds = (timeStr) => {
    const [minutes, seconds] = timeStr.split(':').map(Number);
    return (minutes * 60 + seconds) * 1000;
  };

  useEffect(() => {
    if (!socket) return;

    socket.on("searchResponse", (response) => {
      console.log(response);
      setSongs(response);
    });

    socket.on("updateCurrentSong", (response) => {
      console.log(response)
      setCurrentSong(response);
      // setCurrentTime(response.progress_ms / 1000); // Convert milliseconds to seconds
      // setLyricProgressMs(response.progress_ms);
      // setTrackLength(convertToMilliseconds(response.item.length));
    });


    socket.on("updatePlayer", (response) => {
      setPaused(response.decision);
    });

    socket.on("updateLyrics", (response) => {
      setLyrics(response);
      console.log(response);
      setCurrentLines({
        past: [],
        present: [],
        future: [],
      });
    });

    return () => {
      socket.off("searchResponse");
    };
  }, [socket]);

  // useEffect for setting up the socket listener
  useEffect(() => {
    const handleUpdateCanvas = (response) => {
      if (response && response !== canvaz) {
        console.log(response);
        console.log(canvaz);
        setCanvaz(response);
        fetch(response)
          .then((response) => response.blob())
          .then((blob) => {
            const blobUrl = URL.createObjectURL(blob);
            setVideoSrc(blobUrl);

            if (videoRef.current) {
              videoRef.current.load(); // Reload the video element
            }
          })
          .catch((error) => console.error('Error loading video:', error));
      } else if (!response) {
        // Clear the video source if response is empty
        setVideoSrc('');
        if (videoRef.current) {
          videoRef.current.load(); // Reload the video element
        }
      }
    };

    // Listen for the "updateCanvas" event
    socket.on("updateCanvas", handleUpdateCanvas);

    socket.on("claimPlayerRes", (response) => {
      if (response.error) {
        console.log('Error:', response.error);
        // Handle error
      } else {
        window.open(response.url);
      }
    });

    socket.on("unClaimPlayerRes", (response) => {
      if (response.error) {
        console.log('Error:', response.error);
        // Handle error
      } else {
        console.log('Player token:', response.token);
        // Handle success and use the player token
      }
    });

    // Clean up the socket listener when the component is unmounted
    return () => {
      socket.off("updateCanvas", handleUpdateCanvas);
    };
  }, [socket, canvaz]);

  useEffect(() => {
    // Simulate progress every 100ms
    const interval = setInterval(() => {
      setLyricProgressMs((prevProgress) => prevProgress + 100);
    }, 100);

    return () => clearInterval(interval); // Clean up interval on component unmount
  }, []);

  useEffect(() => {
    if (lyrics == null) return;
    const pastLines = lyrics.filter(
      (line) => line.startTimeMs < lyric_progress_ms,
    );
    const presentLines = lyrics.filter(
      (line) => line.startTimeMs > lyric_progress_ms,
    );
    const futureLines = lyrics.filter(
      (line) => line.startTimeMs > lyric_progress_ms,
    );

    setCurrentLines({
      past: pastLines.slice(-2, 1), // Get the last past line
      present: pastLines.slice(-1),
      future: futureLines.slice(0, 1), // Get the first future line
    });
  }, [lyrics, lyric_progress_ms]);

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedSongName(songName);
    }, 300);

    // Cleanup function to clear the timeout if songName changes
    return () => {
      clearTimeout(handler);
    };
  }, [songName]);

  useEffect(() => {
    if (socket != null && debouncedSongName) {
      socket.emit("searchRequest", { shopId, songName: debouncedSongName });
    }
  }, [debouncedSongName, shopId, socket]);

  const handleInputChange = (event) => {
    setSongName(event.target.value);
  };

  const onRequest = (track) => {
    const token = localStorage.getItem("auth");
    if (socket != null && token) {
      socket.emit("songRequest", { token, shopId, track });
      setSongName("");
    }
  };

  const onDecision = (trackId, vote) => {
    const token = localStorage.getItem("auth");
    if (socket != null && token)
      socket.emit("songVote", { token, shopId, trackId, vote });
  };

  const handlePauseOrResume = (trackId, vote) => {
    const token = localStorage.getItem("auth");
    if (socket != null && token) {
      socket.emit("playOrPause", {
        token,
        shopId,
        action: paused ? "pause" : "resume",
      });
      console.log(paused);
      setPaused(!paused);
    }
  };

  const handleSetPlayer = () => {
    const token = localStorage.getItem("auth");

    socket.emit("claimPlayer", {
      token,
      shopId,
    });
    if (isSpotifyNeedLogin) {
    } else {
      // socket.emit("unClaimPlayer", {
      //   token,
      //   shopId,
      // });
    }
  };

  useEffect(() => {
    const interval = setInterval(() => {
      setCurrentTime((prevTime) =>
        prevTime < trackLength ? prevTime + 1 : prevTime,
      );
    }, 1000);

    return () => clearInterval(interval);
  }, [trackLength]);

  const formatTime = (timeInSeconds) => {
    const minutes = Math.floor(timeInSeconds / 60);
    const seconds = Math.floor(timeInSeconds % 60);

    // Ensure seconds and milliseconds are always displayed with two and three digits respectively
    const formattedSeconds = seconds < 10 ? `0${seconds}` : `${seconds}`;

    return `${minutes}:${formattedSeconds}`;
  };

  const toggleView = () => {
    setViewing(!viewing);
  };
  const toggleExpand = () => {
    setExpanded(!expanded);
  };

  const expandableContainerRef = useRef(null);

  useEffect(() => {
    if (expanded && expandableContainerRef.current) {
      expandableContainerRef.current.scrollTo({ top: 0, behavior: "smooth" });
    }
  }, [expanded]);


  const [text, setText] = useState("Menunggu musik favoritmu");
  const textIndex = useRef(0);
  const [messages, setMessages] = useState(["Menunggu musik favoritmu", "Klik untuk putar musik favoritmu"]);


  useEffect(() => {
    // Update the messages based on currentSong
    const newMessages = [
      currentSong != null && currentSong != undefined
        ? `${currentSong.name} - ${currentSong.artist}`
        : "Menunggu musik favoritmu",
      "Klik untuk putar musik favoritmu"
    ];

    setMessages(newMessages);
    setText(newMessages[0]); // Update the text state to the first message

    const element = document.querySelector('.animated-text');

    // Check if the element exists before adding the event listener
    if (element) {
      const handleAnimationIteration = () => {
        // Toggle between the two text values based on the current index
        textIndex.current = (textIndex.current + 1) % messages.length;
        setText(messages[textIndex.current]);
      };

      element.addEventListener('animationiteration', handleAnimationIteration);

      return () => {
        element.removeEventListener('animationiteration', handleAnimationIteration);
      };
    }
  }, [currentSong]); // Run effect when currentSong changes

  const handleButtonClick = () => {
    setClicked(true);

    if (inputRef.current) {
      inputRef.current.focus(); // Focus the input when the button is clicked
    }

    // After 1 second, remove the "clicked" class to let the color gradually return to the original
    setTimeout(() => {
      setClicked(false);
    }, 1000); // 1 second timeout (same as the CSS transition duration)
  };

  function modifyUrl(url) {
    // Use a regular expression to find the part of the URL that starts with '='
    return url.replace(/=(w\d+)-(h\d+)-/, '=w255-h255-');
}
  
  return (
    <div className={`music-player`} style={{ marginBottom: `${viewing ? '-10px' : ''}` }}>
      <div
        onClick={toggleView}
        className="current-bgr"
        style={{ backgroundImage: `url(${modifyUrl(backgroundImage)})` }}
      // style={{ backgroundImage: `url(${videoSrc != "" ? '' : backgroundImage})` }}
      >
        {/* <video
          ref={videoRef}
          autoPlay
          loop
          playsInline
          muted
          style={{ height: '100%', width: '100%', objectFit: 'cover', position: 'absolute', top: 0, right: 0, zIndex: -1 }}
        >
          {videoSrc && <source src={videoSrc} type="video/mp4" />}
        </video> */}
        {currentLines.present.map((line, index) => (
          <div className="present" style={{
            color: subtitleColor,
            textShadow: `2px 2px 2px ${subtitleBG}`,
          }} key={index}>
            <p>{line.words}</p>
          </div>
        ))}
        {currentLines.future.map((line, index) => (
          <div className="future" style={{
            color: subtitleColor,
            textShadow: `2px 2px 2px ${subtitleBG}`,
          }} key={index}>
            <p>{line.words}</p>
          </div>
        ))}
      </div>

      <div className="current-info" >
        <div
          className={`current-name ${viewing ? '' : 'animated-text'}`} style={{ margin: `${viewing ? '35px 30px' : '13px 30px'}` }}>
          {currentSong && currentSong.name
            ? (viewing ? currentSong.name : text)
            :
            viewing ? messages[0] : text}
        </div>
        {viewing && <>
          <div className="current-artist">
            {
              currentSong &&
                currentSong.image &&
                currentSong.artist
                ? currentSong.artist
                : "Pilih hits terbaikmu dibawah!"}
          </div>
        </>
        }
      </div>
      {viewing &&
        <>
          <div
            className={`expandable-container ${expanded ? "expanded" : ""}`}
            ref={expandableContainerRef}
          >
            {user.cafeId == shopId || user.userId == shopOwnerId && (
              <div className="auth-box">
                <input
                  type="text"
                  placeholder={
                    isSpotifyNeedLogin ? "Jadikan perangkat sebagai pemutar musik" : "Unset as music player"
                  }
                  onClick={handleSetPlayer}
                />
              </div>
            )}
            <div className="search-box">
              <input
                ref={inputRef}
                type="text"
                placeholder="Cari musik..."
                value={songName}
                onChange={handleInputChange}
                className={clicked ? 'clicked' : ''}
              />
            </div>


            <div
              className="rectangle"
              style={{
                justifyContent: songName === "" && queue && queue.length > 0 && queue.length < 3 || songName != '' ? 'flex-start' : 'center'
              }}
            >
              {songName == "" && queue && queue.length < 1 && (
                <div className="middle-text">
                  <span className="bold-text">Antrian kosong</span><br />
                  <span className="normal-text">Pilih musikmu</span>
                  <button
                    className={`search-button ${clicked ? 'clicked' : ''}`}
                    onClick={handleButtonClick}
                  >
                    Cari musik
                  </button>
                </div>
              )}
              {songName != "" &&
                songs.map((song, index) => (
                  <MusicComponent
                    key={index}
                    song={song}
                    min={0}
                    max={100}
                    onDecision={(e) => onRequest(song)}
                  />
                ))}
              {
                songName === "" &&
                queue &&
                Array.isArray(queue) &&
                queue.length > 0 && (
                  queue.map((song, index) => (
                    <MusicComponent
                      key={index}
                      song={song}
                      min={-100}
                      max={100}
                      onDecision={(vote) => onDecision(song.trackId, vote)}
                    />
                  ))
                )
              }
              {songName == "" && queue && queue.length > 0 && queue.length < 3 && (

                <div className="middle-text">
                  <span className="normal-text">Tambahkan musikmu</span>
                  <button
                    className={`search-button ${clicked ? 'clicked' : ''}`}
                    onClick={handleButtonClick}
                  >
                    Cari musik
                  </button>
                </div>
              )}
            </div>




          </div>
          <div className={`expand-button ${expanded ? "expanded" : ""}`} onClick={toggleExpand}>

            <h5>
              {expanded ? '⋀' : 'Lihat antrian musik'}
            </h5>
          </div></>
      }
    </div >
  );
}
