import ComponentAccount from '@components/Account'
import haptics from '@components/haptics'
import ComponentHashtag from '@components/Hashtag'
import Icon from '@components/Icon'
import { Loading } from '@components/Loading'
import ComponentSeparator from '@components/Separator'
import { useSearchQuery } from '@utils/queryHooks/search'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { Fragment, useContext, useEffect } from 'react'
import { View } from 'react-native'
import ComposeContext from '../utils/createContext'
import { formatText } from '../utils/processText'

const ComposeRootSuggestions: React.FC = () => {
  const { composeState, composeDispatch } = useContext(ComposeContext)

  const { colors } = useTheme()

  useEffect(() => {
    if (composeState.text.raw.length === 0) {
      composeDispatch({ type: 'tag', payload: undefined })
    }
  }, [composeState.text.raw.length])

  const mapSchemaToType = () => {
    if (composeState.tag) {
      switch (composeState.tag?.schema) {
        case '@':
          return 'accounts'
        case '#':
          return 'hashtags'
      }
    } else {
      return undefined
    }
  }
  const { isFetching, data, refetch } = useSearchQuery({
    type: mapSchemaToType(),
    term: composeState.tag?.raw.substring(1),
    ...(mapSchemaToType() === 'accounts' && { following: true }),
    options: { enabled: false }
  })
  useEffect(() => {
    if (
      (composeState.tag?.schema === '@' || composeState.tag?.schema === '#') &&
      composeState.tag?.raw
    ) {
      refetch()
    }
  }, [composeState.tag])

  const onPress = (content: string) => {
    const focusedInput = composeState.textInputFocus.current
    const updatedText = (): string => {
      const textInput = composeState.textInputFocus.current
      if (composeState.tag) {
        const contentFront = composeState[textInput].raw.slice(0, composeState.tag.index)
        const contentRear = composeState[textInput].raw.slice(composeState.tag.lastIndex)

        const spaceFront =
          contentFront.length === 0 ||
          composeState[textInput].raw.length === 0 ||
          /\s/g.test(contentFront.slice(-1))
            ? ''
            : ' '
        const spaceRear = /\s/g.test(contentRear[0]) ? '' : ' '

        return [contentFront, spaceFront, content, spaceRear, contentRear].join('')
      } else {
        return composeState[textInput].raw
      }
    }
    formatText({
      textInput: focusedInput,
      composeDispatch,
      content: updatedText(),
      disableDebounce: true
    })
    haptics('Light')
  }

  const main = () => {
    if (composeState.tag) {
      switch (composeState.tag?.schema) {
        case '@':
          return (
            <View>
              {data?.accounts?.map(account => (
                <Fragment key={account.id}>
                  <ComponentAccount
                    account={account}
                    props={{ onPress: () => onPress(`@${account.acct}`) }}
                    children={
                      <Icon
                        name='plus'
                        size={StyleConstants.Font.Size.L}
                        color={colors.secondary}
                        style={{ marginLeft: 8 }}
                      />
                    }
                  />
                  <ComponentSeparator />
                </Fragment>
              ))}
            </View>
          )
        case '#':
          return (
            <View>
              {data?.hashtags?.map(hashtag => (
                <Fragment key={hashtag.name}>
                  <ComponentHashtag hashtag={hashtag} onPress={() => onPress(`#${hashtag.name}`)} />
                  <ComponentSeparator />
                </Fragment>
              ))}
            </View>
          )
      }
    }
  }

  return isFetching ? (
    <View
      key='listEmpty'
      style={{ flex: 1, alignItems: 'center', marginVertical: StyleConstants.Spacing.M }}
    >
      <Loading />
    </View>
  ) : (
    <>{main()}</>
  )
}

export default ComposeRootSuggestions
