import { useNavigation } from '@react-navigation/native'
import React, { useContext, useEffect } from 'react'
import { View, Text, StyleSheet } from 'react-native'

import { TextStyles } from '../Styles'
import { UserContext } from '../contexts/UserContext'
import { useAsyncStorage } from '../hooks/useAsyncStore'
import { useNetwork } from '../hooks/useNetwork'
import { Strings } from '../i18n'
import * as SecureStore from '../secure-store'
import { InfoModal } from './InfoModal'
import { useGet } from './Network'

interface Bulletin {
  id: string
  body: string
  title: string
}

function useDismissedBulletins(): [Set<string>, (id: string) => void] {
  const [dismissedBulletinIds, setDismissedBulletinIds] = useAsyncStorage<
    Set<string>
  >(
    SecureStore.Key.DISMISSED_BULLETIN_IDS,
    {
      serialize: (set: Set<string>) => JSON.stringify(Array.from(set)),
      deserialize: (string: string) => new Set(JSON.parse(string)),
    },
    new Set<string>()
  )

  const dismissBulletinId = (id: string) => {
    const newSet = new Set<string>(id)
    dismissedBulletinIds?.forEach((id) => newSet.add(id))
    setDismissedBulletinIds(newSet)
  }

  return [dismissedBulletinIds ?? new Set<string>(), dismissBulletinId]
}

const styles = StyleSheet.create({
  bulletin: {
    ...TextStyles.body,
    marginBottom: 14,
  },
  subHeading: {
    ...TextStyles.tinyCaps,
    marginBottom: 8,
  },
  timeFrame: {
    marginTop: 32,
  },
})

export const Bulletins: React.FC = () => {
  const path = `api/bulletins`
  const user = useContext(UserContext)
  // eslint-disable-next-line @typescript-eslint/no-empty-function
  const response = useNetwork<Bulletin[]>(useGet(path, user))
  const { retry } = response
  const navigation = useNavigation()

  // Revalidate bulletins every time screen it's rendered on is focused
  useEffect(() => navigation.addListener('focus', retry), [navigation, retry])

  const [dismissedBulletinIds, dismissBulletinId] = useDismissedBulletins()

  const bulletins =
    response?.data &&
    response?.data?.filter(
      (bulletin) => !dismissedBulletinIds?.has(bulletin.id)
    )

  const bulletin = bulletins?.[0]

  if (!bulletin) return null

  return (
    <View style={styles.timeFrame}>
      <Text style={styles.subHeading}>{Strings.Shared.Bulletin}</Text>
      <InfoModal
        title={bulletin.title}
        body={{ type: 'html', html: bulletin.body }}
      >
        {(open) => (
          <View
            style={{
              flexDirection: 'row',
              flexGrow: 1,
              alignContent: 'space-between',
            }}
          >
            <Text style={[styles.bulletin, { color: 'white' }]} onPress={open}>
              {bulletin.title}...
            </Text>
            <Text
              style={styles.bulletin}
              onPress={() => dismissBulletinId(bulletin.id)}
            >
              {'   x'}
            </Text>
          </View>
        )}
      </InfoModal>
    </View>
  )
}
