import classNames from 'classnames'
import React from 'react'
import type { Channel } from 'stream-chat'
import {
  ChannelList as StreamChannelList,
  InfiniteScroll,
} from 'stream-chat-react'

import { restorePendingMessages } from '../../hooks/useRestorePendingMessages'
import { useMessagingContext } from '../../providers/MessagingProvider'
import type { ChannelListProps } from '../../types'

import { ChannelListProvider } from './ChannelListContext'
import CustomChannelPreview from './CustomChannelPreview'

const DEFAULT_SORT = { last_message_at: -1 } as const

/**
 * Channel list component with customizable header and actions
 */
export const ChannelList = React.memo<ChannelListProps>(
  ({
    onChannelSelect,
    selectedChannel,
    filters,
    allowNewMessagesFromUnfilteredChannels = false,
    channelRenderFilterFn,
    sort = DEFAULT_SORT,
    className,
    customEmptyStateIndicator,
    channelListPaginator: Paginator = InfiniteScroll,
    channelPreview,
    renderMessagePreview,
    viewerLanguage,
    lockChannelOrder,
    onMessageNewHandler,
    onMessageNew,
    onChannelVisible,
    onAddedToChannel,
    onChannelUpdated,
  }) => {
    // Track renders
    const renderCountRef = React.useRef(0)
    renderCountRef.current++

    // Get debug flag from context
    const { debug = false } = useMessagingContext()

    // Wrap channelRenderFilterFn to restore pending messages for all channels
    // as soon as they are loaded, without waiting for the user to click into each one.
    const wrappedChannelRenderFilterFn = React.useCallback(
      (channels: Channel[]) => {
        for (const channel of channels) {
          restorePendingMessages(channel)
        }
        return channelRenderFilterFn
          ? channelRenderFilterFn(channels)
          : channels
      },
      [channelRenderFilterFn]
    )

    if (debug) {
      console.log('📺 [ChannelList] 🔄 RENDER START', {
        renderCount: renderCountRef.current,
        selectedChannelId: selectedChannel?.id,
        filters,
      })
    }

    const contextValue = React.useMemo(
      () => ({
        selectedChannel,
        onChannelSelect,
        debug,
        channelPreview,
        renderMessagePreview,
        viewerLanguage,
      }),
      [
        selectedChannel,
        onChannelSelect,
        debug,
        channelPreview,
        renderMessagePreview,
        viewerLanguage,
      ]
    )

    return (
      <div
        className={classNames(
          'messaging-channel-list h-full flex flex-col min-w-0 overflow-hidden',
          className
        )}
      >
        {/* Channel List */}
        <div className="flex-1 overflow-hidden min-w-0">
          <ChannelListProvider value={contextValue}>
            <StreamChannelList
              key={`${JSON.stringify(filters)}:${JSON.stringify(sort)}`}
              filters={filters}
              sort={sort}
              options={{ limit: 30 }}
              allowNewMessagesFromUnfilteredChannels={
                allowNewMessagesFromUnfilteredChannels
              }
              channelRenderFilterFn={wrappedChannelRenderFilterFn}
              lockChannelOrder={lockChannelOrder}
              onMessageNewHandler={onMessageNewHandler}
              onMessageNew={onMessageNew}
              onChannelVisible={onChannelVisible}
              onAddedToChannel={onAddedToChannel}
              onChannelUpdated={onChannelUpdated}
              Paginator={Paginator}
              Preview={CustomChannelPreview}
              EmptyStateIndicator={customEmptyStateIndicator}
            />
          </ChannelListProvider>
        </div>
      </div>
    )
  }
)
ChannelList.displayName = 'ChannelList'
