import { FlashList } from '@shopify/flash-list'
import { useQuery } from '@tanstack/react-query'
import type { ErrorBoundaryProps } from 'expo-router'
import { useLocalSearchParams } from 'expo-router'
import { useCallback, useMemo } from 'react'
import { ActivityIndicator } from 'react-native'
import { ErrorState } from 'src/components/common/ErrorState'
import ExpandableText from 'src/components/common/ExpandableText'
import { ScreenScrollContainer } from 'src/components/layout'
import { postQueries } from 'src/lib/queries/posts'
import { htmlToTextWithLineBreaks, timeAgo } from 'src/utils'
import { Separator, Text, useTheme, View, XStack, YStack } from 'tamagui'

export function ErrorBoundary({ error, retry }: ErrorBoundaryProps) {
  return <ErrorState message={error.message} onRetry={retry} />
}

export default function Page() {
  const { id } = useLocalSearchParams<{ id: string }>()
  const theme = useTheme()

  const { isPending, isError, data, error } = useQuery(postQueries.history(id))

  const filteredData = useMemo(() => data, [data])

  const getDiff = (oldContent: string, newContent: string) => {
    const oldWords = oldContent.split(/\s+/)
    const newWords = newContent.split(/\s+/)
    const diff = []
    let i = 0
    let j = 0

    while (i < oldWords.length && j < newWords.length) {
      if (oldWords[i] === newWords[j]) {
        diff.push({ text: oldWords[i], type: 'same' })
        i++
        j++
      } else if (oldWords[i] !== newWords[j]) {
        diff.push({ text: oldWords[i], type: 'removed' })
        diff.push({ text: newWords[j], type: 'added' })
        i++
        j++
      }
    }

    while (i < oldWords.length) {
      diff.push({ text: oldWords[i], type: 'removed' })
      i++
    }
    while (j < newWords.length) {
      diff.push({ text: newWords[j], type: 'added' })
      j++
    }

    return diff
  }

  const HighlightedDiff = ({
    oldContent,
    newContent,
  }: {
    oldContent: string
    newContent: string
  }) => {
    const diff = getDiff(oldContent, newContent)

    return (
      <>
        {diff.map((part, index) => (
          <Text
            key={index}
            flexWrap="wrap"
            fontSize="$3"
            allowFontScaling={false}
            color={
              part.type === 'added'
                ? 'green'
                : part.type === 'removed'
                  ? '#D55453'
                  : theme.color.val
            }
            backgroundColor={
              part.type === 'added'
                ? '#F4FCF6'
                : part.type === 'removed'
                  ? '#FCEFEF'
                  : undefined
            }
          >
            {part.text}
            <Text> </Text>
          </Text>
        ))}
      </>
    )
  }
  const RenderItem = useCallback(
    ({ item, index }: { item: any; index: any }) => {
      let prevData = index > 0 ? data[index - 1]?.content : null
      return (
        <View p="$5" bg={theme.backgroundTertiary.val}>
          <YStack gap="$2">
            <XStack gap="$3" flexWrap="wrap">
              <Text fontWeight="bold" color={theme.colorTertiary.val}>
                Version #{index + 1}
              </Text>
              <Text color={theme.colorTertiary.val}>
                Post edited {timeAgo(item?.created_at)}
              </Text>
            </XStack>
            {index > 0 ? (
              <ExpandableText
                text={htmlToTextWithLineBreaks(item.content)}
                thresholdChars={280}
                maxLines={3}
              >
                <HighlightedDiff
                  oldContent={htmlToTextWithLineBreaks(prevData)}
                  newContent={htmlToTextWithLineBreaks(item.content)}
                />
              </ExpandableText>
            ) : (
              <ExpandableText
                text={htmlToTextWithLineBreaks(item.content)}
                thresholdChars={280}
                maxLines={3}
              >
                <Text fontSize="$3" allowFontScaling={false} color={theme.color.val}>
                  {htmlToTextWithLineBreaks(item.content)}
                </Text>
              </ExpandableText>
            )}
          </YStack>
        </View>
      )
    },
    [data]
  )
  if (isPending) {
    return (
      <View flexGrow={1} mt="$5">
        <ActivityIndicator color={theme.color.val} />
      </View>
    )
  }

  if (isError) {
    return <Text>Error: {error?.message}</Text>
  }

  return (
    <ScreenScrollContainer variant="flashlist" header="Edit History">
      {(scrollProps) => (
        <FlashList
          data={filteredData}
          renderItem={RenderItem}
          ItemSeparatorComponent={Separator}
          {...scrollProps}
        />
      )}
    </ScreenScrollContainer>
  )
}
