import {MyButton, MyIconButton} from '@components/MyButton';
import {MyIcon} from '@components/MyIcon';
import {MyIconInput, MyInputError} from '@components/MyInput';
import {MyScreenContainer} from '@components/MyScreenContainer';
import {MyTitle} from '@components/MyTitle';
import showToast from '@components/MyToast';
import {appVarActions} from '@configs/appVarReducer';
import {
  accountNameOptions,
  passwordOptions,
  userNameOptions,
} from '@configs/types';
import {Spinner, set, useToast} from '@gluestack-ui/themed';
import {ToBase64} from '@helper/base64';
import {apiBackendRequest, makeRequest} from '@helper/request';
import {RootScreenNavigationProp} from '@navigation/navigation';
import {
  ContentContainer,
  navigateToHome,
} from '@navigation/registration/registration';
import {useNavigation} from '@react-navigation/native';
import {RootState, store} from '@redux/store';
import MyUserManager from '@user/MyUserManager';
import {useEffect, useState} from 'react';
import {Text} from 'react-native';
import {View} from 'react-native';
import {useSelector} from 'react-redux';
import reactStringReplace from 'react-string-replace';

function Title({text, description}: {text: string; description?: string}) {
  return (
    <>
      <MyTitle text={text} textAlign="left" paddingBottom={0} />
      {description && <Text>{description}</Text>}
    </>
  );
}

export function SignUpStepUsername() {
  const lang = useSelector(
    (state: RootState) => state.appVariables.lang.registration,
  );
  const navigation = useNavigation<RootScreenNavigationProp>();

  const registerProcess = useSelector(
    (state: RootState) => state.appVariables.preferences.RegisterProcess,
  );

  const [username, setUsername] = useState('');
  const [inputTouched, setInputTouched] = useState(false);

  const usernameValid = username.length < userNameOptions.minLength;

  const errorText = reactStringReplace(
    lang.signUpStepUsername.error,
    '${minLength}',
    (match, i) => {
      return userNameOptions.minLength.toString();
    },
  );

  return (
    <MyScreenContainer
      style={{
        flexDirection: 'column',
      }}>
      <ContentContainer>
        <Title
          text={lang.signUpStepUsername.title}
          description={lang.signUpStepUsername.description}
        />

        <View style={{gap: 12, marginTop: 20}}>
          <MyIconInput
            text={lang.signUpStepUsername.inputUsername}
            iconName="person"
            value={username}
            onChangeText={text => {
              setUsername(text);
              setInputTouched(true);
            }}
            maxLength={userNameOptions.maxLength}
            helper={
              inputTouched &&
              usernameValid && <MyInputError text={errorText.join('')} />
            }
          />

          <MyButton
            type="secondary"
            text={lang.buttonNext}
            style={{marginBottom: 20}}
            disabled={username.length < userNameOptions.minLength}
            onPress={() => {
              let rp = {...registerProcess};

              rp.Username = username;

              store.dispatch(appVarActions.setRegisterProcess(rp));

              navigation.navigate('Registration', {
                screen: /*'SignUpStepPhoneNumber' */ 'SignUpStepPassword',
              });
            }}
          />
        </View>
      </ContentContainer>
    </MyScreenContainer>
  );
}
/*
export function SignUpStepPhoneNumber() {
  const lang = useSelector(
    (state: RootState) => state.appVariables.lang.registration,
  );
  const navigation = useNavigation<RootScreenNavigationProp>();

  return (
    <MyScreenContainer
      style={{
        flexDirection: 'column',
      }}>
      <ContentContainer>
        <Title text={lang.signUpStepPhoneNumber.title} />

        <View style={{gap: 12, marginTop: 20}}>
          <MyIconInput
            text={lang.signUpStepPhoneNumber.inputPhoneNumber}
            iconName="phone-iphone"
            keyboardType="phone-pad"
          />

          <MyButton
            type="secondary"
            text={lang.buttonNext}
            style={{marginBottom: 20}}
            onPress={() => {
              navigation.navigate('Registration', {
                screen: 'SignUpStepVerifyPhoneNumber',
              });
            }}
          />
        </View>
      </ContentContainer>
    </MyScreenContainer>
  );
}

export function SignUpStepVerifyPhoneNumber() {
  const lang = useSelector(
    (state: RootState) => state.appVariables.lang.registration,
  );
  const currentTheme = useSelector(
    (state: RootState) => state.nonSaveVariables.theme.colors,
  );
  const navigation = useNavigation<RootScreenNavigationProp>();

  return (
    <MyScreenContainer
      style={{
        flexDirection: 'column',
      }}>
      <ContentContainer>
        <Title
          text={lang.signUpStepVerifyPhoneNumber.title}
          description={`${lang.signUpStepVerifyPhoneNumber.description} +49 15** ******43`}
        />

        <View style={{gap: 12, marginTop: 20}}>
          <ConfirmationCodeInput />

          <MyButton
            type="secondary"
            text={lang.buttonNext}
            style={{marginBottom: 2}}
            onPress={() => {
              navigation.navigate('Registration', {
                screen: 'SignUpStepPassword',
              });
            }}
          />
          <View style={{alignItems: 'center'}}>
            <MyClickableText
              text={lang.signUpStepVerifyPhoneNumber.clickableTextResendCode}
              color={currentTheme.textLight400}
            />
          </View>
        </View>
      </ContentContainer>
    </MyScreenContainer>
  );
}
*/
export function SignUpStepPassword() {
  const lang = useSelector(
    (state: RootState) => state.appVariables.lang.registration,
  );
  const navigation = useNavigation<RootScreenNavigationProp>();

  const registerProcess = useSelector(
    (state: RootState) => state.appVariables.preferences.RegisterProcess,
  );

  const [password, setPassword] = useState('');
  const [inputTouched, setInputTouched] = useState(false);

  const [isPasswordVisible, setIsPasswordVisible] = useState(false);

  const togglePasswordVisibility = () => {
    setIsPasswordVisible(!isPasswordVisible);
  };

  const passwordValid = () => {
    if (password.length < passwordOptions.minLength) {
      return false;
    } else if (!passwordOptions.isAllowed(password)) {
      return false;
    } else {
      return true;
    }
  };

  const descriptionText = reactStringReplace(
    lang.signUpStepPassword.description,
    '${minLength}',
    () => {
      return passwordOptions.minLength.toString();
    },
  );

  const errorLengthText = reactStringReplace(
    lang.signUpStepPassword.errorLength,
    '${minLength}',
    () => {
      return passwordOptions.minLength.toString();
    },
  );

  const errorText = () => {
    if (password.length < passwordOptions.minLength) {
      return errorLengthText.join('');
    } else if (!passwordOptions.isAllowed(password)) {
      return lang.signUpStepPassword.errorPasswordInvalid;
    } else {
      return '';
    }
  };

  return (
    <MyScreenContainer
      style={{
        flexDirection: 'column',
      }}>
      <ContentContainer>
        <Title
          text={lang.signUpStepPassword.title}
          description={descriptionText.join('')}
        />

        <View style={{gap: 12, marginTop: 20}}>
          <MyIconInput
            text={lang.signUpStepPassword.inputPassword}
            iconName="lock"
            secureTextEntry={!isPasswordVisible}
            value={password}
            maxLength={passwordOptions.maxLength}
            onChangeText={text => {
              setPassword(text);
              setInputTouched(true);
            }}
            rightComponent={
              <MyIconButton
                MyIconProps={{
                  name: isPasswordVisible ? 'visibility-off' : 'visibility',
                  size: 24,
                }}
                onPress={togglePasswordVisibility}
              />
            }
            helper={
              inputTouched &&
              !passwordValid() && <MyInputError text={errorText()} />
            }
          />

          <MyButton
            type="secondary"
            text={lang.buttonNext}
            style={{marginBottom: 2}}
            disabled={!passwordValid()}
            onPress={() => {
              let rp = {...registerProcess};

              rp.Password = ToBase64(password);

              store.dispatch(appVarActions.setRegisterProcess(rp));

              navigation.navigate('Registration', {
                screen: 'SignUpStepAccountName',
              });
            }}
          />
        </View>
      </ContentContainer>
    </MyScreenContainer>
  );
}

enum AccountNameAvailable {
  Loading,
  Available,
  NotAvailable,
}

export function SignUpStepAccountName() {
  const lang = useSelector(
    (state: RootState) => state.appVariables.lang.registration,
  );
  const currentTheme = useSelector(
    (state: RootState) => state.nonSaveVariables.theme.colors,
  );

  const navigation = useNavigation<RootScreenNavigationProp>();
  const toast = useToast();

  const registerProcess = useSelector(
    (state: RootState) => state.appVariables.preferences.RegisterProcess,
  );

  const [isLoading, setIsLoading] = useState(false);
  const [accountName, setAccountName] = useState('');
  const [isAccountNameAvailable, setIsAccountNameAvailable] = useState(
    AccountNameAvailable.Loading,
  );
  const [inputTouched, setInputTouched] = useState(false);

  const accountNameValid = () => {
    if (accountName.length < accountNameOptions.minLength) {
      return false;
    } else if (!accountNameOptions.isAllowed(accountName)) {
      return false;
    } else {
      return true;
    }
  };

  const errorText = () => {
    if (accountName.length < accountNameOptions.minLength) {
      return reactStringReplace(
        lang.signUpStepAccountName.errorLength,
        '${minLength}',
        () => {
          return accountNameOptions.minLength.toString();
        },
      ).join('');
    } else if (!accountNameOptions.isAllowed(accountName)) {
      return lang.signUpStepAccountName.errorAccountNameInvalid;
    } else {
      return '';
    }
  };

  const rightComponent = () => {
    const closeIcon = (
      <MyIcon name="close" size={24} color={currentTheme.red600} />
    );

    if (!accountNameValid()) {
      return closeIcon;
    } else if (isAccountNameAvailable === AccountNameAvailable.Loading) {
      return <Spinner />;
    } else if (isAccountNameAvailable === AccountNameAvailable.Available) {
      return <MyIcon name="check" size={24} color={currentTheme.green400} />;
    } else {
      return closeIcon;
    }
  };

  useEffect(() => {
    if (!accountNameValid()) return;

    const delay = 400;
    const timeoutId = setTimeout(() => {
      makeRequest({
        path: apiBackendRequest.CHECK_ACCOUNT_NAME,
        requestGET: {':accountName': accountName},
        response: {},
      })
        .then(() => setIsAccountNameAvailable(AccountNameAvailable.Available))
        .catch(() =>
          setIsAccountNameAvailable(AccountNameAvailable.NotAvailable),
        );
    }, delay);

    // Cleanup the timeout on component unmount or when inputValue changes
    return () => clearTimeout(timeoutId);
  }, [accountName]);

  return (
    <MyScreenContainer
      scrollView
      style={{
        flexDirection: 'column',
      }}>
      <ContentContainer>
        <Title
          text={lang.signUpStepAccountName.title}
          description={lang.signUpStepAccountName.description}
        />

        <View style={{gap: 12, marginTop: 20}}>
          <MyIconInput
            text={lang.signUpStepAccountName.inputAccountName}
            iconName="person"
            value={accountName}
            onChangeText={text => {
              setAccountName(text);
              setInputTouched(true);
              setIsAccountNameAvailable(AccountNameAvailable.Loading);
            }}
            maxLength={accountNameOptions.maxLength}
            rightComponent={rightComponent()}
            helper={
              inputTouched &&
              !accountNameValid() && <MyInputError text={errorText()} />
            }
          />

          <MyButton
            type="primary"
            text={lang.signUpStepAccountName.buttonGetStarted}
            style={{marginBottom: 2}}
            isLoading={isLoading}
            disabled={
              !accountNameValid() ||
              isAccountNameAvailable !== AccountNameAvailable.Available
            }
            onPress={() => {
              setIsLoading(true);

              let rp = {...registerProcess};

              rp.AccountName = accountName;

              store.dispatch(appVarActions.setRegisterProcess(rp));

              makeRequest({
                path: apiBackendRequest.SIGN_UP,
                request: rp,
                method: 'POST',
                response: {
                  XAuthorization: '',
                  Username: '',
                },
              })
                .then(resp => {
                  MyUserManager.createNewMyUser(
                    accountName,
                    resp.response.Username,
                    resp.response.XAuthorization,
                  )
                    .then(async () => {
                      setIsLoading(false);
                      navigateToHome(navigation);
                    })
                    .catch(err => {
                      console.log('catch', err);
                    });
                })
                .catch(reason => {
                  console.log('error', reason);

                  setIsLoading(false);

                  let text =
                    store.getState().appVariables.lang.registration
                      .signUpStepAccountName.signUpError[
                      reason.status as number
                    ];

                  console.log('text', text, reason.status);

                  showToast(toast, {
                    title: 'Failed',
                    variant: 'solid',
                    action: 'error',
                    description: text,
                    isClosable: true,
                    //rest: {colorScheme: 'primary'},
                  });
                });
            }}
          />
        </View>
      </ContentContainer>
    </MyScreenContainer>
  );
}
