import * as React from 'react';
import {
  Keyboard,
  KeyboardAvoidingView,
  TextInput,
  TouchableWithoutFeedback,
  View,
} from 'react-native';

import { SpinAnimation } from '../../components/animations';
import { Button } from '../../components/button';
import { FeedbackBar } from '../../components/feedback-bar';
import { Icon } from '../../components/icon';
import { Text } from '../../components/text';
import { TextField } from '../../components/text-field';
import { testIdProps } from '../../../test/utils'
import { keyboardBehavior } from '../../utils/keyboard';

import { LoginFormProps } from './login-form.props';
import {
  ICON_LOGO_SIZE as iconSize,
  feedbackBarIconSize,
  iconColors,
  loginFormStyles as styles,
  passwordIconSize,
} from './login-form.styles';

const { DEFAULT_USERNAME, DEFAULT_PASSWORD } = { DEFAULT_USERNAME: "", DEFAULT_PASSWORD: "" };

/**
 * Login form
 *
 * @param loading Optional, true if logging in, disables button and show activity.
 * @param onPress Callback when login button is pressed.
 * @param style Optional, login form style override
 */
export const LoginForm: React.FC<LoginFormProps> = (props) => {
  const { loading, error, onLogin, style } = props;
  const [username, setUsername] = React.useState<string>(DEFAULT_USERNAME);
  const [password, setPassword] = React.useState<string>(DEFAULT_PASSWORD);
  const [usernameError, setUsernameError] = React.useState(false);
  const [passwordError, setPasswordError] = React.useState(false);
  const [passwordSecured, setPasswordSecured] = React.useState(true);
  const passwordRef = React.useRef<TextInput>();
  const passwordIcon = React.useMemo(() => (passwordSecured ? 'eye' : 'eye-hide'), [
    passwordSecured,
  ]);
  const passwordIconColor = React.useMemo(
    () => (password ? iconColors.active : iconColors.noActive),
    [password],
  );
  const usernameFieldLabelTx = React.useMemo(
    () =>
      usernameError
        ? 'component.loginForm.usernameRequired'
        : 'component.loginForm.fieldLabelUsername',
    [usernameError],
  );
  const usernameFieldLabelStyle = React.useMemo(
    () => [styles.fieldLabel, usernameError && styles.errorLabel],
    [usernameError],
  );
  const passwordFieldLabelTx = React.useMemo(
    () =>
      passwordError
        ? 'component.loginForm.passwordRequired'
        : 'component.loginForm.fieldLabelPassword',
    [passwordError],
  );
  const passwordFieldLabelStyle = React.useMemo(
    () => [styles.fieldLabel, passwordError && styles.errorLabel],
    [passwordError],
  );

  function doLogin() {
    Keyboard.dismiss();

    if (username && password && !loading) {
      onLogin(username.trim(), password);
    } else {
      setUsernameError(!username);
      setPasswordError(!password);
    }
  }

  function handleChangeUsername(username: string) {
    setUsername(username);
    setUsernameError(false);
  }

  function handleChangePassword(password: string) {
    setPassword(password);
    setPasswordError(false);
  }

  function handleShowPassword() {
    setPasswordSecured(!passwordSecured);
  }

  function handleUsernameSubmit() {
    if (passwordRef && passwordRef.current) {
      passwordRef.current.focus();
    }
  }

  function handlePasswordSubmit() {
    doLogin();
  }

  function handleLogin() {
    doLogin();
  }

  return (
    <KeyboardAvoidingView behavior={keyboardBehavior} style={style}>
      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
        <View style={styles.content}>
          <View style={styles.headerContainer}>
            <View style={styles.logoContainer}>
              <Icon color={iconColors.header} name="logo-paack-combined-color" size={iconSize} />
            </View>
            {loading && (
              <FeedbackBar
                icon={
                  <SpinAnimation height={feedbackBarIconSize} width={feedbackBarIconSize}>
                    <Icon color={iconColors.warning} name="loader" size={feedbackBarIconSize} />
                  </SpinAnimation>
                }
                preset="warning"
                style={styles.feedbackBar}
                titleTx="component.loginForm.feedbackLogin"
              />
            )}
            {error && (
              <FeedbackBar
                icon={<Icon color={iconColors.error} name="warning" size={feedbackBarIconSize} />}
                preset="error"
                style={[styles.feedbackBar, styles.feedbackBarError]}
                title={error}
              />
            )}
          </View>
          <View style={styles.formContainer}>
            {/* Username field */}
            <Text preset="caption" style={usernameFieldLabelStyle} tx={usernameFieldLabelTx} />
            <TextField
              autoCapitalize="none"
              blurOnSubmit={false}
              defaultValue={DEFAULT_USERNAME}
              placeholderTx="component.loginForm.placeholderUsername"
              preset="input"
              returnKeyType="next"
              value={username}
              onChangeText={handleChangeUsername}
              onSubmitEditing={handleUsernameSubmit}
              {...testIdProps('username-field')}
            />
            {/* Password field */}
            <Text preset="caption" style={passwordFieldLabelStyle} tx={passwordFieldLabelTx} />
            <TextField
              ref={passwordRef}
              autoCapitalize="none"
              defaultValue={DEFAULT_PASSWORD}
              placeholderTx="component.loginForm.placeholderPassword"
              preset="input"
              returnKeyType="done"
              rightComponent={
                <Icon
                  color={passwordIconColor}
                  name={passwordIcon}
                  size={passwordIconSize}
                  onPress={handleShowPassword}
                  {...testIdProps('password-icon')}
                />
              }
              secureTextEntry={passwordSecured}
              value={password}
              onChangeText={handleChangePassword}
              onSubmitEditing={handlePasswordSubmit}
              {...testIdProps('password-field')}
            />
            <View style={styles.buttonContainer}>
              <Button
                disabled={loading}
                preset="primary"
                textStyle={styles.buttonText}
                tx="component.loginForm.buttonSubmit"
                onPress={handleLogin}
                {...testIdProps('login')}
              ></Button>
            </View>
          </View>
        </View>
      </TouchableWithoutFeedback>
    </KeyboardAvoidingView>
  );
};

LoginForm.defaultProps = {
  loading: false,
};
