import { ConnectionQuality, SessionState } from '@zocks-communications/client-sdk-js'
import { render, screen } from '@testing-library/react'
import { setupZocksSdkMocks } from '../../testUtils'
import { configureStore, EnhancedStore } from '@reduxjs/toolkit'
import { Provider } from 'react-redux'
import { ScreenShare } from './ScreenShare'
import { zocksStoreConfig } from '../../app/store'
import { setLocalParticipantId, setRoomId, setSessionState } from '../../store/session/sessionSlice'
import { ParticipantModel } from '../../store'

const renderWithState = (store: EnhancedStore, participant: ParticipantModel) => {
  return render(
    <Provider store={store}>
      <ScreenShare participant={participant} />
    </Provider>
  )
}

test('renders a video component and attaches the screen share track to it if the track is available and subscribed', () => {
  const { mockLocalScreenShareTrack } = setupZocksSdkMocks()
  const localParticipantWithScreenShare = {
    id: 'testLocalParticipantId',
    name: 'testLocalParticipantName',
    tracks: {
      audioTracks: [],
      videoTracks: [],
      screenShareTrack: {
        id: 'testLocalScreenShareTrackId',
        isMuted: false,
        isSubscribed: true,
      },
    },
    connectionQuality: ConnectionQuality.EXCELLENT,
  }
  const store = configureStore(zocksStoreConfig)
  store.dispatch(setSessionState(SessionState.CONNECTED))
  store.dispatch(setRoomId('testRoomId'))
  store.dispatch(setLocalParticipantId('testLocalParticipantId'))

  renderWithState(store, localParticipantWithScreenShare)

  expect(screen.getByTestId('videoElement')).toBeInTheDocument()
  expect(mockLocalScreenShareTrack.attach).toHaveBeenCalledTimes(1)
  expect(mockLocalScreenShareTrack.attach.mock.calls[0][0]).toBeInstanceOf(HTMLVideoElement)
})

test('does not render anything if the track is available, but not subscribed', () => {
  const localParticipantWithUnsubscribedScreenShare = {
    id: 'testLocalParticipantId',
    name: 'testLocalParticipantName',
    tracks: {
      audioTracks: [],
      videoTracks: [],
      screenShareTrack: {
        id: 'testLocalScreenShareTrackId',
        isMuted: false,
        isSubscribed: false,
      },
    },
    connectionQuality: ConnectionQuality.EXCELLENT,
  }
  const store = configureStore(zocksStoreConfig)
  store.dispatch(setSessionState(SessionState.CONNECTED))
  store.dispatch(setRoomId('testRoomId'))
  store.dispatch(setLocalParticipantId('testLocalParticipantId'))

  renderWithState(store, localParticipantWithUnsubscribedScreenShare)

  expect(screen.queryByTestId('videoElement')).not.toBeInTheDocument()
})

test('does not render anything if the track is not available', () => {
  const localParticipantWithoutScreenShare = {
    id: 'testLocalParticipantId',
    name: 'testLocalParticipantName',
    tracks: {
      audioTracks: [],
      videoTracks: [],
      screenShareTrack: null,
    },
    connectionQuality: ConnectionQuality.EXCELLENT,
  }
  const store = configureStore(zocksStoreConfig)
  store.dispatch(setSessionState(SessionState.CONNECTED))
  store.dispatch(setRoomId('testRoomId'))
  store.dispatch(setLocalParticipantId('testLocalParticipantId'))

  renderWithState(store, localParticipantWithoutScreenShare)

  expect(screen.queryByTestId('videoElement')).not.toBeInTheDocument()
})
