import {useEffect, useState} from 'react'
import useParticipants from './useParticipants'
import { SdkConfig } from '@/types/SdkConfig'
import randomStringHelper from '@/utils/randomString.helper'
import {VROOM_SDK_EVENT, VroomSDK} from 'vroom-web-sdk-beta'
import {useVroomUI} from '@/contexts/VroomUI'
import {useSdkStateGlobal} from '@/contexts/SdkStateGlobal'

type initParams = {
  config: SdkConfig,
  enableVideo: boolean,
  enableAudio: boolean,
  callStart: boolean,
  username: string,
  vroomUIProps: any,
}

type SDK = any

const useVroomSdk = (initValue: initParams) => {
  let sdk: SDK = null
  const [sdkState, setSdkState] = useState(null)
  const [callStarted, setCallStarted] = useState(initValue.callStart)
  const [sdkMonitor, setSdkMonitor] = useState(null)
  const [localStream, setLocalStream] = useState(null)
  const vroomUI = useVroomUI()
  const sdkStateGlobal = useSdkStateGlobal()

  const {
    attendees,
    participantsState,
    handleInitParticipant,
    handleAddParticipant,
    handleDeleteParticipant,
    handleSetVideoMediaStream,
    handleClearAttendees,
    handleClearParticipantState,
  } = useParticipants([])

  const handleStartCall = () => {
    sdk = new VroomSDK({
      token: initValue.vroomUIProps.config.token,
      roomId: initValue.vroomUIProps.config.roomId,
      displayName: initValue.vroomUIProps.config.displayName,
      endpoint: initValue.vroomUIProps.config.endpoint,
      opaqueId: 'videoroom-' + randomStringHelper(12)
    })

    // TODO: Should be Better for this way
    setCallStarted(true)
  }

  const handleHangup = () => {
    // @ts-ignore
    if (sdkState && sdkState?.roomInfo && callStarted) {
      // @ts-ignore
      sdkState.onHangupCall(sdkState)
    }
  }

  const handleLocalSteamUpdate = (stream: MediaStream) => {
    // @ts-ignore
    setLocalStream(stream)
  }

  useEffect(() => {
    return () => {
      if (sdk) {
        sdk.on(VROOM_SDK_EVENT.MONITOR, (data: any) => {
          setSdkMonitor(data)
        })

        sdk.on(VROOM_SDK_EVENT.CREATED, (_data: any) => {
          sdk.initLocalStream(initValue.enableAudio, initValue.enableVideo)
            .then((_stream: any) => {
              setLocalStream(_stream)
              return sdk.join(_stream, initValue.enableAudio, initValue.enableVideo)
            })
            .then(() => {
              if (sdkState === null) {
                setSdkState(sdk)
                sdkStateGlobal.setStateAll(sdk)

                if (sdk?.attendees?.length > 0) {
                  sdk?.attendees.map((att: any) => {
                    handleInitParticipant(att)
                  })
                }

                if (sdk?.devices) {
                  sdkStateGlobal.setCameraList(sdk?.devices)
                }

                if (sdk?.currentCamera) {
                  sdkStateGlobal.setCurrentCamera(sdk.currentCamera)
                  vroomUI.setEmitCurrentCamera(sdk.currentCamera)
                }
              }
            })
            .catch(console.error)
        })

        sdk.on(VROOM_SDK_EVENT.LEAVE, (data: any) => {
          // console.log('VROOM_SDK_EVENT.LEAVE', data)
          sdk.removeSubscriberStream(data)
          handleDeleteParticipant(data)
        })

        sdk.on(VROOM_SDK_EVENT.LEAVE, handleDeleteParticipant)

        sdk.on(VROOM_SDK_EVENT.AFTER_HANGUP, () => {
          sdk = null
          setSdkState(null)
          setCallStarted(false)
          vroomUI.setEmitCameraDeviceList([])
          setLocalStream(null)
          handleClearAttendees()
          handleClearParticipantState()
        })

        sdk.on(VROOM_SDK_EVENT.INIT_SUB, (data: any) => {
          // console.log('VROOM_SDK_EVENT.INIT_SUB', data)
          handleInitParticipant(data)
        })

        sdk.on(VROOM_SDK_EVENT.UPDATE_SUB_MEDIA_LIST, (data: any) => {
          // console.log('VROOM_SDK_EVENT.UPDATE_SUB_MEDIA_LIST', data)
          handleSetVideoMediaStream(data)
        })

        sdk.on(VROOM_SDK_EVENT.LOCAL_STREAM_UPDATE, handleLocalSteamUpdate)

        sdk.on(VROOM_SDK_EVENT.JOIN_FAILURE, (data: any) => {
          console.error(data)
        })
      }
    }
  }, [
    callStarted,
    initValue.enableAudio,
    initValue.enableVideo,
    handleAddParticipant,
    handleDeleteParticipant,
    handleInitParticipant,
    handleSetVideoMediaStream,
    sdk
  ])

  useEffect(() => {
    if (sdkStateGlobal.cameraList.length) {
      vroomUI.setEmitCameraDeviceList(sdkStateGlobal.cameraList)
    }
  }, [sdkStateGlobal.cameraList])

  return {
    sdk: sdk,
    sdkState: sdkState,
    sdkMonitor: sdkMonitor,
    attendees: attendees,
    VIDEO: initValue.enableVideo,
    AUDIO: initValue.enableAudio,
    localStream: localStream,
    participantsState: participantsState,
    callStarted: callStarted,
    onStartCall: handleStartCall,
    onHangupCall: handleHangup,
  }
}

export default useVroomSdk
