"use client"

import * as React from "react"
import { cn } from "@/lib/utils"
import { ICameraVideoTrack, ILocalVideoTrack, IMicrophoneAudioTrack } from "agora-rtc-sdk-ng"
import { useAppSelector, useAppDispatch } from "@/common/hooks"
import { isVoiceGenderSupported, VideoSourceType } from "@/common/constant"
import { ITextItem, EMessageType, IChatItem } from "@/types"
import { rtcManager, IUserTracks, IRtcUser } from "@/manager"
import {
  setRoomConnected,
  addChatItem,
  setVoiceType,
  setOptions,
} from "@/store/reducers/global"
import AgentVoicePresetSelect from "@/components/Agent/VoicePresetSelect"
import AgentView from "@/components/Agent/View"
import MicrophoneBlock from "@/components/Agent/Microphone"
import CameraBlock from "@/components/Agent/Camera"
import VideoBlock from "@/components/Agent/Camera"

let hasInit: boolean = false

export default function RTCCard(props: { className?: string }) {
  const { className } = props

  const dispatch = useAppDispatch()
  const options = useAppSelector((state) => state.global.options)
  const voiceType = useAppSelector((state) => state.global.voiceType)
  const selectedGraphId = useAppSelector((state) => state.global.graphName)
  const { userId, channel } = options
  const [videoTrack, setVideoTrack] = React.useState<ICameraVideoTrack>()
  const [audioTrack, setAudioTrack] = React.useState<IMicrophoneAudioTrack>()
  const [screenTrack, setScreenTrack] = React.useState<ILocalVideoTrack>()
  const [remoteuser, setRemoteUser] = React.useState<IRtcUser>()
  const [videoSourceType, setVideoSourceType] = React.useState<VideoSourceType>(VideoSourceType.CAMERA)

  React.useEffect(() => {
    if (!options.channel) {
      return
    }
    if (hasInit) {
      return
    }

    init()

    return () => {
      if (hasInit) {
        destory()
      }
    }
  }, [options.channel])

  const init = async () => {
    console.log("[rtc] init")
    rtcManager.on("localTracksChanged", onLocalTracksChanged)
    rtcManager.on("textChanged", onTextChanged)
    rtcManager.on("remoteUserChanged", onRemoteUserChanged)
    await rtcManager.createCameraTracks()
    await rtcManager.createMicrophoneTracks()
    await rtcManager.join({
      channel,
      userId,
    })
    dispatch(
      setOptions({
        ...options,
        appId: rtcManager.appId ?? "",
        token: rtcManager.token ?? "",
      }),
    )
    await rtcManager.publish()
    dispatch(setRoomConnected(true))
    hasInit = true
  }

  const destory = async () => {
    console.log("[rtc] destory")
    rtcManager.off("textChanged", onTextChanged)
    rtcManager.off("localTracksChanged", onLocalTracksChanged)
    rtcManager.off("remoteUserChanged", onRemoteUserChanged)
    await rtcManager.destroy()
    dispatch(setRoomConnected(false))
    hasInit = false
  }

  const onRemoteUserChanged = (user: IRtcUser) => {
    console.log("[rtc] onRemoteUserChanged", user)
    setRemoteUser(user)
  }

  const onLocalTracksChanged = (tracks: IUserTracks) => {
    console.log("[rtc] onLocalTracksChanged", tracks)
    const { videoTrack, audioTrack, screenTrack } = tracks
    setVideoTrack(videoTrack)
    setScreenTrack(screenTrack)
    if (audioTrack) {
      setAudioTrack(audioTrack)
    }
  }

  const onTextChanged = (text: IChatItem) => {
    console.log("[rtc] onTextChanged", text)
    dispatch(
      addChatItem(text),
    )
  }

  const onVoiceChange = (value: any) => {
    dispatch(setVoiceType(value))
  }

  const onVideoSourceTypeChange = async (value: VideoSourceType) => {
    await rtcManager.switchVideoSource(value)
    setVideoSourceType(value)
  }

  return (
    <>
      <div className={cn("flex-shrink-0", "overflow-y-auto", className)}>
        <div className="flex h-full w-full flex-col">
          {/* -- Agent */}
          <div className="w-full">
            <div className="flex w-full items-center justify-between p-2">
              <h2 className="mb-2 text-xl font-semibold">Audio & Video</h2>
              {
                isVoiceGenderSupported(selectedGraphId) ?
                  <AgentVoicePresetSelect /> :
                  null}
            </div>
            <AgentView audioTrack={remoteuser?.audioTrack} />
          </div>

          {/* -- You */}
          <div className="w-full space-y-2 px-2">
            <MicrophoneBlock audioTrack={audioTrack} />
            <VideoBlock
              cameraTrack={videoTrack}
              screenTrack={screenTrack}
              videoSourceType={videoSourceType}
              onVideoSourceChange={onVideoSourceTypeChange}
            />
          </div>
        </div>
      </div>
    </>
  )
}
