'use client'

import { videos } from '@/utils/provide-videos-app'
import Image from 'next/image'

import { useEffect, useRef, useState } from 'react'
import { DialogErrorAcessWebcam } from '@/components/dialog-error-acess-webcam'
import { api } from '@/lib/axios'
import { useRouter } from 'next/navigation'
import { getRandomEmotion , verifyEmotions} from '@/utils/emotions'; // Ajuste o caminho conforme necessário

interface ParamsProps {
  params: {
    id: string
  }
}

interface PlayerState {
  playing: boolean
  percentage: number
}

interface PlayerFunctions {
  playerState: PlayerState
  playNextVideo: () => void
}

function usePlayerState(
  $videoPlayer: React.RefObject<HTMLVideoElement>,
): PlayerFunctions {
  const [playerState, setPlayerState] = useState<PlayerState>({
    playing: false,
    percentage: 0,
  })

  const [emotionsByVideo, setEmotionsByVideo] = useState<string[][]>([]);  

  useEffect(() => {

    if ($videoPlayer.current) {
      playerState.playing
        ? $videoPlayer.current.play()
        : $videoPlayer.current.pause()
    }
  }, [playerState.playing, $videoPlayer])



  function playNextVideo() {
    // Encontrar o índice do vídeo atual
    const currentSrc = $videoPlayer.current?.src
    const currentPath = currentSrc ? currentSrc.split('/videos/')[1] : null // Obtém o caminho relativo

    const currentIndex = videos.findIndex(
      (video) => currentPath && video.path.endsWith(currentPath),
    )

    console.log('Current Video Src:', currentSrc)
    console.log('Current Video Index:', currentIndex)

    // Calcular o próximo índice, considerando a repetição dos vídeos
    const nextIndex = (currentIndex + 1) % videos.length

    // Log para verificar o próximo índice e caminho do próximo vídeo
    console.log('Next Video Index:', nextIndex)
    console.log('Next Video Src:', videos[nextIndex].path)

    // Atualizar a fonte do vídeo para o próximo vídeo
    if ($videoPlayer.current) {
      $videoPlayer.current.src = videos[nextIndex].path
      $videoPlayer.current.load()
      setPlayerState({
        playing: true,
        percentage: 0,
      })
      if (nextIndex !=0) {
        $videoPlayer.current.play()
      }else{

        $videoPlayer.current.pause()
      }
    }
  }

  return { playerState, playNextVideo };
}

export default function Operator(props: ParamsProps) {
  const $videoPlayer = useRef<HTMLVideoElement>(null)
  const webcamVideoRef = useRef<HTMLVideoElement | null>(null)
  const [openDialogAcessWebcam, setOpenDialogAcessWebcam] = useState(false)
  const { id } = props.params
  const router = useRouter()

  async function getUserExists() {
    try {
      await api.get(`/users/${id}`)
    } catch (error) {
      router.push('/')
    }
  }


  async function gravaResult(favoriteVideoPos:string){
    try {

      const [emotion, userId] = [favoriteVideoPos, id];

      await api.post('/results', {
        emotion,
        userId
      }).then((response) => {
        const { id } = response.data
        router.push(`/result/${id}`)
      })
    } catch (error) {
      console.log(error);
      router.push('/')
    }
  }




  useEffect(() => {
    getUserExists()

    const accessWebcam = async () => {
      try {
        const stream = await navigator.mediaDevices.getUserMedia({
          video: true,
        })

        if (webcamVideoRef.current) {
          webcamVideoRef.current.srcObject = stream
        }

        setOpenDialogAcessWebcam(false)
      } catch (error) {
        console.error('Error accessing webcam:', error)
        setOpenDialogAcessWebcam(true)
      }
    }

    accessWebcam()

    return () => {
      const stream = webcamVideoRef.current?.srcObject as
        | MediaStream
        | undefined
      if (stream) {
        const tracks = stream.getTracks()
        tracks.forEach((track) => track.stop())
      }
    }
  }, [])

  const { playNextVideo } = usePlayerState($videoPlayer)

  //Armazena os Status do Vídeo (Primeira execução e Stop);
  const [firstPlay, setFirstPlay] = useState(true)
  

  //Emotions Array Geral
  const [emotionsByVideoArray, setEmotionsByVideoArray] = useState<string[]>([])
  const [emotionsArray, setEmotionsArray] = useState<string[][]>([])


  //Função para executar a cada n segundos 
  const [intervalRef, setIntervalRef] = useState<number | null | NodeJS.Timeout>(null);
  function updateEmotions() {
    //Pega no momento a imagem que está na webcam (se ela existir)

    if (webcamVideoRef.current) {
      const webcamVideo = webcamVideoRef.current
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');

      const endpoint = "https://api.skybiometry.com/fc/faces/detect.json";

      canvas.width = webcamVideo.videoWidth;
      canvas.height = webcamVideo.videoHeight;

      ctx.drawImage(webcamVideo, 0, 0, canvas.width, canvas.height);
      canvas.toBlob(async function (blob) {
        //Agora com o blob chama a API de Verificação de emotions;
        if (blob){

        const newEmotion = await verifyEmotions(blob)
        console.log(newEmotion);
        setEmotionsByVideoArray((prevEmotions) => [...prevEmotions, newEmotion])

        }
      }, 'image/jpeg');
    }

    // const newEmotion = getRandomEmotion() // ou a lógica que você utilizará para obter a emoção
    // console.log(newEmotion);
    // setEmotionsByVideoArray((prevEmotions) => [...prevEmotions, newEmotion])
  }

  const intervalFunction = () => {
    if (intervalRef !== null) {
      clearInterval(intervalRef)
    }
    const newIntervalRef = setInterval(()=>{
      updateEmotions()
    }, 2000) 
    setIntervalRef(newIntervalRef)
  }


  //Ação de Finalizar Videos 
  useEffect(() => {
    // Verifica se o array existe e se completou os 4 para garantir que viu os três vídeos
    if (emotionsArray.length >= 5) {
      // Pega os 4 primeiros elementos do array
      console.log(emotionsArray);

      const emotionElements = emotionsArray.slice(0, 5)
  
      // Função para contar o número de ocorrências de uma emoção específica em um elemento
      const countEmotion = (emotions: string[], targetEmotion: string) =>
        emotions.filter(e => e === targetEmotion).length
  
      // Função para comparar elementos com base nas regras fornecidas
      const compareElements = (a: string[], b: string[]) => {
        const countHappyA = countEmotion(a, 'happy')
        const countHappyB = countEmotion(b, 'happy')
   
        // Se o número de "happy" for diferente, ordena por esse número em ordem decrescente
        if (countHappyA !== countHappyB) {
          return countHappyB - countHappyA
        }
  
        // Em caso de empate, considera a hierarquia de outras emoções
        const otherEmotionsPriority = ['neutral', 'surprised', 'scared', 'sad', 'disgusted', 'angry']
  
        for (const emotion of otherEmotionsPriority) {
          const countA = countEmotion(a, emotion)
          const countB = countEmotion(b, emotion)
  
          if (countA !== countB) {
            return countB - countA;
          }
        }
  
        // Se ainda houver empate, considera o menor índice
        return emotionsArray.indexOf(a) - emotionsArray.indexOf(b)
      }
  
      // Ordena os elementos com base nas regras fornecidas
      const sortedElements = emotionElements.sort(compareElements)
  
      // Pega os índices dos quatro elementos
      const indices = sortedElements.map(element => emotionsArray.indexOf(element))

      const favoriteVideoPos = indices[0] + 1

      gravaResult(favoriteVideoPos.toString())
      
    }
  }, [emotionsArray]);



  useEffect(() => {
    const currentVideo = $videoPlayer.current

    if (currentVideo) {


       //handlerPlay
      const playHandler = () => {
      
        if (firstPlay===true) {
          // aqui vai a função com interval
           intervalFunction();
          // Atualize o estado para indicar que a função foi executada
          setFirstPlay(false);
        }
      };
      currentVideo.addEventListener('playing', playHandler);


      //handlerEnded
      const endedHandler = () => {
        //reseta a variável para o próximo Vídeo
        setFirstPlay(true);

        //reset oarray de emoçoes do Vídeo Atual e Coloca na Variável geral;
        setEmotionsArray((prevArray) => [...prevArray, emotionsByVideoArray]);
       
        // Encontrar o índice do vídeo atual
        const currentSrc = $videoPlayer.current?.src
        const currentPath = currentSrc ? currentSrc.split('/videos/')[1] : null // Obtém o caminho relativo

        const currentIndex = videos.findIndex(
          (video) => currentPath && video.path.endsWith(currentPath),
        )

        // Calcular o próximo índice, considerando a repetição dos vídeos
        const nextIndex = (currentIndex + 1) % videos.length

         //Se tiver proximos vídeos vai pro próximo e zera as emotions da vez
    
        if(nextIndex!=0){
          setEmotionsByVideoArray([]);
          playNextVideo()
        }
      
      }
      currentVideo.addEventListener('ended', endedHandler)

      //handlerPause
      const pausedHandler = () => {
        setFirstPlay(true);
        clearInterval(intervalRef);
      }
      currentVideo.addEventListener('pause', pausedHandler)

      //Clear
      return () => {
        currentVideo.removeEventListener('ended', endedHandler)
        currentVideo.removeEventListener('playing', playHandler);
        currentVideo.removeEventListener('pause', pausedHandler);
      }
    }
  }, [playNextVideo,updateEmotions])

  return (
    <main className="w-full h-screen flex flex-col items-center px-2">
      <Image
        className="w-28 mt-28"
        src='/totalenergies-logo.png'
        alt="Total Energies Brasil"
        width={120}
        height={82}
      />

      <div className="mt-20 w-[740px] h-[460px]">
        <video
          ref={$videoPlayer}
          src={videos[0].path}
          controls
          className="shadow-2xl"
          width="100%"
          height="auto"
        />
      </div>

      <div className="mt-20 w-[400px] h-[300px] absolute top-0 left-3 ">
        <video
          autoPlay
          ref={webcamVideoRef}
          className="shadow-2xl"
          width="100%"
          height="auto"
          id = "webcam"
        />
      </div>

      <DialogErrorAcessWebcam open={openDialogAcessWebcam} />
    </main>
  )
}
