import type { Channel } from 'stream-chat'
import { describe, expect, it, vi } from 'vitest'

import { fireEvent, renderWithProviders, screen } from '../../test/utils'

import {
  ChannelListProvider,
  useChannelListContext,
} from './ChannelListContext'

const channel = { id: 'channel-1' } as Channel

function ContextConsumer() {
  const value = useChannelListContext()

  return (
    <div>
      <span data-testid="selected-channel">
        {value.selectedChannel?.id ?? 'undefined'}
      </span>
      <span data-testid="debug">{String(value.debug)}</span>
      <span data-testid="render-message-preview">
        {value.renderMessagePreview ? 'provided' : 'undefined'}
      </span>
      <span data-testid="channel-preview">
        {value.channelPreview ? 'provided' : 'undefined'}
      </span>
      <span data-testid="viewer-language">
        {value.viewerLanguage ?? 'undefined'}
      </span>
      <button type="button" onClick={() => value.onChannelSelect(channel)}>
        Select channel
      </button>
    </div>
  )
}

describe('ChannelListContext', () => {
  it('provides safe documented defaults without a provider', () => {
    renderWithProviders(<ContextConsumer />)

    expect(screen.getByTestId('selected-channel')).toHaveTextContent(
      'undefined'
    )
    expect(screen.getByTestId('debug')).toHaveTextContent('false')
    expect(screen.getByTestId('render-message-preview')).toHaveTextContent(
      'undefined'
    )
    expect(screen.getByTestId('channel-preview')).toHaveTextContent('undefined')
    expect(screen.getByTestId('viewer-language')).toHaveTextContent('undefined')
    expect(() => fireEvent.click(screen.getByRole('button'))).not.toThrow()
  })

  it('exposes the value supplied by a provider', () => {
    const onChannelSelect = vi.fn()
    const ChannelPreview = () => null
    const renderMessagePreview = () => 'preview'

    renderWithProviders(
      <ChannelListProvider
        value={{
          selectedChannel: channel,
          onChannelSelect,
          debug: true,
          renderMessagePreview,
          channelPreview: ChannelPreview,
          viewerLanguage: 'es',
        }}
      >
        <ContextConsumer />
      </ChannelListProvider>
    )

    expect(screen.getByTestId('selected-channel')).toHaveTextContent(
      'channel-1'
    )
    expect(screen.getByTestId('debug')).toHaveTextContent('true')
    expect(screen.getByTestId('render-message-preview')).toHaveTextContent(
      'provided'
    )
    expect(screen.getByTestId('channel-preview')).toHaveTextContent('provided')
    expect(screen.getByTestId('viewer-language')).toHaveTextContent('es')

    fireEvent.click(screen.getByRole('button'))
    expect(onChannelSelect).toHaveBeenCalledWith(channel)
  })
})
