import React from 'react'
import { VirtualBackgroundType } from '@zocks-communications/client-sdk-js'
import { AudioControlButton, VideoControlButton, VirtualBackgroundVideoControlMenu } from '../../ControlButtons'
import { getClassName, getMergedClassNames, StyledComponent } from '../../common'
import { Video } from '../../Media'
import { JoinPageLocalStreamsProps } from './models'
import zocksStyle from './JoinPageLocalStreams.module.scss'

export const JoinPageLocalStreams: React.FC<JoinPageLocalStreamsProps> = ({ styles, localMedia, components }) => {
  const {
    localAudioStream,
    localVideoStream,
    virtualBackgroundStream,
    currentVirtualBackground,
    videoStreamIsLoading,
    currentVideoDeviceId,
    toggleLocalAudioStream,
    toggleLocalVideoStream,
    changeVirtualBackground,
    stopLocalVirtualBackground,
    selectAudioDevice,
    selectVideoDevice,
  } = localMedia

  const audioEnabled = !!localAudioStream
  const videoEnabled = !!localVideoStream || !!virtualBackgroundStream

  const AudioControlButtonElement = components?.AudioControlButton ?? AudioControlButton
  const VideoControlButtonElement = components?.VideoControlButton ?? VideoControlButton
  const DisabledVideoComponentElement = components?.DisabledVideoComponent ?? DisabledVideoComponent
  const ExtraComponentElement = components?.ExtraComponent || null

  const changeVideoDevice = async (videoDevice: MediaDeviceInfo) => {
    selectVideoDevice(videoDevice)
    if (currentVirtualBackground) {
      await changeVirtualBackground(currentVirtualBackground, videoDevice.deviceId)
    }
  }

  const toggleVideoStream = async () => {
    toggleLocalVideoStream()
    if (videoEnabled) {
      stopLocalVirtualBackground()
    } else if (currentVirtualBackground) {
      await changeVirtualBackground(currentVirtualBackground, currentVideoDeviceId || undefined)
    }
  }

  const toggleBlur = async () => {
    if (currentVirtualBackground) {
      await changeVirtualBackground(null)
    } else {
      await changeVirtualBackground(VirtualBackgroundType.BLUR, currentVideoDeviceId || undefined)
    }
  }

  const mergedStyles = getMergedClassNames(zocksStyle, styles)

  return (
    <div className={getClassName('join-page__local-streams', mergedStyles)}>
      {localVideoStream || virtualBackgroundStream ? (
        <div className={getClassName('join-page__video-container', mergedStyles)}>
          <div className={getClassName('join-page__video-preview', mergedStyles)}>
            <Video videoStream={virtualBackgroundStream || localVideoStream!} />
          </div>
        </div>
      ) : (
        <DisabledVideoComponentElement styles={mergedStyles} />
      )}
      <div className={getClassName('join-page__local-stream-buttons', mergedStyles)}>
        <AudioControlButtonElement
          audioIsOn={audioEnabled}
          toggleAudio={toggleLocalAudioStream}
          onAudioDeviceSelected={selectAudioDevice}
          styles={mergedStyles}
        />
        <VideoControlButtonElement
          videoIsOn={videoEnabled}
          toggleVideo={toggleVideoStream}
          onVideoDeviceSelected={changeVideoDevice}
          videoIsLoading={videoStreamIsLoading}
          components={{ VideoControlMenu: VirtualBackgroundVideoControlMenu(currentVirtualBackground, toggleBlur) }}
          styles={mergedStyles}
        />
        {ExtraComponentElement && <ExtraComponentElement styles={mergedStyles} />}
      </div>
    </div>
  )
}

const DisabledVideoComponent: React.FC<StyledComponent> = ({ styles }) => {
  return <div className={getClassName('join-page__no-video-icon', styles)} />
}
