import "./App.css";
import { useCallback, useEffect, useRef, useState } from "react";
import WaveForm from "./WaveForm";

const App = () => {
  const [audioUrl, setAudioUrl] = useState(),
    [analyzerData, setAnalyzerData] = useState(null),
    [bounce, setBounce] = useState(''),
    [json, setJson] = useState({}),
    [currentVolume, setCurrentVolume] = useState(0.5),
    [muted, setMuted] = useState(false),
    [link, setLink] = useState(''),
    [title, setTitle] = useState('Stream Radio'),
    [currentListeners, setCurrentListeners] = useState(0),
    [maxListeners, setMaxListeners] = useState(0),
    [playPause, setPlayPause] = useState(false),
    audioElmRef = useRef(null),
    once = useRef(false),
    audioAnalyzer = () => {
      const audioCtx = new (window.AudioContext || window.webkitAudioContext)(),
        analyzer = audioCtx.createAnalyser()
      analyzer.fftSize = 2048
      const bufferLength = analyzer.frequencyBinCount,
        dataArray = new Uint8Array(bufferLength),
        source = audioCtx.createMediaElementSource(audioElmRef.current)
      source.connect(analyzer)
      source.connect(audioCtx.destination)
      source.onended = () => {
        source.disconnect()
      }
      setAnalyzerData({ analyzer, bufferLength, dataArray })
    },
    play = () => {
      if (audioElmRef.current) {
        audioElmRef.current.play().then(() => {
          setPlayPause(true)
        }).catch(err => {
          console.error('Error playing audio: ' + err.message)
        })
      }
    },
    pause = () => {
      if (audioElmRef.current) {
        audioElmRef.current.pause().then(() => {
          setPlayPause(false)
        }).catch(err => {
          console.error('Error pausing audio: ' + err.message)
        })
      }
    },
    loadData = () => {
      fetch('/stream.json').then(response => response.json()).then(json => {
        setJson(json)
      }).catch(err => {
        console.error('Error fetching data: ' + err.message)
      })
    },
    loadListeners = () => {
      fetch('/status.xsl').then(response => response.text()).then(data => {
        const parser = new DOMParser(),
          xmlDoc = parser.parseFromString(data, 'text/html'),
          listeners = xmlDoc.getElementsByTagName('td')
        for (let i = 0; i < listeners.length; i++) {
          if (i === 9) {
            setCurrentListeners(listeners[i].textContent)
          } else if (i === 11) {
            setMaxListeners(listeners[i].textContent)
          }
        }
      }).catch(err => {
        console.error('Error fetching data: ' + err.message)
      })
    }
  useEffect(() => {
    if (json?.media?.track[0] && bounce.search(json?.media?.track[0].Title) === -1) {
      setBounce('Now Playing: ')
      setLink(json?.media['@ref']?.replace('/musica', 'https://manalejandro.com'))
      Object.keys(json.media.track[0]).map((key) => {
        if (key === 'Title' || key === 'Performer' || key === 'Album') {
          if (key === 'Title') {
            setTitle(json.media.track[0][key])
          }
          setBounce(data => data + json.media.track[0][key] + ' - ')
        } else if (key === 'Filesize') {
          setBounce(data => data + Math.round(parseInt(json.media.track[0][key]) / 1024 / 1024) + 'Mb - ')
        } else if (key === 'Bitrate') {
          setBounce(data => data + Math.floor(parseInt(json.media.track[0][key]) / 1000) + 'kbps - ')
        } else if (key === 'Duration') {
          setBounce(data => data + Math.floor(parseInt(json.media.track[0][key])) + 's - ')
        } else if (key === 'Recorded_Date') {
          setBounce(data => data + json.media.track[0][key])
        }
      })
    } else if (!json?.media && bounce.search('Now Playing: null') === -1) {
      setLink('#')
      setTitle('Stream Radio')
      setBounce('Now Playing: null')
    }
  }, [json])
  useEffect(() => {
    loadData()
    loadListeners()
    setAudioUrl('/stream.mp3')
    audioAnalyzer()
    const inter = setInterval(() => {
      loadData()
      loadListeners()
    }, (Math.floor(Math.random() * 20) + 10) * 1000)
    return () => clearInterval(inter)
  }, [])
  useEffect(() => {
    if (audioElmRef.current && audioElmRef.current.volume !== currentVolume && currentVolume >= 0 && currentVolume <= 1) {
      audioElmRef.current.volume = currentVolume
    }
  }, [currentVolume])
  return (
    <>
      <h1><a href="https://git.manalejandro.com/ale/stream-radio" title="Stream Radio Git Repository" alt="Stream Radio Git Repository" target="_blank">📻 Stream Radio</a></h1>
      {analyzerData && <WaveForm analyzerData={analyzerData} />}
      <h2>Current Listeners: {currentListeners} - Peak: {maxListeners}</h2>
      <h4><p className="bounce"><a href={link} target="_blank" title={title} alt={title}>{bounce}</a></p></h4>
      <div>
        <h2>Audio Controls</h2>
        {!playPause ?
          <button onClick={play}>Play ⏯️</button> :
          <button onClick={pause}>Pause ⏯️</button>
        }
        <br /><br />
        <button onClick={() => setCurrentVolume(currentVolume >= 0 && currentVolume <= 0.9 ? currentVolume + 0.1 : currentVolume)}>Volume Up 🔊</button>
        &nbsp;
        <button onClick={() => setCurrentVolume(currentVolume > 0.01 && currentVolume <= 1 ? currentVolume - 0.1 : currentVolume)}>Volume Down 🔈</button>
        <br /><br />
        <span>Volume: <b>{Math.round(currentVolume * 100)}%</b></span>
        <br /><br />
        {muted ?
          <button onClick={() => setMuted(false)}>Unmute 🔉</button> :
          <button onClick={() => setMuted(true)}>Mute 🔇</button>
        }
      </div>
      <audio src={audioUrl} controls={false} ref={audioElmRef} volume={currentVolume} preload={"none"} muted={muted} />
    </>
  )
}

export default App