// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {injectIntl, intlShape} from 'react-intl';
import {
    ActivityIndicator,
    Image,
    Keyboard,
    KeyboardAvoidingView,
    Platform,
    StatusBar,
    TouchableWithoutFeedback,
    View
} from 'react-native';
import Button from 'react-native-button';
import semver from 'semver';

import {RequestStatus} from 'mattermost-redux/constants';
import {Client, Client4} from 'mattermost-redux/client';

import ErrorText from 'app/components/error_text';
import FormattedText from 'app/components/formatted_text';
import TextInputWithLocalizedPlaceholder from 'app/components/text_input_with_localized_placeholder';
import {GlobalStyles} from 'app/styles';
import {isValidUrl, stripTrailingSlashes} from 'app/utils/url';

import urlParse from 'url-parse';

import logo from 'assets/images/logo.png';

class SelectServer extends PureComponent {
    static propTypes = {
        navigator: PropTypes.object,
        intl: intlShape.isRequired,
        config: PropTypes.object,
        license: PropTypes.object,
        theme: PropTypes.object,
        transition: PropTypes.bool.isRequired,
        serverUrl: PropTypes.string.isRequired,
        pingRequest: PropTypes.object.isRequired,
        configRequest: PropTypes.object.isRequired,
        licenseRequest: PropTypes.object.isRequired,
        serverVersion: PropTypes.string.isRequired,
        actions: PropTypes.shape({
            getPing: PropTypes.func.isRequired,
            resetPing: PropTypes.func.isRequired,
            handleServerUrlChanged: PropTypes.func.isRequired
        }).isRequired
    };

    constructor(props) {
        super(props);

        this.state = {
            error: null
        };
    }

    componentDidMount() {
        if (Platform.OS === 'android') {
            Keyboard.addListener('keyboardDidHide', this.handleAndroidKeyboard);
        }
    }

    componentWillReceiveProps(nextProps) {
        if (!this.props.transition && nextProps.transition) {
            this.handleLoginOptions();
        }
    }

    componentWillUnmount() {
        if (Platform.OS === 'android') {
            Keyboard.removeListener('keyboardDidHide', this.handleAndroidKeyboard);
        }
    }

    handleLoginOptions = () => {
        const {config, intl, license, serverVersion, theme} = this.props;
        const version = serverVersion.match(/^[0-9]*.[0-9]*.[0-9]*(-[a-zA-Z0-9.-]*)?/g)[0];
        const samlEnabled = config.EnableSaml === 'true' && license.IsLicensed === 'true' && license.SAML === 'true';
        const gitlabEnabled = config.EnableSignUpWithGitLab === 'true' && semver.valid(version) && semver.gte(version, 'v3.10.0');

        let options = 0;
        if (samlEnabled || gitlabEnabled) {
            options += 1;
        }

        let screen;
        let title;
        if (options) {
            screen = 'LoginOptions';
            title = intl.formatMessage({id: 'mobile.routes.loginOptions', defaultMessage: 'Login Chooser'});
        } else {
            screen = 'Login';
            title = intl.formatMessage({id: 'mobile.routes.login', defaultMessage: 'Login'});
        }

        this.props.navigator.push({
            screen,
            title,
            animated: true,
            backButtonTitle: '',
            navigatorStyle: {
                navBarTextColor: theme.sidebarHeaderTextColor,
                navBarBackgroundColor: theme.sidebarHeaderBg,
                navBarButtonColor: theme.sidebarHeaderTextColor
            }
        });

        this.props.actions.resetPing();
    };

    handleAndroidKeyboard = () => {
        this.blur();
    };

    onClick = async () => {
        const preUrl = urlParse(this.props.serverUrl, true);
        const url = stripTrailingSlashes(preUrl.protocol + '//' + preUrl.host);
        let error = null;

        Keyboard.dismiss();

        if (isValidUrl(url)) {
            Client4.setUrl(url);
            Client.setUrl(url);
            this.props.actions.handleServerUrlChanged(url);
            await this.props.actions.getPing();
        } else {
            error = {
                intl: {
                    id: 'mobile.server_url.invalid_format',
                    defaultMessage: 'URL must start with http:// or https://'
                }
            };
        }

        this.setState({error});
    };

    inputRef = (ref) => {
        this.textInput = ref;
    };

    blur = () => {
        if (this.textInput) {
            this.textInput.refs.wrappedInstance.blur();
        }
    };

    render() {
        const {serverUrl, pingRequest, configRequest, licenseRequest} = this.props;
        const isLoading = pingRequest.status === RequestStatus.STARTED ||
            configRequest.status === RequestStatus.STARTED ||
            licenseRequest.status === RequestStatus.STARTED;

        let proceed;
        if (isLoading) {
            proceed = (
                <ActivityIndicator
                    animating={true}
                    size='small'
                />
            );
        } else {
            proceed = (
                <Button
                    onPress={this.onClick}
                    containerStyle={GlobalStyles.signupButton}
                >
                    <FormattedText
                        style={GlobalStyles.signupButtonText}
                        id='mobile.components.select_server_view.proceed'
                        defaultMessage='Proceed'
                    />
                </Button>
            );
        }

        const error = pingRequest.error || configRequest.error || licenseRequest.error;

        return (
            <KeyboardAvoidingView
                behavior='padding'
                style={{flex: 1}}
                keyboardVerticalOffset={0}
            >
                <StatusBar barStyle='dark-content'/>
                <TouchableWithoutFeedback onPress={this.blur}>
                    <View style={[GlobalStyles.container, GlobalStyles.signupContainer]}>
                        <Image
                            source={logo}
                        />
                        <View>
                            <FormattedText
                                style={[GlobalStyles.header, GlobalStyles.label]}
                                id='mobile.components.select_server_view.enterServerUrl'
                                defaultMessage='Enter Server URL'
                            />
                        </View>
                        <TextInputWithLocalizedPlaceholder
                            ref={this.inputRef}
                            value={serverUrl}
                            onChangeText={this.props.actions.handleServerUrlChanged}
                            onSubmitEditing={this.onClick}
                            style={GlobalStyles.inputBox}
                            autoCapitalize='none'
                            autoCorrect={false}
                            keyboardType='url'
                            placeholder={{id: 'mobile.components.select_server_view.siteUrlPlaceholder', defaultMessage: 'https://mattermost.example.com'}}
                            returnKeyType='go'
                            underlineColorAndroid='transparent'
                        />
                        {proceed}
                        <ErrorText error={this.state.error || error}/>
                    </View>
                </TouchableWithoutFeedback>
            </KeyboardAvoidingView>
        );
    }
}

export default injectIntl(SelectServer);
