import React, { useContext, useEffect, useState } from 'react'
import {
  Clipboard,
  Dimensions,
  FlatList,
  ListRenderItem,
  ScrollView,
  StyleSheet,
  View,
} from 'react-native'
import { AppContext } from '../../Contexts/AppContext'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import { EventKind } from '../../lib/nostr/Events'
import {
  DirectMessage,
  getGroupedDirectMessages,
} from '../../Functions/DatabaseFunctions/DirectMessages'
import { getUsers, User } from '../../Functions/DatabaseFunctions/Users'
import { getOtherPubKey } from '../../Functions/RelayFunctions/DirectMessages'
import { NostrosAvatar } from '../../Components/NostrosAvatar'
import { formatPubKey, username } from '../../Functions/RelayFunctions/Users'
import {
  AnimatedFAB,
  Badge,
  Button,
  Divider,
  List,
  Text,
  TextInput,
  TouchableRipple,
  useTheme,
} from 'react-native-paper'
import { UserContext } from '../../Contexts/UserContext'
import { navigate } from '../../lib/Navigation'
import moment from 'moment'
import RBSheet from 'react-native-raw-bottom-sheet'
import { useTranslation } from 'react-i18next'
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'

export const ConversationsFeed: React.FC = () => {
  const theme = useTheme()
  const { t } = useTranslation('common')
  const { database } = useContext(AppContext)
  const { publicKey, privateKey } = useContext(UserContext)
  const { relayPool, lastEventId } = useContext(RelayPoolContext)
  const [directMessages, settDirectMessages] = useState<DirectMessage[]>([])
  const [sendPubKeyInput, setSendPubKeyInput] = useState<string>('')
  const [users, setUsers] = useState<User[]>()
  const bottomSheetCreateRef = React.useRef<RBSheet>(null)
  const bottomSheetUserListRef = React.useRef<RBSheet>(null)
  const bottomSheetPubKeyRef = React.useRef<RBSheet>(null)

  useEffect(() => {
    loadDirectMessages()
  }, [lastEventId])

  useEffect(() => {
    loadDirectMessages()
    subscribeDirectMessages()
  }, [])

  const loadDirectMessages: () => void = () => {
    if (database && publicKey) {
      getGroupedDirectMessages(database, {}).then((results) => {
        if (results && results.length > 0) {
          settDirectMessages(results)
          const otherUsers = results.map((message) => getOtherPubKey(message, publicKey))
          relayPool?.subscribe('directmessages-meta', [
            {
              kinds: [EventKind.meta],
              authors: otherUsers,
            },
          ])
          getUsers(database, { contacts: true }).then(setUsers)
        }
      })
    }
  }

  const subscribeDirectMessages: () => void = async () => {
    relayPool?.unsubscribeAll()
    if (publicKey) {
      relayPool?.subscribe('directmessages-user', [
        {
          kinds: [EventKind.directMessage],
          authors: [publicKey],
        },
        {
          kinds: [EventKind.directMessage],
          '#p': [publicKey],
        },
      ])
    }
  }

  const renderConversationItem: ListRenderItem<DirectMessage> = ({ index, item }) => {
    if (!publicKey || !privateKey) return <></>

    const otherPubKey = getOtherPubKey(item, publicKey)
    const user: User = users?.find((user) => user.id === otherPubKey) ?? { id: otherPubKey }

    return (
      <TouchableRipple
        onPress={() =>
          navigate('Conversation', { pubKey: user.id, conversationId: item.conversation_id })
        }
      >
        <View key={user.id} style={styles.contactRow}>
          <View style={styles.contactUser}>
            <NostrosAvatar
              name={user.name}
              pubKey={user.id}
              src={user.picture}
              lud06={user.lnurl}
              size={40}
            />
            <View style={styles.contactName}>
              <Text variant='titleSmall'>{username(user)}</Text>
            </View>
          </View>
          <View style={styles.contactInfo}>
            <View style={styles.contactName}>
              <Text>{moment.unix(item.created_at).format('HH:mm DD-MM-YY')}</Text>
              {!item.read && <Badge size={16}></Badge>}
            </View>
          </View>
        </View>
      </TouchableRipple>
    )
  }

  const pastePubKey: () => void = () => {
    Clipboard.getString().then((value) => {
      setSendPubKeyInput(value ?? '')
    })
  }

  const bottomSheetStyles = React.useMemo(() => {
    return {
      container: {
        backgroundColor: theme.colors.background,
        padding: 16,
        borderTopRightRadius: 28,
        borderTopLeftRadius: 28,
      },
      draggableIcon: {
        backgroundColor: '#000',
      },
    }
  }, [])

  const createOptions = React.useMemo(() => {
    return [
      {
        key: 1,
        title: t('conversationsFeed.newMessageContact'),
        left: () => (
          <List.Icon
            icon={() => <MaterialCommunityIcons name='account-multiple-plus-outline' size={25} />}
          />
        ),
        onPress: async () => bottomSheetUserListRef.current?.open(),
      },
      {
        key: 2,
        title: t('conversationsFeed.addPubKey'),
        left: () => (
          <List.Icon
            icon={() => <MaterialCommunityIcons name='account-multiple-plus-outline' size={25} />}
          />
        ),
        onPress: async () => bottomSheetPubKeyRef.current?.open(),
      },
    ]
  }, [])

  const renderUserItem: ListRenderItem<User> = ({ index, item }) => (
    <TouchableRipple onPress={() => {}}>
      <View key={item.id} style={styles.contactRow}>
        <View style={styles.contactUser}>
          <NostrosAvatar
            name={item.name}
            pubKey={item.id}
            src={item.picture}
            lud06={item.lnurl}
            size={40}
          />
          <View style={styles.contactName}>
            <Text variant='titleSmall'>{formatPubKey(item.id)}</Text>
            {item.name && <Text variant='titleSmall'>{username(item)}</Text>}
          </View>
        </View>
      </View>
    </TouchableRipple>
  )

  return (
    <View>
      <ScrollView horizontal={false}>
        <FlatList
          data={directMessages}
          renderItem={renderConversationItem}
          ItemSeparatorComponent={Divider}
        />
      </ScrollView>
      <AnimatedFAB
        style={[styles.fab, { top: Dimensions.get('window').height - 220 }]}
        icon='pencil-outline'
        label='Label'
        onPress={() => bottomSheetCreateRef.current?.open()}
        animateFrom='right'
        iconMode='static'
        extended={false}
      />
      <RBSheet
        ref={bottomSheetCreateRef}
        closeOnDragDown={true}
        height={190}
        customStyles={bottomSheetStyles}
      >
        <ScrollView horizontal={false}>
          <FlatList
            data={createOptions}
            renderItem={({ item }) => {
              return (
                <List.Item
                  key={item.key}
                  title={item.title}
                  onPress={item.onPress}
                  left={item.left}
                />
              )
            }}
            ItemSeparatorComponent={Divider}
          />
        </ScrollView>
      </RBSheet>
      <RBSheet
        ref={bottomSheetUserListRef}
        closeOnDragDown={true}
        height={620}
        customStyles={bottomSheetStyles}
      >
        <ScrollView horizontal={false}>
          <FlatList data={users} renderItem={renderUserItem} ItemSeparatorComponent={Divider} />
        </ScrollView>
      </RBSheet>
      <RBSheet
        ref={bottomSheetPubKeyRef}
        closeOnDragDown={true}
        height={220}
        customStyles={bottomSheetStyles}
      >
        <View>
          <Text variant='titleLarge'>{t('conversationsFeed.openMessageTitle')}</Text>
          <Text variant='bodyMedium'>{t('conversationsFeed.openMessageDescription')}</Text>
          <TextInput
            mode='outlined'
            label={t('conversationsFeed.openMessage') ?? ''}
            onChangeText={setSendPubKeyInput}
            value={sendPubKeyInput}
            right={
              <TextInput.Icon
                icon='content-paste'
                onPress={pastePubKey}
                forceTextInputFocus={false}
              />
            }
          />
          <Button
            mode='contained'
            disabled={!sendPubKeyInput || sendPubKeyInput === ''}
            onPress={() => navigate('Conversation', { pubKey: sendPubKeyInput })}
          >
            {t('conversationsFeed.openMessage')}
          </Button>
        </View>
      </RBSheet>
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  contactRow: {
    paddingLeft: 16,
    paddingRight: 16,
    paddingTop: 16,
    flexDirection: 'row',
    justifyContent: 'space-between',
    width: '100%',
  },
  contactName: {
    paddingLeft: 16,
  },
  contactUser: {
    flexDirection: 'row',
    alignContent: 'center',
  },
  contactInfo: {
    alignContent: 'center',
    justifyContent: 'space-between',
  },
  contactFollow: {
    justifyContent: 'center',
  },
  fab: {
    right: 16,
    position: 'absolute',
  },
})

export default ConversationsFeed
