import Button from '@components/Button'
import Icon from '@components/Icon'
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
import { useAppsQuery } from '@utils/queryHooks/apps'
import { useInstanceQuery } from '@utils/queryHooks/instance'
import { getInstances } from '@utils/slices/instancesSlice'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import * as WebBrowser from 'expo-web-browser'
import { debounce } from 'lodash'
import React, { RefObject, useCallback, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import {
  Alert,
  Image,
  KeyboardAvoidingView,
  Platform,
  StyleSheet,
  Text,
  TextInput,
  View
} from 'react-native'
import { ScrollView } from 'react-native-gesture-handler'
import { useSelector } from 'react-redux'
import { Placeholder } from 'rn-placeholder'
import analytics from './analytics'
import InstanceAuth from './Instance/Auth'
import InstanceInfo from './Instance/Info'

export interface Props {
  scrollViewRef?: RefObject<ScrollView>
  disableHeaderImage?: boolean
  goBack?: boolean
}

const ComponentInstance: React.FC<Props> = ({
  scrollViewRef,
  disableHeaderImage,
  goBack = false
}) => {
  const { t } = useTranslation('componentInstance')
  const { mode, theme } = useTheme()
  const { screenReaderEnabled } = useAccessibility()

  const instances = useSelector(getInstances, () => true)
  const [domain, setDomain] = useState<string>()

  const instanceQuery = useInstanceQuery({
    domain,
    options: { enabled: !!domain, retry: false }
  })
  const appsQuery = useAppsQuery({
    domain,
    options: { enabled: false, retry: false }
  })

  const onChangeText = useCallback(
    debounce(
      text => {
        setDomain(text.replace(/^http(s)?\:\/\//i, ''))
        appsQuery.remove()
      },
      1000,
      { trailing: true }
    ),
    []
  )

  const processUpdate = useCallback(() => {
    if (domain) {
      analytics('instance_login')
      if (
        instances &&
        instances.filter(instance => instance.url === domain).length
      ) {
        Alert.alert(t('update.alert.title'), t('update.alert.message'), [
          {
            text: t('update.alert.buttons.cancel'),
            style: 'cancel'
          },
          {
            text: t('update.alert.buttons.continue'),
            onPress: () => {
              appsQuery.refetch()
            }
          }
        ])
      } else {
        appsQuery.refetch()
      }
    }
  }, [domain])

  const onSubmitEditing = useCallback(
    ({ nativeEvent: { text } }) => {
      analytics('instance_textinput_submit', { match: text === domain })
      if (
        text === domain &&
        instanceQuery.isSuccess &&
        instanceQuery.data &&
        instanceQuery.data.uri
      ) {
        processUpdate()
      }
    },
    [domain, instanceQuery.isSuccess, instanceQuery.data]
  )

  const requestAuth = useMemo(() => {
    if (
      domain &&
      instanceQuery.data?.uri &&
      appsQuery.data?.client_id &&
      appsQuery.data.client_secret
    ) {
      return (
        <InstanceAuth
          key={Math.random()}
          instanceDomain={domain}
          instance={instanceQuery.data}
          appData={{
            clientId: appsQuery.data.client_id,
            clientSecret: appsQuery.data.client_secret
          }}
          goBack={goBack}
        />
      )
    }
  }, [domain, instanceQuery.data, appsQuery.data])

  return (
    <KeyboardAvoidingView
      style={{ flex: 1 }}
      behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
    >
      {!disableHeaderImage ? (
        <View style={styles.imageContainer}>
          <Image
            source={require('assets/images/welcome.png')}
            style={styles.image}
          />
        </View>
      ) : null}
      <View style={styles.base}>
        <View style={styles.inputRow}>
          <TextInput
            accessible={false}
            accessibilityRole='none'
            style={[
              styles.prefix,
              {
                color: theme.primaryDefault,
                borderBottomColor: instanceQuery.isError
                  ? theme.red
                  : theme.border
              }
            ]}
            editable={false}
            defaultValue='https://'
          />
          <TextInput
            style={[
              styles.textInput,
              {
                color: theme.primaryDefault,
                borderBottomColor: instanceQuery.isError
                  ? theme.red
                  : theme.border
              }
            ]}
            onChangeText={onChangeText}
            autoCapitalize='none'
            clearButtonMode='never'
            keyboardType='url'
            textContentType='URL'
            onSubmitEditing={onSubmitEditing}
            placeholder={' ' + t('server.textInput.placeholder')}
            placeholderTextColor={theme.secondary}
            returnKeyType='go'
            keyboardAppearance={mode}
            {...(scrollViewRef && {
              onFocus: () =>
                setTimeout(() => scrollViewRef.current?.scrollToEnd(), 150)
            })}
            autoCorrect={false}
            spellCheck={false}
          />
          <Button
            type='text'
            content={t('server.button')}
            onPress={processUpdate}
            disabled={!instanceQuery.data?.uri}
            loading={instanceQuery.isFetching || appsQuery.isFetching}
          />
        </View>

        <View>
          <Placeholder>
            <InstanceInfo
              header={t('server.information.name')}
              content={instanceQuery.data?.title || undefined}
              potentialWidth={2}
            />
            <View style={styles.instanceStats}>
              <InstanceInfo
                style={styles.stat1}
                header={t('server.information.accounts')}
                content={
                  instanceQuery.data?.stats?.user_count?.toString() || undefined
                }
                potentialWidth={4}
              />
              <InstanceInfo
                style={styles.stat2}
                header={t('server.information.statuses')}
                content={
                  instanceQuery.data?.stats?.status_count?.toString() ||
                  undefined
                }
                potentialWidth={4}
              />
              <InstanceInfo
                style={styles.stat3}
                header={t('server.information.domains')}
                content={
                  instanceQuery.data?.stats?.domain_count?.toString() ||
                  undefined
                }
                potentialWidth={4}
              />
            </View>
          </Placeholder>
          <View style={styles.disclaimer}>
            <Icon
              name='Lock'
              size={StyleConstants.Font.Size.S}
              color={theme.secondary}
              style={styles.disclaimerIcon}
            />
            <Text
              style={[styles.disclaimerText, { color: theme.secondary }]}
              accessibilityRole='link'
              onPress={() => {
                if (screenReaderEnabled) {
                  analytics('view_privacy')
                  WebBrowser.openBrowserAsync(
                    'https://tooot.app/privacy-policy'
                  )
                }
              }}
            >
              {t('server.disclaimer.base')}
              <Text
                accessible
                style={{ color: theme.blue }}
                onPress={() => {
                  analytics('view_privacy')
                  WebBrowser.openBrowserAsync(
                    'https://tooot.app/privacy-policy'
                  )
                }}
              >
                {t('server.disclaimer.privacy')}
              </Text>
            </Text>
          </View>
        </View>
      </View>

      {requestAuth}
    </KeyboardAvoidingView>
  )
}

const styles = StyleSheet.create({
  imageContainer: { flexDirection: 'row' },
  image: { resizeMode: 'contain', flex: 1, aspectRatio: 16 / 9 },
  base: {
    marginVertical: StyleConstants.Spacing.L,
    marginHorizontal: StyleConstants.Spacing.Global.PagePadding
  },
  inputRow: {
    flexDirection: 'row',
    marginHorizontal: StyleConstants.Spacing.Global.PagePadding
  },
  prefix: {
    borderBottomWidth: 1,
    ...StyleConstants.FontStyle.M
  },
  textInput: {
    flex: 1,
    borderBottomWidth: 1,
    ...StyleConstants.FontStyle.M,
    marginRight: StyleConstants.Spacing.M
  },
  instanceStats: {
    flex: 1,
    flexDirection: 'row'
  },
  stat1: {
    alignItems: 'flex-start'
  },
  stat2: {
    alignItems: 'center'
  },
  stat3: {
    alignItems: 'flex-end'
  },
  disclaimer: {
    flexDirection: 'row',
    marginHorizontal: StyleConstants.Spacing.Global.PagePadding,
    marginVertical: StyleConstants.Spacing.M
  },
  disclaimerIcon: {
    marginTop:
      (StyleConstants.Font.LineHeight.S - StyleConstants.Font.Size.S) / 2,
    marginRight: StyleConstants.Spacing.XS
  },
  disclaimerText: {
    flex: 1,
    ...StyleConstants.FontStyle.S
  }
})

export default ComponentInstance
