import React, { Component } from 'react';
import {
  ActivityIndicator,
  Image,
  LayoutAnimation,
  ScrollView,
  StyleSheet,
  TouchableNativeFeedback,
  View,
} from 'react-native';
import { Button, FormValidationMessage, Icon, SocialIcon } from 'react-native-elements';
import { connect, Dispatch } from 'react-redux';
import { AuthActions } from '../actions';
import { Images } from '../assets';
import { EmailLogin } from '../components/common/EmailLogin';
import { Colors } from '../components/ui';
import { RootState, UserRole } from '../models';

interface State {
  userRole?: UserRole;
  loginType?: 'email' | 'google' | 'facebook';
  error?: string;
}

interface StateProps {
  loading: boolean;
  error?: string;
}

interface DispatchProps {
  requestFacebookLogin: (userRole: UserRole) => void;
  requestGoogleLogin: (userRole: UserRole) => void;
}

type Props = StateProps & DispatchProps;

export class LoginScreenComponent extends Component<Props, State> {

  state: State = {
    userRole: undefined,
  };

  goBack = () => {
    if (this.state.loginType) {
      this.setState({ loginType: undefined, error: null });
    } else if (this.state.userRole) {
      this.setState({ userRole: undefined, error: null });
    }
  }

  setError = (error) => {
    this.setState({ error });
  }

  setUserRole(userRole: UserRole) {

    this.setState({ userRole });
  }

  componentWillUpdate() {
    LayoutAnimation.easeInEaseOut();
  }

  renderRoleSelectionButtons() {
    return (
      <View>
        <Button
          backgroundColor={Colors.employer.primary}
          raised
          containerViewStyle={styles.button}
          fontWeight='bold'
          borderRadius={4}
          title='Jestem pracodawcą'
          buttonStyle={{ height: 50 }}
          onPress={() => this.setUserRole(UserRole.EMPLOYER)}
        />
        <Button
          backgroundColor={Colors.employee.primary}
          raised
          borderRadius={4}
          fontWeight='bold'
          containerViewStyle={[styles.button, { marginTop: 8 }]}
          title='Szukam pracy'
          buttonStyle={{ height: 50 }}
          onPress={() => this.setUserRole(UserRole.EMPLOYEE)}
        />
      </View>
    );
  }

  renderProvderChoice() {
    return (
      <View style={{ flex: 1, justifyContent: 'center' }}>
        <Button
          title={'Zaloguj się przez Email'}
          raised
          borderRadius={4}
          containerViewStyle={[styles.button, { marginBottom: 6 }]}
          fontWeight='bold'
          buttonStyle={{ backgroundColor: 'green', height: 50 }}
          onPress={() => this.setState({ loginType: 'email' })}
        />
        <SocialIcon
          title='Zaloguj się przez Facebook'
          button
          type='facebook'
          onPress={() => this.props.requestFacebookLogin(this.state.userRole)}
          style={{ borderRadius: 4 }}
        />
        <SocialIcon
          title='Zaloguj się przez Google'
          button
          type='google-plus-official'
          onPress={() => this.props.requestGoogleLogin(this.state.userRole)}
          style={{ borderRadius: 4 }}
        />
      </View>
    );
  }

  renderLoadingView() {
    const color = this.state.userRole && this.state.userRole === UserRole.EMPLOYEE && Colors.employee.primary
      || Colors.employer.primary;
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Image source={Images.logo} />
        <ActivityIndicator style={{ marginTop: -20 }} color={color} />
      </View>
    );
  }

  componentWillReceiveProps(nextProps: Props) {
    if (nextProps.error !== this.props.error) {
      let error = 'Błąd logowania, spróbuj później';
      switch (nextProps.error) {
        case 'auth/invalid-email':
        case 'auth/wrong-password':
        case 'auth/user-not-found':
          error = 'Niepoprawny email lub hasło';
          break;
        case 'auth/wrong-role':
          error = 'Masz już inną rolę. Nie możesz być jednocześnie pracownikiem i pracodawcą';
          break;
        // tslint:disable-next-line max-line-length
        case 'An account already exists with the same email address but different sign-in credentials. Sign in using a provider associated with this email address.':
          error = 'Konto z tym email\'em zostało założone już z użyciem innego serwisu';
          break;
        case '':
          error = null;
          break;
        default:
          break;
      }
      this.setState({ error });
    }
  }

  render() {
    const loading = this.props.loading;
    if (loading) return this.renderLoadingView();
    return (
      <ScrollView contentContainerStyle={styles.container}>
        <View style={{ flex: 1, justifyContent: 'center'}}>
          <View style={{ flexDirection: 'row', height: 50 }}>
            {
              this.state.userRole &&
              <TouchableNativeFeedback onPress={this.goBack}>
                <Icon
                  containerStyle={{ padding: 16, marginLeft: -16 }}
                  name='arrow-back'
                  color='gray'
                />
              </TouchableNativeFeedback>
            }
          </View>
          {!this.state.userRole && this.renderRoleSelectionButtons()}
          {this.state.userRole && !this.state.loginType && this.renderProvderChoice()}
          {this.state.loginType === 'email' && (
            <EmailLogin
              loading={loading}
              hasError={!!this.state.error}
              setError={this.setError}
              role={this.state.userRole}
            />
          )}
          {this.state.error && (
            <FormValidationMessage containerStyle={styles.error} labelStyle={{ textAlign: 'center' }}>
              {this.state.error}
            </FormValidationMessage>
          )}
        </View>
      </ScrollView >
    );
  }
}

const mapStateToProps: (state: RootState) => StateProps =
  (state) => ({
    loading: state.network.user.auth.loading,
    error: state.network.user.auth.error,
  });

const mapDispatchToProps: (dispatch: Dispatch<RootState>) => DispatchProps =
  (dispatch) => ({
    requestFacebookLogin: (userRole: UserRole) => dispatch(AuthActions.loginWithFacebookRequested(userRole)),
    requestGoogleLogin: (userRole: UserRole) => dispatch(AuthActions.loginWithGoogleRequested(userRole)),
  });

export const LoginScreen = connect(mapStateToProps, mapDispatchToProps)(LoginScreenComponent);

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingHorizontal: 18,
    justifyContent: 'center',
  },
  error: {
    alignSelf: 'center',
    marginBottom: 60,
  },
  button: {
    marginLeft: 8,
    marginRight: 8,
  },
});
