import React, {FC, useState, useEffect} from 'react';
import {AxiosResponse} from 'axios';
import {useForm, Controller} from 'react-hook-form';
import {useNavigation, StackActions} from '@react-navigation/native';
import NetInfo from '@react-native-community/netinfo';
import {useGet} from '@hooks/api';
import {TEST_USER_MOBILE_NUMBER} from '@constants/api';
import ErrorModal from '@components/ErrorModal';
import TextInput from '@components/TextInput';
import Button from '@components/Button';
import Checkbox from '@components/Checkbox';
import {FormData, IAuthProps} from '@components/Auth/types';
// import {SdkService} from '@services/AffinidiSDKService';
import useTncContext from '@contexts/tnc';
import useUserContext from '@contexts/user';
import useLoaderContext from '@contexts/loader';
import {CHECK_USER_REGISTRATION, SIGN_IN_PASSWORD_LESS} from '@constants/api';
import {cloudWalletServiceInstance} from '@services/Axios';
import {ONBOARDING, LOGIN, OTP} from '@constants/navigation/onboarding';
import {TERMS_AND_CONDITION} from '@constants/navigation/terms-and-condition';
import {
  BodyWrapper,
  Body,
  SubmitButton,
  otpButtonStyle,
  Field,
  TermsAndCondition,
  TermsAndConditionText,
  TermsAndConditionButton,
} from '@styles/components/auth';

const Form: FC<IAuthProps> = ({isSignUpScreen}) => {
  const [focus, setFocus] = useState<boolean>(false);
  const [error, setError] = useState<string>();
  const [isOffline, setOfflineStatus] = useState(false);
  const {value: tncValue, setValue} = useTncContext();
  const {setLoginToken, setPhoneNumber} = useUserContext();
  const navigation = useNavigation();

  useEffect(() => {
    const removeNetInfoSubscription = NetInfo.addEventListener(state => {
      const offline = !(state.isConnected && state.isInternetReachable);
      setOfflineStatus(offline);
    });

    return () => removeNetInfoSubscription();
  }, []);

  const {
    control,
    handleSubmit,
    formState: {errors, isValid},
    getValues,
  } = useForm<FormData>({
    mode: 'onChange',
    reValidateMode: 'onChange',
  });

  const {refetch} = useGet(
    CHECK_USER_REGISTRATION,
    `${CHECK_USER_REGISTRATION}?userId=${getValues('phoneNumber')}`,
    {
      enabled: false,
    },
  );
  const {showLoader, hideLoader} = useLoaderContext();

  const onSubmit = async (data: FormData) => {
    try {
      const isTestUser = data?.phoneNumber === TEST_USER_MOBILE_NUMBER;

      const checkUserStatus = await refetch();

      const userExist = checkUserStatus?.data?.data?.success;

      if (isSignUpScreen && userExist && !isOffline) {
        return setError(
          "This mobile number is already registered with us. Please 'Login' with your registered number to access Asli wallet",
        );
      } else if (!isSignUpScreen && !userExist && !isOffline) {
        return setError(
          "This mobile number is not registered with us. Please 'Sign up' with your mobile number to access Asli wallet.",
        );
      }

      if (isTestUser) {
        await setPhoneNumber(data?.phoneNumber);
        navigation.dispatch(StackActions.push(OTP.SCREEN, {isSignUpScreen}));
      } else {
        showLoader();
        // const logInToken = await SdkService.initiateSignInPasswordless(
        //   data?.phoneNumber,
        // );
        const response: AxiosResponse = await cloudWalletServiceInstance.post(
          SIGN_IN_PASSWORD_LESS,
          {username: `+91${data?.phoneNumber}`},
        );
        hideLoader();
        const logInToken = response?.data;

        if (typeof logInToken === 'object' && logInToken?.error) {
          setError(logInToken?.error);
        } else if (typeof logInToken === 'string') {
          await setPhoneNumber(data?.phoneNumber);
          await setLoginToken(logInToken);
          navigation.dispatch(StackActions.push(OTP.SCREEN, {isSignUpScreen}));
        }
      }
    } catch (e: any) {
      setError(e?.message);
      throw new Error(`${e?.message} [${data?.phoneNumber}]`);
    }
  };

  return (
    <BodyWrapper>
      <Body>
        <Field>
          <Controller
            control={control}
            rules={{
              required: true,
              maxLength: 10,
              minLength: 10,
            }}
            render={({field: {onChange, value}}) => (
              <TextInput
                label="Mobile Number"
                onFocus={() => setFocus(true)}
                onBlur={() => setFocus(false)}
                onChangeText={v => {
                  const specialCharacterRegex = new RegExp('^[0-9]*$');
                  const whiteSpaceRegex = /^\S*$/;

                  if (
                    specialCharacterRegex.test(v) &&
                    whiteSpaceRegex.test(v)
                  ) {
                    onChange(v);
                  } else {
                    onChange(getValues('phoneNumber') || '');
                  }
                }}
                value={value}
                error={
                  errors?.phoneNumber && !focus ? 'Required Field' : undefined
                }
                keyboardType="number-pad"
                maxLength={10}
              />
            )}
            name="phoneNumber"
          />
        </Field>

        {isSignUpScreen && (
          <Field>
            <Checkbox
              onChange={v => setValue({...tncValue, agree: v})}
              checked={!!tncValue?.agree}
              description={
                <TermsAndCondition>
                  <TermsAndConditionText>
                    By selecting “Get OTP” you agree to our
                  </TermsAndConditionText>
                  <TermsAndConditionButton>
                    <TermsAndConditionText
                      clickable={true}
                      onPress={() =>
                        navigation.dispatch(
                          StackActions.push(TERMS_AND_CONDITION.SCREEN, {
                            showConsentCheckbox: true,
                          }),
                        )
                      }
                      testID="tncLink">
                      Terms and conditions & Privacy Policy
                    </TermsAndConditionText>
                  </TermsAndConditionButton>
                </TermsAndCondition>
              }
              testID="tncCB"
            />
          </Field>
        )}
      </Body>
      <SubmitButton>
        <Button
          disabled={isSignUpScreen ? !isValid || !tncValue?.agree : !isValid}
          title="Get OTP"
          onPress={handleSubmit(onSubmit)}
          style={otpButtonStyle}
          testID="gtOtp"
        />
        <Button
          title={isSignUpScreen ? 'Login' : 'Sign up'}
          variant="text"
          onPress={() =>
            navigation.dispatch(
              StackActions.replace(
                isSignUpScreen ? LOGIN?.SCREEN : ONBOARDING?.SCREEN,
              ),
            )
          }
          testID="lgn_Sinup"
        />
      </SubmitButton>

      <ErrorModal
        visible={!!error}
        description={error}
        hideModal={() => {
          setError(undefined);
        }}
        retry={() => {
          const data = {
            phoneNumber: getValues('phoneNumber'),
          };
          onSubmit(data);
        }}
        type="error"
      />
    </BodyWrapper>
  );
};

export default Form;
