import PropTypes from 'prop-types';
import React from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';

import { block } from 'bem-cn';
import Form from 'ui/Form';
import Button from 'lego-ui/Button';
import SessionSelect from 'components/SessionSelect';

import InviteActions from 'actions/Invite';

import AuthStore from 'stores/Auth';
import SessionStore from 'stores/Sessions';
import InvitesStore from 'stores/Invites';

import { i18n } from 'lib/i18n';
import Url from 'lib/Url';
import StoreMixin from 'lib/StoreMixin';

import './index.css';

const bInvite = block('invite');

const Invite = React.createClass({

    mixins: [PureRenderMixin, StoreMixin],

    getStoreState() {
        const { id } = this.props;
        const { selectedSessionId } = this.state || {};
        const authSessionId = AuthStore.getUserId();
        const invite = InvitesStore.get(id);

        return {
            authSessionId,
            selectedSessionId: selectedSessionId || authSessionId,
            isCodeActive: invite.isValid(),
            orgName: invite.getOrganizationName(),
            code: invite.getCode(),
        };
    },

    componentDidMount() {
        this.subscribe([SessionStore, AuthStore, InvitesStore]);
    },

    componentWillUnmount() {
        clearTimeout(this._redirectTimeout);
    },

    _createUser() {
        const { id: code } = this.props;
        const { loading, selectedSessionId } = this.state;

        if (loading) {
            return;
        }

        this.setState({
            error: null,
            loading: true,
        });

        const data = {
            uid: selectedSessionId,
            code,
        };

        clearTimeout(this._redirectTimeout);

        InviteActions.createUser(data)
            .then(response => {
                if (response.errors) {
                    const errorData = response.errors.toJS();

                    return this._onError(errorData._common[0]);
                }

                const { wait = 0 } = response;

                this._redirectTimeout = setTimeout(() => {
                    this._onUserCreated(response);
                }, wait * 1000);
            })
            .catch(() => {
                this._onError(i18n('common.error.unknown'));
            });
    },

    _onUserCreated(response = {}) {
        const { selectedSessionId } = this.state;
        const { org_id: orgId } = response;
        const { redirect_to: redirectTo } = response;

        let redirectUrl = redirectTo ? Url.getLocation(redirectTo) : Url.getNewOrganizationUrl(orgId);

        if (selectedSessionId !== AuthStore.getUserId()) {
            redirectUrl = AuthStore.getSessionChangeUrl(selectedSessionId, redirectUrl);
        }

        Url.open(redirectUrl);
    },

    _onError(error) {
        this.setState({
            error,
            loading: false,
        });
    },

    _onSelect(selectedSessionId) {
        this.setState({ selectedSessionId });
    },

    _renderInvalidState() {
        const { code } = this.state;

        return (
            <Form className={bInvite({ invalid: true })}>
                <h1 className={bInvite('header')}>
                    {i18n(`invites.status.${code}`) || i18n('invites.status.invalid')}
                </h1>
            </Form>
        );
    },

    render() {
        const { error, loading, selectedSessionId, authSessionId, orgName, isCodeActive } = this.state;

        if (!isCodeActive) {
            return this._renderInvalidState();
        }

        return (
            <Form className={bInvite({ loading: loading ? 'yes' : 'no' })}>
                <h1 className={bInvite('header')}>
                    {i18n('invites.header', { orgName })}
                </h1>

                <SessionSelect
                    onSelect={this._onSelect}
                    selectedSessionId={selectedSessionId}
                    authSessionId={authSessionId}
                />

                <Form.Error value={error} mod="standalone" />
                <div className={bInvite('controls')}>
                    <Button
                        text={i18n('invites.create_user_button')}
                        view="action"
                        type="submit"
                        width="available"
                        busy={loading}
                        onClick={this._createUser}
                    />
                </div>
            </Form>
        );
    },
});

Invite.propTypes = {
    id: PropTypes.string.isRequired,
};

export default Invite;
