import React from 'react'
import { act, render, screen } from '@testing-library/react'

import { initStore } from '../../../testUtils'
import { Provider } from 'react-redux'
import { OnlineParticipantsList } from './OnlineParticipantsList'
import {
  activeSpeakersChanged,
  participantLocalTrackPublished,
  setLocalParticipantName,
} from '../../../store/session/sessionSlice'
import { StreamKind, StreamSource } from '@zocks-communications/client-sdk-js'

const renderWithParticipants = (numberOfRemoteParticipants: number, activeSpeakers?: string[]) => {
  const store = initStore(numberOfRemoteParticipants, activeSpeakers)
  const { container } = render(
    <Provider store={store}>
      <OnlineParticipantsList />
    </Provider>
  )
  return { container, store }
}

test('renders all of the online participants', () => {
  renderWithParticipants(2)

  expect(screen.getByText('Participant name: local')).toBeInTheDocument()
  expect(screen.getByText('Participant name: 0')).toBeInTheDocument()
  expect(screen.getByText('Participant name: 1')).toBeInTheDocument()
})

test('renders an audio icon based on the audio state of the participant', () => {
  const { store, container } = renderWithParticipants(0)

  expect(container.querySelector('.zocks__participants-list__participant-no-audio-icon')).toBeInTheDocument()
  expect(container.querySelector('.zocks__participants-list__participant-audio-icon')).not.toBeInTheDocument()

  act(() => {
    store.dispatch(
      participantLocalTrackPublished({
        trackId: 'testAudioTrackId',
        trackSource: StreamSource.MICROPHONE,
        trackKind: StreamKind.AUDIO,
        trackIsMuted: false,
      })
    )
  })

  expect(container.querySelector('.zocks__participants-list__participant-audio-icon')).toBeInTheDocument()
  expect(container.querySelector('.zocks__participants-list__participant-no-audio-icon')).not.toBeInTheDocument()
})

test('renders a video icon based on the video state of the participant', () => {
  const { store, container } = renderWithParticipants(0)

  expect(container.querySelector('.zocks__participants-list__participant-no-video-icon')).toBeInTheDocument()
  expect(container.querySelector('.zocks__participants-list__participant-video-icon')).not.toBeInTheDocument()

  act(() => {
    store.dispatch(
      participantLocalTrackPublished({
        trackId: 'testVideoTrackId',
        trackSource: StreamSource.CAMERA,
        trackKind: StreamKind.VIDEO,
        trackIsMuted: false,
      })
    )
  })

  expect(container.querySelector('.zocks__participants-list__participant-video-icon')).toBeInTheDocument()
  expect(container.querySelector('.zocks__participants-list__participant-no-video-icon')).not.toBeInTheDocument()
})

test('renders a custom audio icon when a participant is speaking', () => {
  const { store, container } = renderWithParticipants(0)

  expect(container.querySelector('.zocks__participants-list__participant-speaking')).not.toBeInTheDocument()

  act(() => {
    store.dispatch(activeSpeakersChanged(['Participant id: local']))
  })

  expect(container.querySelector('.zocks__participants-list__participant-speaking')).toBeInTheDocument()
})

test('does not render avatar and name for participants without a name', () => {
  const store = initStore(0)
  store.dispatch(setLocalParticipantName(''))
  render(
    <Provider store={store}>
      <OnlineParticipantsList />
    </Provider>
  )

  expect(screen.queryByText(/./)).not.toBeInTheDocument()
})
