import {RouteProp} from '@react-navigation/native';
import {StackNavigationProp} from '@react-navigation/stack';
import React from 'react';
import {
  Alert,
  KeyboardAvoidingView,
  Platform,
  StyleSheet,
  TouchableOpacity,
  View,
} from 'react-native';
import {Text} from 'react-native-animatable';
import {
  CodeField,
  Cursor,
  useBlurOnFulfill,
  useClearByFocusCell,
} from 'react-native-confirmation-code-field';
import {trackPromise} from 'react-promise-tracker';
import {
  ArrowButton,
  Background,
  LoadingIndicator,
  RegistrationWizard,
  SubmitButton,
} from '../../components';
import {codeRegex} from '../../constants';
import {
  ERROR_INVALID_VERIFICATION_CODE_FORMAT,
  ERROR_SOMETHING_WENT_WRONG,
} from '../../constants/strings';
import {OnboardingStackParams} from '../../routes';
import {
  handlePasswordCodeVerification,
  handlePasswordResetRequest,
  sendOtp,
  verifyOtp,
} from '../../services';
import {BackgroundGradientType, VerificationScreenType} from '../../types';

type VerificationScreenRouteProp = RouteProp<
  OnboardingStackParams,
  'Verification'
>;
type VerificationScreenNavigationProp = StackNavigationProp<
  OnboardingStackParams,
  'Verification'
>;
interface VerificationProps {
  route: VerificationScreenRouteProp;
  navigation: VerificationScreenNavigationProp;
}

const Verification: React.FC<VerificationProps> = ({route, navigation}) => {
  const [value, setValue] = React.useState('');
  const ref = useBlurOnFulfill({value, cellCount: 6});
  const [valueProps, getCellOnLayoutHandler] = useClearByFocusCell({
    value,
    setValue,
  });
  const {id, screenType} = route.params;
  const isPhoneVerification = screenType === VerificationScreenType.Phone;

  const handlePhoneVerification = async () => {
    const success = await trackPromise(verifyOtp(id, value));
    if (success) {
      navigation.navigate('RegistrationTwo', {phone: id});
    }
  };

  const handlePasswordVerification = async () => {
    const success = await trackPromise(
      handlePasswordCodeVerification(id, value),
    );
    if (success) {
      navigation.navigate('PasswordReset', {value: id});
    }
  };

  /**
   * Sends the verify_otp request upon tapping the Verify button.
   * If successful, it navigates to the respected page.
   */
  const handleVerification = async () => {
    if (codeRegex.test(value)) {
      try {
        switch (screenType) {
          case VerificationScreenType.Phone:
            handlePhoneVerification();
            break;
          case VerificationScreenType.Password:
            handlePasswordVerification();
            break;
        }
      } catch (error) {
        console.log(error);
        Alert.alert(ERROR_SOMETHING_WENT_WRONG);
      }
    } else {
      Alert.alert(ERROR_INVALID_VERIFICATION_CODE_FORMAT);
    }
  };

  /**
   * Sends the send_otp request so to provide a new verification code upon tapping the Resend Code button.
   */
  const handleResend = async () => {
    try {
      switch (screenType) {
        case VerificationScreenType.Phone:
          trackPromise(sendOtp(id));
          break;
        case VerificationScreenType.Password:
          trackPromise(handlePasswordResetRequest(id));
          break;
      }
    } catch (error) {
      console.log(error);
      Alert.alert(ERROR_SOMETHING_WENT_WRONG);
    }
  };

  const handleGoBack = () => {
    switch (screenType) {
      case VerificationScreenType.Phone:
        navigation.navigate('RegistrationOne');
        break;
      case VerificationScreenType.Password:
        navigation.navigate('PasswordResetRequest');
        break;
    }
  };

  const Footer = () => (
    <View style={styles.footer}>
      <ArrowButton direction="backward" onPress={() => handleGoBack()} />
    </View>
  );

  return (
    <Background
      centered
      style={styles.container}
      gradientType={BackgroundGradientType.Light}>
      {isPhoneVerification ? (
        <RegistrationWizard style={styles.wizard} step="three" />
      ) : (
        <React.Fragment />
      )}
      <KeyboardAvoidingView
        behavior="padding"
        style={
          isPhoneVerification ? styles.form : styles.formPasswordVerification
        }>
        <Text style={styles.formHeader}>Enter 6 digit code</Text>
        <Text style={styles.description}>
          We sent a 6 digit verification code to the phone number you provided.
        </Text>
        <CodeField
          ref={ref}
          {...valueProps}
          value={value}
          onChangeText={setValue}
          cellCount={6}
          rootStyle={styles.codeFieldRoot}
          keyboardType="number-pad"
          textContentType="oneTimeCode"
          renderCell={({index, symbol, isFocused}) => (
            <View
              onLayout={getCellOnLayoutHandler(index)}
              key={index}
              style={[styles.cellRoot, isFocused && styles.focusCell]}>
              <Text style={styles.cellText}>
                {symbol || (isFocused ? <Cursor /> : null)}
              </Text>
            </View>
          )}
        />
        <SubmitButton
          text="Verify"
          color="#fff"
          style={styles.button}
          accessibilityLabel="Verify"
          accessibilityHint="Select this after entering your phone number verification code"
          onPress={handleVerification}
        />
        <TouchableOpacity onPress={handleResend}>
          <Text style={styles.resend}>Resend Code</Text>
        </TouchableOpacity>
        <LoadingIndicator />
      </KeyboardAvoidingView>
      <Footer />
    </Background>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  wizard: {
    marginTop: '3.5%',
    flex: 1,
    justifyContent: 'center',
  },
  form: {
    alignItems: 'center',
    justifyContent: 'flex-start',
    flex: 3,
  },
  formPasswordVerification: {
    alignItems: 'center',
    justifyContent: 'flex-start',
    flex: 3,
    top: '25%',
  },
  formHeader: {
    color: '#fff',
    fontSize: 20,
    fontWeight: 'bold',
    alignSelf: 'flex-start',
    marginBottom: '6%',
    marginHorizontal: '10%',
  },
  description: {
    color: '#fff',
    fontWeight: '600',
    fontSize: 17,
    marginHorizontal: '10%',
  },
  resend: {
    textDecorationLine: 'underline',
    color: '#fff',
    fontSize: 15,
    fontWeight: '600',
  },
  codeFieldRoot: {
    width: 280,
    marginHorizontal: 'auto',
    marginVertical: '15%',
  },
  cellRoot: {
    width: 40,
    height: 60,
    justifyContent: 'center',
    alignItems: 'center',
    borderBottomColor: '#fff',
    borderBottomWidth: 1,
  },
  cellText: {
    color: '#fff',
    fontSize: 48,
    textAlign: 'center',
  },
  focusCell: {
    borderBottomColor: '#78a0ef',
    borderBottomWidth: 2,
  },
  button: {
    marginVertical: '5%',
  },
  loadingIndicator: {
    marginVertical: '5%',
  },
  footer: {
    width: '100%',
    flexDirection: 'row',
    justifyContent: 'space-around',
    ...Platform.select({
      ios: {
        bottom: '20%',
      },
      android: {
        bottom: '10%',
      },
    }),
  },
});
export default Verification;
