import { useRef, useState, useEffect } from "@wordpress/element";
import ClockIcon from "../icons/Clock.jsx";
import PlayIcon from "../icons/Play.jsx";
import PauseIcon from "../icons/Pause.jsx";
import PlusIcon from "../icons/Plus.jsx";
import CrossIcon from "../icons/Cross.jsx";

const MusicSection = ({imgDir, musicDir, musics, setMusics, defaultMusics, sweetAlert, delay, updateDelay, uploaderNonce, isPreview}) => {
  const inputRefs = useRef([]);
  const [audioFiles, setAudioFiles] = useState([]);
  const audioRefs = useRef([]);
  

  const handleButtonClick = (index) => {
    let audio;
      if(wp.media){
          wp.media.view.Modal.prototype.on('close',function(){
              const existingModal = document.querySelector(".media-modal");
              if(existingModal){
                  existingModal.remove();
              }
          })
          audio = wp.media({
              title: "Upload Icon",
              multiple: false,
              library: {
                  type: 'audio'
              }
          }).open().on('select', function() {
              let uploaded_audio = audio.state().get('selection').first();
              let audio_url = uploaded_audio.toJSON().url;
              setMusics((prevMusics) => {
                  const updateMusics = [...prevMusics];
                  updateMusics[index] = [...defaultMusics, {"url": audio_url, "uploading": false, "selected": false, "playing": false, "title": uploaded_audio.toJSON().title}];

                  return updateMusics;
              });
          });
          audio.open();
      }
  };

  const updateLastMusic = (url, uploading, index, title="music") => {
    setMusics((prevMusics) => {
      const updatedMusics = [...prevMusics];
      updatedMusics[index] = [...defaultMusics, {"url": url, "uploading": uploading, "selected": false, "playing": false, "title": title}];
      return updatedMusics;
    })

  }

  const uploadToMedia = async (e, index) => {
    e.preventDefault();
    const file = e.dataTransfer ? e.dataTransfer.files[0] : e.target.files[0];
    const formData = new FormData();
    formData.append("nonce", uploaderNonce);
    formData.append("action", "tabrecall_upload_file");
    formData.append('type', 'audio');
    formData.append("file", file);

    try {
      const response = await fetch(ajaxurl, {
        method: "POST",
        body: formData,
      });
      const data = await response.json();
      if (data.success) {
        const fileInfo = data?.data ?? {};
        updateLastMusic(fileInfo?.url, false, index, fileInfo?.title ?? 'music');
        sweetAlert("The audio uploaded successfully!", "success");
      } else {
        updateLastMusic("", false, index);
        sweetAlert(`Error uploading file: ${data.data ?? "Please try again"}`, "error");
      }
    } catch (error) {
      alert("Error uploading file:", error);
      updateLastMusic("", false, index);
    }
  }

  const handleDragOver = (e) => {
    e.preventDefault();
    const dragDropText = e.currentTarget.querySelector(".tabrecall_text");
    dragDropText.textContent = "Drop here to upload";
  };

  const handleDragLeave = (e) => {
    e.preventDefault();
    // dropArea.querySelector(".dragDropText").textContent = "Upload 48×48 png";
    const dragDropText = e.currentTarget.querySelector(".tabrecall_text");
    dragDropText.textContent = "Upload .wav or .mp3";
  }

  const handleMusicUpload = (index, file) => {
    if (file) {
      const audioUrl = URL.createObjectURL(file);

      // ✅ Update audio file
      setAudioFiles((prev) => {
        const updated = [...prev];
        updated[index] = audioUrl;
        return updated;
      });
    }
  };


  const playAudio = (index) => {
    const audio = audioRefs.current[index];
    if (audio) {
      audio.pause(); // Stop any currently playing
      audio.currentTime = 0;
      audio.play();
    }
  };

  const handleAudioClick = (idx, index) => () => {
    setMusics((prev) => {
      const updated = [...prev];
      updated[index] = updated[index].map((icon, i) => ({
        ...icon,
        selected: i === idx,
        playing: false,
      }));
      return updated;
    });
  }

  const addMusicField = () => {
    setMusics((prev) => {
      const updated = [...prev];
      if (updated.length >= 3) {
        sweetAlert("You can only add 3 sound.", "error");
        return updated;
    }
      const newMusics = JSON.parse(JSON.stringify(defaultMusics));
      newMusics[0].selected = true;
      updated.push(newMusics);
      return updated;
    });
  }
  const handleAudioPlay = (idx, index) => () => {
    setMusics((prev) => {
      const updated = [...prev];
      updated[index] = updated[index].map((icon, i) => ({
        ...icon,
        playing: i === idx ? !icon.playing : false,
      }));
      return updated;
    });
    const audio = audioRefs.current[index];
    if (audio) {
      if (audio.paused) {
        audio.play();
      }
      else { 
        audio.pause();
        audio.currentTime = 0;
      }

      audio.addEventListener("ended", () => {
        setMusics((prev) => {
          const updated = [...prev];
          updated[index] = updated[index].map((icon, i) => ({
            ...icon,
            playing: i === idx ? false : icon.playing,
          }));
          return updated;
        });
      });
    }
  }

  useEffect(() => {
    const audioElements = audioRefs.current;
    const handleAudioEnd = (index) => {
      setMusics((prev) => {
        const updated = [...prev];
        updated[index] = updated[index].map((icon, i) => ({
          ...icon,
          playing: i === index ? false : icon.playing,
        }));
        return updated;
      });
    };
    
    const cleanupFunctions = [];
    audioElements.forEach((audio, index) => {
      if (audio) {
        audio.addEventListener("ended", () => handleAudioEnd(index));
        cleanupFunctions.push(() => {
          audio.removeEventListener("ended", () => handleAudioEnd(index));
        });
      }
    }

    );
    return () => {
      cleanupFunctions.forEach((cleanup) => cleanup());
    }
    
  }, [audioRefs.current]);

  return (
    <div className="container msg_container tabrecall_pb_24 tabrecall_mb_20">
      <div className="msg_header_container">
        <div className="msg_header">
          <h3 className="tabrecall_heading_1">Sound</h3>
          <div className="tabrecall_header_time">
            <ClockIcon />
            <p className="tabrecall_text">Delay (milliseconds)</p>
            <input
              type="number"
              className="tabrecall_text msg_header_input"
              onChange={updateDelay && ((e) => updateDelay("music", parseInt(e.target.value)))}
              readOnly={!updateDelay}
              value={delay}
              autoFocus
            />
          </div>
        </div>

        {/* Preview Icons */}
        <div className="music_preview_div">
          <h4 className="tabrecall_text">Preview</h4>
          {
            musics.map((musicGroup, index) => (
              musicGroup.map((music, idx) => (
                  music.selected && (
                        <div key={index} className="icon_preview_group" style={{position: "relative", '--title' : `"${music.title}"`}}>
                        {/* <img
                        key={idx}
                        src=
                        alt="icon"
                        style={{
                          height: "49px",
                          width: "49px",
                          borderRadius: "5px",
                          cursor: "pointer",
                        }}
                        onClick={handleAudioPlay(idx, index)}
                      /> */}
                      {
                        !music.playing ? <PlayIcon idx={idx} onClick={handleAudioPlay(idx, index)} /> : <PauseIcon  idx={idx} onClick={handleAudioPlay(idx, index)} />
                      }
                      <audio
                        // ref={(el) => (audioRefs.current[idx] = el)}
                        ref={(el) => (audioRefs.current[index] = el)}
                        src={music.url}
                      />
                      </div>
                      )
                ))
            ))
          }
        </div>
      </div>

      {musics.map((musicGroup, index) => (
        !isPreview && (
          <div className="parentMusicUploader" key={index}>
          <div className="musicUploadContainer">
            <div className="musicUploadItem" style={{ position: "relative" }}>
              <button
                type="button"
                onClick={() => handleButtonClick(index)}
                onDragOver={ (e) => handleDragOver(e) }
                onDragLeave={ (e) => handleDragLeave(e) }
                onDrop={(e) => uploadToMedia(e, index)} 
                className="musicUploadButton tabrecall_mb_24"
              >
                <p className="tabrecall_text">
                  {/* {musicGroup ? musicGroup : "Upload .wav or .mp3"} */}
                  Upload .wav or .mp3
                </p>
              </button>
              <input
                ref={(el) => (inputRefs.current[index] = el)}
                type="file"
                accept="audio/*"
                onChange={(e) => handleMusicUpload(index, e.target.files[0])}
                className="musicUploadInput"
              />
              {musics.length > 1 && (
                <button
                  type="button"
                  onClick={() => {
                    setMusics((prevIcons) => {
                      const updatedMusics = [...prevIcons];
                      updatedMusics.splice(index, 1);
                      return updatedMusics;
                    });
                  }}
                  className="crossButton"
                >
                  <CrossIcon />
                </button>
              )}
            </div>
          </div>
          <div className="uploadedIconContainer tabrecall_mb_24">
            <div className="uploadedIconText">
              <p className="tabrecall_text">or</p>
              <p className="tabrecall_text">Select</p>
            </div>
            <div className="uploadedIcons musicIcons">
              {musicGroup.map((musicIcon, idx) => {
                if(!musicIcon.url.length) return;

                return (
                  <div
                  key={idx}
                  style={{
                    '--title' : `"${musicIcon.title}"`,
                    position : 'relative',
                    cursor : 'pointer',
                  }}>
                    <PlayIcon idx={idx} onClick={handleAudioClick(idx, index)} className={musicIcon.selected ? "selected" : ""} />
                  </div>
                )
              })}
              {audioFiles.map((audioUrl, idx) => (
                <div key={idx} className="cursor-pointer">
                  <PlayIcon idx={idx} onClick={playAudio(idx)} />
                </div>
              ))}
            </div>
          </div>
        </div>
        )
      ))}

      {!isPreview && (
        <div style={{paddingBottom: "12px"}}>
        <button type="button" onClick={addMusicField} className="addMoreBtn" style={{
                    opacity: (musics.length >= 3) ? "0.8" : "1",
                    cursor: (musics.length >= 3) ? "not-allowed" : "pointer"
                }}>
          <PlusIcon />
          <p className="tabrecall_text tabrecall_text_primary">Add another sound</p>
        </button>
        <div className="tabrecall_note">
            <p>Note: You can show multiple musics which will change after {(delay/1000).toFixed(2)} sec</p>
        </div>
      </div>
      )}
    </div>
  );
};

export default MusicSection;
