import { useState, useEffect, useRef } from "react";
import {Howl, Howler} from 'howler';
import { invoke } from "@tauri-apps/api/core";
import "./App.css";


const DefaultFadeDuration = 3; // 1 second

const CueType={
    Bg: 'bg',
    Announce: 'announce',
    Light: 'light'
}
const EmojiType={
    bg: '🎵', 
    announce: '📢',
    light: '💡'
}

function App() {
  
  const [cuelist, setCuelist] = useState([]);
  const refAudioBg= useRef(null);
  const refAudioAnnounce= useRef(null);
  const refAudio= useRef({});
  const [currentCue, setCurrentCue] = useState(null);
  const [fadeDuration, setFadeDuration] = useState(DefaultFadeDuration); // Default fade duration in seconds
  const [timestamp, setTimestamp] = useState();

  const refCue = useRef(null);
  const refNextCue = useRef(null);


  function sendOsc(addr, message){

    invoke('send_osc_message', {
          key: addr,
          message,
          host:'0.0.0.0:0',
          target:'192.168.234.255:8000',
    });

  }
  function onfade(e){
    console.log('onfade', e);

    if(refNextCue.current) {
      playCue(refNextCue.current);
      refNextCue.current = null;
    }

    if(refAudioBg.current.volume() === 0) {
      refAudioBg.current.stop();
      // refAudioBg.current = null;
    }

  }
  function onAnounceFade(e){
    console.log('onAnounceFade', e);
    if(refAudioAnnounce.current.volume() === 0) {
      refAudioAnnounce.current.stop();
    }

  }

  function loadAudio(audioFile, loop = false, type) {
    if(refAudio.current[audioFile]) {
      return refAudio.current[audioFile];
    }
    const sound = new Howl({
      src: [audioFile],
      volume: 1,
      loop: loop,
      onfade: type==CueType.Bg ? onfade : onAnounceFade,
    });
    refAudio.current[audioFile] = sound;
    return sound;
  }
  
  function playAudio(audioFile, loop = false, type) {
    switch(type){
      case CueType.Bg:
        refAudioBg.current = loadAudio(audioFile, loop, type);        
        refAudioBg.current.play();
        refAudioBg.current.fade(0, 1, fadeDuration * 1000);
        break;
      case CueType.Announce:
        refAudioAnnounce.current = loadAudio(audioFile, loop, type);               
        refAudioAnnounce.current.seek(0); 
        refAudioAnnounce.current.volume(1);
        refAudioAnnounce.current.play();
        break;
    }
  }
 
  function playCue({id, name, description, type, auto, audioFile, ...props}) {
      
    console.log('Playing cue:', {id, name, description, type, auto, audioFile, ...props});
      
      // Handle other cue types and properties here
      switch(type) {
          case CueType.Bg:
              if(refAudioBg.current) {
                  if(refAudioBg.current.volume() === 0) {
                      refAudioBg.current.stop();
                      playAudio(audioFile, props.loop || false, type);
                      setCurrentCue({id, name, description, type, auto, audioFile, ...props});
                  }else{
                    refAudioBg.current.fade(1,0, fadeDuration * 1000);
                    refNextCue.current = {id, name, description, type, auto, audioFile, ...props};                    
                  }
              }else{
                playAudio(audioFile, props.loop || false, type);
                setCurrentCue({id, name, description, type, auto, audioFile, ...props});
              }
              break;

          case CueType.Announce:
              
              playAudio(audioFile, props.loop || false, type);
              setCurrentCue({id, name, description, type, auto, audioFile, ...props});
              
              
              break;

          case CueType.Light:
              // Handle light cue logic here
              console.log('Light cue:', {id, name, description, ...props});
              setCurrentCue({id, name, description, type, auto, audioFile, ...props});
              break;

          default:
              console.warn('Unknown cue type:', type);

      }

      if(props.clientCue){
        sendOsc('/playcue', props.clientCue);
      }


  }
  function stop() {
    console.log('Stop all audio');
    if(refAudioBg.current) {
        refAudioBg.current.fade(1,0, fadeDuration*1000);            
    }
    if(refAudioAnnounce.current) {
        refAudioAnnounce.current.fade(1,0, fadeDuration*1000);
    }

    sendOsc('/stopcue','');

  }
  function secondToTime(seconds) {
    const minutes = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    return `${minutes}:${secs < 10 ? '0' : ''}${secs}`;
  }
  function getAudioDuration(){

    const type= refCue.current?.type;
    // console.log('getAudioDuration', type, refCue.current);
    // switch(type) {
    //   case CueType.Bg:
    if(refAudioBg.current) {
      return `${secondToTime(refAudioBg.current.seek())} / ${secondToTime(refAudioBg.current.duration())} ${refAudioBg.current?.volume()}`;
    } else {
        return 'N/A';
    }
    //   case CueType.Announce:
    //     return refAudioAnnounce.current ? `${secondToTime(refAudioAnnounce.current.seek())} / ${secondToTime(refAudioAnnounce.current.duration())}` : 'N/A';
    //   default:
    //     return 'N/A';
    // }


  }
  useEffect(()=>{
    if(currentCue) {
      refCue.current = currentCue;
      // console.log('Current Cue:', currentCue);
    }
  },[currentCue]);
  useEffect(()=>{
      fetch('/cuelist.json')
          .then(response => response.json())
          .then(data => {
              console.log('Cuelist data:', data);
              setCuelist(data.cuelist);
          })
          .catch(error => {
              console.error('Error fetching cuelist:', error);
          });

      const intervalId = setInterval(() => {
          setTimestamp(getAudioDuration());
      }, 500);
      return () => clearInterval(intervalId);

  },[]);

  return (
    <main className="container">
        <div className="overflow-y-auto flex flex-col gap-8 p-4">
          <section className="flex flex-row gap-4 justify-between items-center">            
            <div className="text-6xl p-4 bg-pink-300">{currentCue ? `${currentCue.name}` : 'None'}</div>  
            <p>
              {timestamp}
            </p>
            <button onClick={stop}>stop all</button>
            <span className="flex flex-col gap-2 items-stretch">
              <label htmlFor="fade_duration">Fade Duration</label>
              <input type="range" id="fade_duration" min="0" max="30" step="0.1" defaultValue={DefaultFadeDuration} className="slider"
                onChange={(e) => {
                    const value = parseFloat(e.target.value);
                    setFadeDuration(value);
                }}></input>
              <span className="text-2xl">{fadeDuration}s</span>
            </span>
          </section>
          <table className="border-collapse w-full **:p-2 border-green-500 border-4">
              <thead className="bg-green-500">
                  <tr className="text-left lowercase font-[900]">
                      {/* <th>ID</th> */}
                      <th></th>
                      <th>Name</th>
                      <th>Description</th>
                      <th>Type</th>
                      <th>Auto</th>
                      <th>Audio / Due</th>
                      <th>clientCue</th>
                  </tr>
              </thead>
              <tbody>
                  {cuelist?.map(({id, name, description, type, auto, audioFile,...props}, index) => (
                      <tr key={id} className={currentCue?.id === id ? 'bg-green-200' : ''}>
                          <td className="flex flex-row gap-2">
                              <button
                                  onClick={()=>{
                                      playCue({id, name, description, type, auto, audioFile, ...props});
                                  }}>go</button>                          
                              {type==CueType.Announce && <button
                                  onClick={()=>{
                                      if(refAudioAnnounce.current) {
                                        refAudioAnnounce.current.fade(1,0, fadeDuration * 1000);
                                      }
                                  }}>stop</button>}
                          </td>
                          <td>{name}</td>
                          <td>{description}</td>
                          <td>{EmojiType[type]}</td>
                          <td>{auto ? '⤵️' : ''}</td>
                          <td>{audioFile || props.duration} {props.callback && `<${props.callback}>`}</td>
                          <td className={`${props.clientCue&& 'bg-green-300 rounded-full text-center font-[900]'}`}>{props.clientCue || ''}</td>
                      </tr>
                  ))}
              </tbody>
          </table>
      </div>
    </main>
  );
}

export default App;
