import styles from "./dashboard-input.module.css"
import { useEffect, useRef, useState, KeyboardEvent } from "react"
import { Button } from "../../../ui-component/button/button.component"
import { InputFileUtils } from "../../../ui-component/input/input-file.utils"
import { RoomType } from "../../../types/room.type"
import { useAccountUser } from "../../../hooks/use-user.hook"
import { MessageType } from "../../../types/message.type"
import { useNavigate } from "react-router-dom"

export function DashboardInput({
  onValueChange,
  value,
  onSend,
  onSendVoice,
  onEnter,
  ...otherProps
}: {
  value: string
  onValueChange?: (value: string) => void
  onSend: () => void
  onSendVoice: (file: File) => void
  onEnter?: () => any
} & React.InputHTMLAttributes<HTMLInputElement>) {
  // ---------------------------------------------------------------------------
  // variables
  // ---------------------------------------------------------------------------

  const [isRecording, setRecording] = useState<boolean>(false)
  const [durationTime, setDurationTime] = useState(0)
  const [text, setText] = useState("")
  const [audioChunks, setAudioChunks] = useState<Blob[]>([])
  const audioRecorderRef = useRef<MediaRecorder | null>(null)
  const audioPlayerRef = useRef<HTMLAudioElement | null>(null)
  const [isSave, setSave] = useState(false)
  const accountUser = useAccountUser()
  const navigate = useNavigate()

  // ---------------------------------------------------------------------------
  // effects
  // ---------------------------------------------------------------------------

  useEffect(() => {
    if (isRecording)
      navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
        if (!audioPlayerRef.current) return
        audioPlayerRef.current.srcObject = stream

        const rec = new MediaRecorder(stream, {
          audioBitsPerSecond: 128000,
          mimeType: InputFileUtils.getAudioInfo().mimeType,
        })
        rec.start()

        audioPlayerRef.current.ontimeupdate = () => {
          console.log(11)
          setDurationTime((prev) => prev + 1)
        }

        audioRecorderRef.current = rec
        audioRecorderRef.current.addEventListener("dataavailable", (e) => {
          console.log(e.data)
          setAudioChunks((prev) => [...prev, e.data])
        })

        audioRecorderRef.current.addEventListener("stop", () => {
          setRecording(false)
        })
      })

    return () => {
      if (!audioRecorderRef.current) return
      audioRecorderRef.current.removeEventListener("dataavailable", (e) =>
        setAudioChunks((prev) => [...prev, e.data]),
      )

      audioRecorderRef.current.removeEventListener("stop", () => {
        setRecording(false)
      })
    }
  }, [isRecording])

  useEffect(() => {
    uploadAudio()
  }, [isRecording, isSave, audioChunks])

  useEffect(() => {
    if (isRecording) {
      const interval = setInterval(() => {
        // recordingDurationRef.current += 1

        setDurationTime((prev) => prev + 1)
      }, 1000)

      return () => {
        clearInterval(interval)
      }
    }
  }, [isRecording])

  // ---------------------------------------------------------------------------
  // functions
  // ---------------------------------------------------------------------------

  function send() {
    if (!accountUser) return
    const room: RoomType = {
      id: String(Date.now()),
      created_at: Date.now(),
      title: text,
      userId: accountUser.id,
      messages: [],
    }

    const message: MessageType = {
      id: "",
      created_at: Date.now(),
      text: text,
      roomId: room.id,
      senderId: accountUser.id,
    }
    const getstoredRooms = localStorage.getItem("rooms")
    const storedRooms = getstoredRooms ? JSON.parse(getstoredRooms) : []
    // const storedRooms = JSON.parse(localStorage.getItem("rooms")) || []
    const updatedRooms = [...storedRooms, room]
    localStorage.setItem("rooms", JSON.stringify(updatedRooms))
    localStorage.setItem("newRoom", JSON.stringify(room))
    localStorage.setItem("newMessage", JSON.stringify(message))
    navigate(`/dashboard/message/${room.id}`)
  }

  function uploadAudio() {
    if (!audioChunks.length || isRecording) return

    if (isSave) {
      console.log("audioChunks:", audioChunks)

      const file = new File(
        audioChunks,
        `chanGptAudioMessage.${InputFileUtils.getAudioInfo().ext}`,
        {
          type: `audio-record/mpeg-3`,
        },
      )
      console.log("file: ", file)

      onSendVoice(file)
    }
  }

  function stopRecording(saveAudio: boolean) {
    if (!audioRecorderRef.current) return

    setRecording(false)
    setSave(saveAudio)
    setDurationTime(0)
    audioRecorderRef.current.stop()
    audioRecorderRef.current.stream.getTracks().forEach((track) => track.stop())
    uploadAudio()
  }

  function formatDuration() {
    const minutes = Math.floor(durationTime / 60)
    const remainingSeconds = durationTime % 60

    return `${minutes}:${remainingSeconds.toString().padStart(2, "0")}`
  }

  function onKeyDown(event: KeyboardEvent<any>) {
    if (event.key === "Enter" && onEnter) {
      send()
      onEnter()
    } else if (otherProps && otherProps.onKeyDown) {
      otherProps.onKeyDown(event)
    }
  }

  // ---------------------------------------------------------------------------
  return (
    <div className={styles.container}>
      <div className={styles.inputWrapper}>
        {/* --------------------------------------------------------------------------- */}
        {/* INPUT */}
        {/* --------------------------------------------------------------------------- */}

        {isRecording && (
          <div className={styles.recordWrapper}>
            <div className={styles.recordingLight}></div>
            <span className={styles.durationTime}>{formatDuration()}</span>
          </div>
        )}

        <input
          value={value}
          onChange={
            onValueChange
              ? (e) => {
                  setText(e.target.value)
                  onValueChange(e.target.value)
                }
              : undefined
          }
          disabled={isRecording}
          onKeyDown={onKeyDown}
          {...otherProps}
        />

        {/* --------------------------------------------------------------------------- */}
        {/* SEND BUTTON */}
        {/* --------------------------------------------------------------------------- */}

        {value ? (
          <Button mode="send" disabled={!value} onClick={onSend} />
        ) : !isRecording ? (
          <Button
            mode="voice"
            onClick={() => {
              setRecording(true)
            }}
          />
        ) : (
          <Button
            mode="stop-record"
            onClick={() => {
              stopRecording(true)
            }}
          />
        )}
      </div>

      <audio
        ref={audioPlayerRef}
        // autoPlay
        controls={false}
        style={{ display: "none" }}
      />
    </div>
  )
}
please don't answer, I'll ask you later