import { useAppDispatch } from 'domains/store'
import { setEventsRead } from 'domains/store/slice'
import { ChannelEvent } from 'domains/store/store.types'
import { useIntersect } from 'domains/visibility/hooks'
import { className } from 'lib/css'
import { FunctionComponent, useEffect } from 'preact/compat'
import { useChatScrollContext } from 'ui/components/conversation/event/chat-scroll/chat-scroll-context'
import TimeIndicator from 'ui/components/conversation/event/divider/variants/time-indicator'
import { useSeamlyCommands } from 'ui/hooks/seamly-hooks'
import useEventComponentMapping from 'ui/hooks/use-event-component-mapping'
import { actionTypes } from 'ui/utils/seamly-utils'

const Event: FunctionComponent<{
  event: ChannelEvent
  newParticipant: boolean
}> = ({ event, newParticipant }) => {
  const { eventRefs, unreadIds } = useChatScrollContext()
  const { sendAction } = useSeamlyCommands()
  const ref = event.payload.id ? eventRefs[event.payload.id] : undefined

  const { containerRef, isVisible } = useIntersect({
    containerRef: ref,
    freezeOnceVisible: true,
  })
  const dispatch = useAppDispatch()
  const [Component, SubComponent] = useEventComponentMapping(event)

  useEffect(() => {
    if (isVisible && unreadIds?.includes(event.payload.id)) {
      const readIds = unreadIds.reduce<string[]>(
        (arr, id) =>
          event?.payload?.id && id && !arr.includes(event.payload.id)
            ? arr.concat(id)
            : arr,
        [],
      )

      dispatch(setEventsRead(readIds))
      sendAction({ type: actionTypes.read, events: readIds })
    }
  }, [dispatch, event.payload.id, isVisible, sendAction, unreadIds])

  if (!Component) {
    return null
  }

  const classNames = ['conversation__item']

  if (event.type === 'info') {
    classNames.push('conversation__item--source-info')
  } else if (event.payload.fromClient) {
    classNames.push('conversation__item--source-user')
  } else {
    classNames.push('conversation__item--source-agent')
  }

  if (newParticipant) {
    classNames.push('conversation__item--new-participant')
  }

  return (
    <li className={className(classNames)} ref={containerRef}>
      {event.payload.timeIndicator && <TimeIndicator event={event} />}
      <Component event={event}>
        <SubComponent event={event} />
      </Component>
    </li>
  )
}

export default Event
