import React from 'react'
import {
  ActivityIndicator,
  KeyboardAvoidingView,
  ScrollView,
  StyleSheet,
  TouchableOpacity,
  View,
} from 'react-native'
import {useAnalytics} from 'lib/analytics/analytics'
import {Text} from '../../util/text/Text'
import {LoggedOutLayout} from 'view/com/util/layouts/LoggedOutLayout'
import {s} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useOnboardingDispatch} from '#/state/shell'
import {useSessionApi} from '#/state/session'
import {useCreateAccount, submit} from './state'
import {useServiceQuery} from '#/state/queries/service'
import {
  usePreferencesSetBirthDateMutation,
  useSetSaveFeedsMutation,
  DEFAULT_PROD_FEEDS,
} from '#/state/queries/preferences'
import {IS_PROD} from '#/lib/constants'

import {Step1} from './Step1'
import {Step2} from './Step2'
import {Step3} from './Step3'

export function CreateAccount({onPressBack}: {onPressBack: () => void}) {
  const {track, screen} = useAnalytics()
  const pal = usePalette('default')
  const {_} = useLingui()
  const [uiState, uiDispatch] = useCreateAccount()
  const onboardingDispatch = useOnboardingDispatch()
  const {createAccount} = useSessionApi()
  const {mutate: setBirthDate} = usePreferencesSetBirthDateMutation()
  const {mutate: setSavedFeeds} = useSetSaveFeedsMutation()

  React.useEffect(() => {
    screen('CreateAccount')
  }, [screen])

  // fetch service info
  // =

  const {
    data: serviceInfo,
    isFetching: serviceInfoIsFetching,
    error: serviceInfoError,
    refetch: refetchServiceInfo,
  } = useServiceQuery(uiState.serviceUrl)

  React.useEffect(() => {
    if (serviceInfo) {
      uiDispatch({type: 'set-service-description', value: serviceInfo})
      uiDispatch({type: 'set-error', value: ''})
    } else if (serviceInfoError) {
      uiDispatch({
        type: 'set-error',
        value: _(
          msg`Unable to contact your service. Please check your Internet connection.`,
        ),
      })
    }
  }, [_, uiDispatch, serviceInfo, serviceInfoError])

  // event handlers
  // =

  const onPressBackInner = React.useCallback(() => {
    if (uiState.canBack) {
      uiDispatch({type: 'back'})
    } else {
      onPressBack()
    }
  }, [uiState, uiDispatch, onPressBack])

  const onPressNext = React.useCallback(async () => {
    if (!uiState.canNext) {
      return
    }
    if (uiState.step < 3) {
      uiDispatch({type: 'next'})
    } else {
      try {
        await submit({
          onboardingDispatch,
          createAccount,
          uiState,
          uiDispatch,
          _,
        })
        track('Create Account')
        setBirthDate({birthDate: uiState.birthDate})
        if (IS_PROD(uiState.serviceUrl)) {
          setSavedFeeds(DEFAULT_PROD_FEEDS)
        }
      } catch {
        // dont need to handle here
      } finally {
        track('Try Create Account')
      }
    }
  }, [
    uiState,
    uiDispatch,
    track,
    onboardingDispatch,
    createAccount,
    setBirthDate,
    setSavedFeeds,
    _,
  ])

  // rendering
  // =

  return (
    <LoggedOutLayout
      leadin={`Step ${uiState.step}`}
      title={_(msg`Create Account`)}
      description={_(msg`We're so excited to have you join us!`)}>
      <ScrollView testID="createAccount" style={pal.view}>
        <KeyboardAvoidingView behavior="padding">
          <View style={styles.stepContainer}>
            {uiState.step === 1 && (
              <Step1 uiState={uiState} uiDispatch={uiDispatch} />
            )}
            {uiState.step === 2 && (
              <Step2 uiState={uiState} uiDispatch={uiDispatch} />
            )}
            {uiState.step === 3 && (
              <Step3 uiState={uiState} uiDispatch={uiDispatch} />
            )}
          </View>
          <View style={[s.flexRow, s.pl20, s.pr20]}>
            <TouchableOpacity
              onPress={onPressBackInner}
              testID="backBtn"
              accessibilityRole="button">
              <Text type="xl" style={pal.link}>
                <Trans>Back</Trans>
              </Text>
            </TouchableOpacity>
            <View style={s.flex1} />
            {uiState.canNext ? (
              <TouchableOpacity
                testID="nextBtn"
                onPress={onPressNext}
                accessibilityRole="button">
                {uiState.isProcessing ? (
                  <ActivityIndicator />
                ) : (
                  <Text type="xl-bold" style={[pal.link, s.pr5]}>
                    <Trans>Next</Trans>
                  </Text>
                )}
              </TouchableOpacity>
            ) : serviceInfoError ? (
              <TouchableOpacity
                testID="retryConnectBtn"
                onPress={() => refetchServiceInfo()}
                accessibilityRole="button"
                accessibilityLabel={_(msg`Retry`)}
                accessibilityHint=""
                accessibilityLiveRegion="polite">
                <Text type="xl-bold" style={[pal.link, s.pr5]}>
                  <Trans>Retry</Trans>
                </Text>
              </TouchableOpacity>
            ) : serviceInfoIsFetching ? (
              <>
                <ActivityIndicator color="#fff" />
                <Text type="xl" style={[pal.text, s.pr5]}>
                  <Trans>Connecting...</Trans>
                </Text>
              </>
            ) : undefined}
          </View>
          <View style={s.footerSpacer} />
        </KeyboardAvoidingView>
      </ScrollView>
    </LoggedOutLayout>
  )
}

const styles = StyleSheet.create({
  stepContainer: {
    paddingHorizontal: 20,
    paddingVertical: 20,
  },
})
