import { act, render, screen } from '@testing-library/react'
import { RecordingButton } from './RecordingButton'
import { ZocksRecordingActions } from '../../../store'
import { Provider } from 'react-redux'
import { configureStore } from '@reduxjs/toolkit'
import { zocksStoreConfig } from '../../../app/store'
import { setActiveSession, setRecording, setRoomId, setSessionConfig } from '../../../store/session/sessionSlice'
import { mock } from 'jest-mock-extended'
import { Auth } from '@zocks-communications/client-sdk-js'
import userEvent from '@testing-library/user-event'
import * as zocksSdk from '@zocks-communications/client-sdk-js'

const recordingActions: ZocksRecordingActions = {
  startRecording: jest.fn(),
  stopRecording: jest.fn(),
}

afterEach(() => jest.restoreAllMocks())

const renderWithState = (authHasScope: boolean) => {
  const mockAuth = mock<Auth>({ hasScope: jest.fn().mockReturnValue(authHasScope) })
  jest.spyOn(zocksSdk, 'Auth').mockReturnValue(mockAuth)
  const store = configureStore(zocksStoreConfig)
  store.dispatch(setSessionConfig({ accountId: 'testAccountId' }))
  store.dispatch(setRoomId('testRoomId'))
  store.dispatch(setRecording(null))
  render(
    <Provider store={store}>
      <RecordingButton recordingActions={recordingActions} />
    </Provider>
  )
  return { store }
}

test('Recording button should be disabled if user does not have permission', () => {
  renderWithState(false)

  const recordingButton = screen.getByRole('button', { name: 'Start recording' })

  expect(recordingButton).toBeInTheDocument()
  expect(recordingButton).toBeDisabled()
  userEvent.click(recordingButton)
  expect(recordingActions.startRecording).toHaveBeenCalledTimes(0)
})

test('Recording button should be enabled if user does have permission', () => {
  renderWithState(true)

  const recordingButton = screen.getByRole('button', { name: 'Start recording' })

  expect(recordingButton).toBeInTheDocument()
  expect(recordingButton).toBeEnabled()
  userEvent.click(recordingButton)
  expect(recordingActions.startRecording).toHaveBeenCalledTimes(1)
})

test('Recording button should change classes if recording changes in the store and it should call start and stop actions', async () => {
  const { store } = renderWithState(true)

  expect(screen.getByRole('button', { name: 'Start recording' })).toHaveClass('zocks__recording-button--start')
  await userEvent.click(screen.getByRole('button', { name: 'Start recording' }))
  expect(recordingActions.startRecording).toHaveBeenCalledTimes(1)
  act(() =>
    store.dispatch(
      setActiveSession({
        recording: {
          userId: 'user-id',
          startedAt: '2023-02-03T00:00:00.000Z',
          fileId: 'file-id',
        },
      })
    )
  )
  expect(screen.getByRole('button', { name: 'Stop recording' })).toHaveClass('zocks__recording-button--stop')
  userEvent.click(screen.getByRole('button', { name: 'Stop recording' }))
  expect(recordingActions.stopRecording).toHaveBeenCalledTimes(1)
})
