import {StackNavigationProp} from '@react-navigation/stack';
import React, {useMemo, useRef, useState} from 'react';
import {
  Alert,
  KeyboardAvoidingView,
  Platform,
  StatusBar,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import {
  ArrowButton,
  Background,
  RegistrationWizard,
  TaggInput,
} from '../../../components';
import {nameRegex, phoneRegex} from '../../../constants';
import {
  ERROR_NEXT_PAGE,
  ERROR_PHONE_IN_USE,
  ERROR_TWILIO_SERVER_ERROR,
} from '../../../constants/strings';
import {OnboardingStackParams} from '../../../routes';
import {sendOtpStatusCode} from '../../../services';
import {BackgroundGradientType} from '../../../types';
import {SCREEN_HEIGHT} from '../../../utils';

type OnboardingStepOneNavigationProp = StackNavigationProp<
  OnboardingStackParams,
  'OnboardingStepOne'
>;
interface OnboardingStepOneProps {
  navigation: OnboardingStepOneNavigationProp;
}

const OnboardingStepOne: React.FC<OnboardingStepOneProps> = ({navigation}) => {
  const lnameRef = useRef();
  const emailRef = useRef();
  const phoneRef = useRef();

  const handleFocusChange = (field: string): void => {
    switch (field) {
      case 'lname':
        const lnameField: any = lnameRef.current;
        lnameField.focus();
        break;
      case 'email':
        const emailField: any = emailRef.current;
        emailField.focus();
        break;
      case 'phone':
        const phoneField: any = phoneRef.current;
        phoneField.focus();
        break;
      default:
        return;
    }
  };

  const [form, setForm] = useState({
    fname: '',
    lname: '',
    phone: '',
    isValidFname: false,
    isValidLname: false,
    isValidPhone: false,
    attemptedSubmit: false,
    token: '',
  });

  const handleFnameUpdate = (fname: string) => {
    fname = fname.trim();
    let isValidFname: boolean = nameRegex.test(fname);
    setForm({
      ...form,
      fname,
      isValidFname,
    });
  };

  const handleLnameUpdate = (lname: string) => {
    lname = lname.trim();
    let isValidLname: boolean = nameRegex.test(lname);
    setForm({
      ...form,
      lname,
      isValidLname,
    });
  };

  const handlePhoneUpdate = (phone: string) => {
    phone = phone.trim();
    let isValidPhone: boolean = phoneRegex.test(phone);
    setForm({
      ...form,
      phone,
      isValidPhone,
    });
  };

  const goNext = async () => {
    if (!form.attemptedSubmit) {
      setForm({
        ...form,
        attemptedSubmit: true,
      });
    }
    try {
      const {isValidFname, isValidLname, isValidPhone} = form;
      if (isValidFname && isValidLname && isValidPhone) {
        const {phone} = form;
        const code = await sendOtpStatusCode(phone);
        if (code) {
          switch (code) {
            case 200:
              const {fname, lname} = form;
              navigation.navigate('PhoneVerification', {
                firstName: fname,
                lastName: lname,
                phone,
              });
              break;
            case 409:
              Alert.alert(ERROR_PHONE_IN_USE);
              break;
            default:
              Alert.alert(ERROR_TWILIO_SERVER_ERROR);
          }
        }
      } else {
        setForm({...form, attemptedSubmit: false});
        setTimeout(() => setForm({...form, attemptedSubmit: true}));
      }
    } catch (error) {
      Alert.alert(ERROR_NEXT_PAGE);
      return {
        name: 'Navigation error',
        description: error,
      };
    }
  };

  const footer = useMemo(
    () => (
      <View style={styles.footer}>
        <ArrowButton
          direction="backward"
          onPress={() => navigation.navigate('Login')}
        />
        <TouchableOpacity onPress={goNext}>
          <ArrowButton
            direction="forward"
            disabled={
              !(form.isValidFname && form.isValidLname && form.isValidPhone)
            }
            onPress={goNext}
          />
        </TouchableOpacity>
      </View>
    ),
    [
      form.fname,
      form.lname,
      form.phone,
      form.isValidFname,
      form.isValidLname,
      form.isValidPhone,
    ],
  );

  return (
    <Background
      style={styles.container}
      gradientType={BackgroundGradientType.Light}>
      <StatusBar barStyle="light-content" />
      <RegistrationWizard style={styles.wizard} step="one" />
      <KeyboardAvoidingView
        behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
        style={styles.container}>
        <View>
          <Text style={styles.formHeader}>ENTER NAME</Text>
        </View>
        <TaggInput
          accessibilityHint="Enter your first name."
          accessibilityLabel="First name input field."
          placeholder="First Name"
          autoCompleteType="name"
          textContentType="name"
          returnKeyType="next"
          onChangeText={handleFnameUpdate}
          onSubmitEditing={() => handleFocusChange('lname')}
          blurOnSubmit={false}
          valid={form.isValidFname}
          invalidWarning="Please enter a valid first name."
          attemptedSubmit={form.attemptedSubmit}
          width={280}
        />
        <TaggInput
          accessibilityHint="Enter your last name."
          accessibilityLabel="Last name input field."
          placeholder="Last Name"
          autoCompleteType="name"
          textContentType="name"
          returnKeyType="next"
          onChangeText={handleLnameUpdate}
          blurOnSubmit={false}
          ref={lnameRef}
          valid={form.isValidLname}
          invalidWarning="Please enter a valid last name."
          attemptedSubmit={form.attemptedSubmit}
          width={280}
        />
        <TaggInput
          maxLength={10} // currently only support US phone numbers
          accessibilityHint="Enter your phone number."
          accessibilityLabel="Phone number input field."
          placeholder="Phone Number"
          autoCompleteType="tel"
          textContentType="telephoneNumber"
          autoCapitalize="none"
          keyboardType="number-pad"
          onChangeText={handlePhoneUpdate}
          blurOnSubmit={false}
          ref={phoneRef}
          valid={form.isValidPhone}
          invalidWarning={'Please enter a valid 10 digit number.'}
          attemptedSubmit={form.attemptedSubmit}
          width={280}
          onSubmitEditing={goNext}
        />
      </KeyboardAvoidingView>
      {footer}
    </Background>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  wizard: {
    position: 'absolute',
    top: SCREEN_HEIGHT * 0.1,
  },
  formHeader: {
    color: '#fff',
    fontSize: 30,
    fontWeight: '600',
    marginBottom: '16%',
  },
  load: {
    top: '5%',
  },
  footer: {
    width: '100%',
    flexDirection: 'row',
    justifyContent: 'space-around',
    ...Platform.select({
      ios: {
        bottom: '20%',
      },
      android: {
        bottom: '10%',
      },
    }),
  },
});

export default OnboardingStepOne;
