'use client'
import { useState, useEffect, useRef } from 'react'
import { io } from "socket.io-client"
import { getRandomQuestion } from "./questions"
import { useForceUpdate } from "./forceUpdate"
import { IconCrown } from "@tabler/icons-react"
import { defaultAvatarImage } from '../avatarImage'

interface roomProps {
  params: {
    id: string;
  };
}

export default function Home({ params }: roomProps) {
  const [isConnected, setIsConnected] = useState(false)
  const [forceUpdate, setForceUpdate] = useState(0)

  const [role, setRole] = useState("")
  const [name, setName] = useState("")
  const [avatar, setAvatar] = useState(defaultAvatarImage)

  const [gameStarted, setGameStarted] = useState(false)
  const [gameEnded, setGameEnded] = useState(false)
  const [questionDisplayed, setQuestionDisplayed] = useState("")
  const [possibleChoice, setPossibleChoice] = useState([])
  const [totalVotes, setTotalVotes] = useState(0)
  const [choice, setChoice] = useState("")
  const [countdown, setCountdown] = useState(0)
  const [players, setPlayers] = useState([])
  const [questionNbr, setQuestionNbr] = useState(0)
  const [questionAlreadyDone, setQuestionAlreadyDone] = useState([])

  const socketRef = useRef()
  const duration = 15
  const questionLimit = 10

  const { id } = params
  const roomNameDisplay = id.substring(0,3) + " " + id.substring(3,6)

  useEffect(() => {
        const localName = localStorage.getItem('name')
        setName(localName)
        const localAvatar = localStorage.getItem('avatar')
        setAvatar(localAvatar)
        // Listen for incoming setMessages
        socketRef.current = io("ws://localhost:3000");

        socketRef.current.on("connect", () => {
          setIsConnected(true)
          socketRef.current.emit('room_connect', {id: id, name: localName, avatar: localAvatar})
        });

        socketRef.current.on("new_player", (params) => {
          setPlayers(oldPlayers => [...oldPlayers, params])
        })

        socketRef.current.on("start_game", (params) => {
          setQuestionNbr(oldQ => oldQ + 1)
          setGameStarted(true)
          setQuestionDisplayed(params.question)
          setPossibleChoice(params.possibleChoice)
          setCountdown(params.duration)
        })

        socketRef.current.on("next_question", (params) => {
          setQuestionNbr(oldQ => oldQ + 1)
          setChoice("")
          setQuestionDisplayed(params.question)
          setPossibleChoice(params.possibleChoice)
          setCountdown(params.duration)
          setTotalVotes(0)
        })

        socketRef.current.on("reset_game", (params) => {
          setGameStarted(false)
          setCountdown(0)
          setPossibleChoice([])
          setQuestionDisplayed("")
          setChoice("")
          setQuestionNbr(0)
          setTotalVotes(0)
        })

        socketRef.current.on("room_joined", (params) => {
          setPlayers(params.room_users)
          setRole(params.role)
        })

        // Clean up the socket connection on unmount
        return () => {
            socketRef.current.disconnect();
        };
    }, []);

  function forceUpdateFunc(){
    setForceUpdate(fu => fu + 1)
  }

  useEffect(() => {
        const eventListener = (params) => {
          setTotalVotes(oldTotal => oldTotal += 1)
          console.log(params)
          let temp_possibleChoice = possibleChoice
          temp_possibleChoice.forEach((playerChoice) => {
            if(playerChoice.name == params.choice) {
              playerChoice.nbrVotes += 1
            }
          })
          forceUpdateFunc()
        };
        socketRef.current.on("player_choice", eventListener)
        return () => socketRef.current.off("player_choice", eventListener)
  }, [possibleChoice])

  useEffect(() => {
    countdown > 0 && setTimeout(() => setCountdown(countdown - 1), 1000);
  }, [countdown]);

  function getPossibleChoice() {
    let choice1 = Math.floor(Math.random() * players.length)
    console.log(players.length)
    let choice2 = Math.floor(Math.random() * players.length)
    console.log(choice2)
    while(choice2 == choice1){
      choice2 = Math.floor(Math.random() * players.length)
    }
    let playerChoice1 = players[choice1]
    playerChoice1.nbrVotes = 0
    let playerChoice2 = players[choice2]
    playerChoice2.nbrVotes = 0
    return [playerChoice1, playerChoice2]
  }

  function startGame() {
    let possibleChoice = getPossibleChoice()
    let questionObj = getRandomQuestion()
    let question = questionObj.question
    setQuestionAlreadyDone(questionObj.alreadyDone)
    socketRef.current.emit("start_game", {roomId: id, question: question, possibleChoice: possibleChoice, duration: duration})
    setCountdown(duration)
    setPossibleChoice(possibleChoice)
    setQuestionDisplayed(question)
    setGameStarted(true)
    setQuestionNbr(oldQ => oldQ + 1)
  }

  function nextQuestion() {
    let possibleChoice = getPossibleChoice()
    let questionObj = getRandomQuestion(questionAlreadyDone)
    let question = questionObj.question
    setQuestionAlreadyDone(questionObj.alreadyDone)
    socketRef.current.emit("next_question", {roomId: id, question: question, possibleChoice: possibleChoice, duration: duration})
    setCountdown(duration)
    setPossibleChoice(possibleChoice)
    setQuestionDisplayed(question)
    setChoice("")
    setQuestionNbr(oldQ => oldQ + 1)
    setTotalVotes(0)
  }

  function resetGame() {
    socketRef.current.emit("reset_game", {roomId: id})
    setGameStarted(false)
    setCountdown(0)
    setPossibleChoice([])
    setQuestionDisplayed("")
    setChoice("")
    setQuestionNbr(0)
    setTotalVotes(0)
  }

  function setAndSendChoice(playerName) {
    setChoice(playerName)
    setTotalVotes(oldTotal => oldTotal += 1)
    let temp_possibleChoice = possibleChoice
    temp_possibleChoice.forEach((playerChoice) => {
      if(playerChoice.name == playerName) {
        playerChoice.nbrVotes += 1
      }
    })
    setPossibleChoice(temp_possibleChoice)
    socketRef.current.emit("player_choice", {roomId: id, choice: playerName, player: name})
  }

  return (
    <main className="flex min-h-screen flex-col items-center space-y-16 p-4">
      { !gameStarted && 
        <>
          <div className="flex flex-col">
            <h1 className="text-3xl">{roomNameDisplay}</h1>
          </div>
          <div className="flex flex-col space-y-4">
            { !isConnected &&
              <p>Connecting to room...</p>
            }
            { (isConnected && players.length == 0) &&
              <p>Waiting for players to join...</p>
            }
            { (isConnected && players.length > 0) &&
              <div className="flex flex-col space-y-16">
                <div className="grid grid-cols-3 gap-4">
                  { players.map((player) => {
                    return (
                      <>
                        <div className="flex flex-col items-center">
                          <div className="avatar indicator">
                            {player.role == "owner" && <IconCrown className="indicator-item" />}
                            <div className="w-16 rounded">
                              <img src={player.avatar} />
                            </div>
                          </div>
                          <p className="flex flex-row">{player.name}</p>
                        </div>
                      </>
                    )
                  })}
                </div>
                { role == "owner" && 
                  <button className="btn btn-primary" onClick={startGame}>Start game</button>
                }
              </div>
            }
          </div>
        </>
      }
      { gameStarted &&
        <>
        <div className="flex flex-col space-y-4 items-center">
          <h1 className="text-3xl">{questionDisplayed}</h1>
          <span className="indicator-item badge indicator-bottom indicator-center opacity-30">{questionNbr}/{questionLimit}</span>
        </div>
        { countdown > 0 &&
          <>
            <span className="countdown">
              <span style={{"--value":countdown.toString()}}></span>
            </span>
            <div className="flex flex-row space-x-4">
              { choice == "" &&
                <>
                  { possibleChoice.map((playerChoice) => (
                    <button className="btn btn-primary" disabled={choice != ""} onClick={() => {setAndSendChoice(playerChoice.name)}}>{playerChoice.name}</button>
                  ))}
                </>
              }
              { choice != "" &&
                  <span>Waiting <span className="loading loading-dots loading-xs"></span></span>
              }
            </div>
          </>
        }
        { countdown == 0 && 
          <>
          <div className="flex flex-row space-x-4">
            { possibleChoice.map((playerChoice) => {
              console.log(totalVotes)
              console.log(playerChoice.nbrVotes / totalVotes)
              let percent = Math.floor((playerChoice.nbrVotes / totalVotes) * 100)
              return (
                <div className="flex items-center space-y-4 flex-col">
                  <div className="radial-progress text-primary" style={{ "--value": percent }} role="progressbar">
                  {percent}%
                  </div> 
                  <h1>{playerChoice.name}</h1>
                </div>
              )})}
          </div>
            { (role == "owner" && questionNbr < questionLimit) &&
              <button className="btn btn-primary" onClick={nextQuestion}>Next question</button>
            }
            { (role == "owner" && questionNbr == questionLimit) &&
              <button className="btn btn-primary" onClick={resetGame}>Replay</button>
            }
          </>
        }
        </>
      }
    </main>
  );
}
