import React from 'react';
import { block } from 'bem-cn';
import Loader from 'ui-components/lib/Loader';
import { Link, Button } from 'lego-on-react';
import { i18n } from 'lib/i18n';
import FormMixin from 'lib/FormMixin';

import SessionStore from 'stores/Sessions';
import AuthStore from 'stores/Auth';
import ConfigStore from 'stores/Config';

import SettingsActions from 'actions/Settings';
import SenderActions from 'actions/Sender';

import Form from 'ui/Form';
import Input from 'lego-ui/Input';
import Select from 'lego-ui/Select';

import senderValidator from 'validation/newsMailSubscription';

import './index.css';

const MAIL_LIST = 'newsList';
const SELECT_LIST_HEIGHT = 110;
const bSubscriptionPage = block('subscribe-page');

const Subscribe = React.createClass({

    mixins: [FormMixin],

    getInitialState() {
        return {
            errors: senderValidator.getErrors(),
            currentUserId: AuthStore.getUserId(),
            selectList: this._getSelectList(),
            emailContent: SessionStore.getUserEmail(AuthStore.getUserId()),
        };
    },

    _getSelectList() {
        const selectList = SessionStore.getList().map(({ id, login }) => ({ val: id, text: login }));

        selectList.push({ val: 'subEmail', text: i18n('news_mail_subscription.add_email') });

        return selectList;
    },

    _gerErrorContent(name) {
        const errors = this.state.errors.toJS();

        if (errors[name]) {
            return `<p class="error">${errors[name]}</p>`;
        }
    },

    _onSelectChange(event) {
        this.setState({
            isAnotherEmailSet: event.target.value === 'subEmail',
            emailContent: SessionStore.getUserEmail(event.target.value),
            errors: senderValidator.getErrors(this.state),
        });
    },

    _onInputChange(event) {
        this.setState({ emailContent: event.target.value });
    },

    _updateSettings() {
        this.setState({ isLoading: true });

        const { isAnotherEmailSet, emailContent } = this.state;
        const senderData = {
            email: emailContent,
            to_email: emailContent,
            mail_list: MAIL_LIST,
            args: {
                lang: ConfigStore.get('app.locale'),
                tld: ConfigStore.get('app.tld'),
            },
        };
        const updateData = {
            news_mail_subscription: {
                confirm: true,
            },
        };
        const action = isAnotherEmailSet ? 'requestEmail' : 'subscribeEmail';
        const settingsActionProm = SenderActions[action](senderData)
            .then(({ errors } = {}) => {
                if (errors) {
                    return { errors };
                }

                return SettingsActions.updateSettings(updateData);
            });

        return this._submit(settingsActionProm)
            .then(({ errors } = {}) => {
                this.setState({
                    isLoading: false,
                    isSubmitError: errors,
                    isSubmitSuccess: !errors,
                });
            });
    },

    _handleFormSubmit() {
        const { isSubmitSuccess } = this.state;

        if (isSubmitSuccess) {
            return this.props.close();
        }

        if (this._use(senderValidator)._validate(this.state)) {
            return this._updateSettings(true);
        }

        if (this._subInput) {
            this._subInput.focus();
        }
    },

    _renderSelect() {
        const { selectList, currentUserId, isSubmitSuccess } = this.state;

        if (isSubmitSuccess) {
            return null;
        }

        return (
            <div className={bSubscriptionPage('form-field')}>
                <Select
                    name="email"
                    mode="radio"
                    maxListHeight={SELECT_LIST_HEIGHT}
                    onChange={this._onSelectChange}
                    options={selectList}
                    val={currentUserId}
                    width="available"
                    size="m"
                />
            </div>
        );
    },

    _renderSubInput() {
        const { isAnotherEmailSet, isSubmitSuccess } = this.state;

        if ((!isAnotherEmailSet && !isSubmitSuccess) || isSubmitSuccess) {
            return null;
        }

        return (
            <div className={bSubscriptionPage('form-field')}>
                <Input
                    name="sub_email"
                    ref={input => this._subInput = input}
                    onChange={this._onInputChange}
                    placeholder={i18n('news_mail_subscription.email_placeholder')}
                    tipPosition="bottom-left"
                    error={this._gerErrorContent('email')}
                    border="all"
                    size="m"
                    width="available"
                />
            </div>
        );
    },

    _onSkip() {
        this.props.close();
    },

    _onDecline() {
        this.setState({ isLoading: true });

        const updateData = {
            news_mail_subscription: {
                declined: true,
            },
        };

        SettingsActions.updateSettings(updateData)
            .then(({ errors } = {}) => {
                this.setState({
                    isLoading: false,
                    isSubmitError: errors,
                    isSubmitSuccess: !errors,
                });
                this.props.close();
            });
    },

    _renderLink() {
        const { isSubmitSuccess } = this.state;

        if (isSubmitSuccess) {
            return null;
        }

        return [
            <Link
                theme="black"
                text={i18n('news_mail_subscription.skip_link')}
                onClick={this._onSkip}
                cls={bSubscriptionPage('link')}
                key="news_mail_subscription_skip_link"
            />,
            <Link
                theme="ghost"
                text={i18n('news_mail_subscription.decline_link')}
                onClick={this._onDecline}
                cls={bSubscriptionPage('link')}
                key="news_mail_subscription_decline_link"
            />,
        ];
    },

    _renderBody() {
        const { isSubmitSuccess, isSubmitError } = this.state;

        const bodyClassName = bSubscriptionPage({
            success: isSubmitSuccess,
        });
        const formState = isSubmitSuccess ? 'success' : 'promo';

        let submitError;

        if (isSubmitError) {
            submitError = i18n('news_mail_subscription.errors.something_wrong_error');
        }

        return (
            <div ref={this._getBody} className={bodyClassName}>
                <div className={bSubscriptionPage('image')} />
                <h1 className={bSubscriptionPage('title')}>
                    {i18n(`news_mail_subscription.title.${formState}`)}
                </h1>
                <p className={bSubscriptionPage('description')}>
                    {i18n(`news_mail_subscription.description.${formState}`)}
                </p>
                {this._renderSelect()}
                {this._renderSubInput()}
                <div className={bSubscriptionPage('button')}>
                    <Button
                        text={i18n(`news_mail_subscription.button.${formState}`)}
                        theme="action"
                        size="m"
                        onClick={this._handleFormSubmit}
                        width="available"
                    />
                    <Form.Error value={submitError} mod="standalone" />
                </div>
                {this._renderLink()}
            </div>
        );
    },

    render() {
        return (
            <div>
                <Loader visible={this.state.isLoading} />
                {this._renderBody()}
            </div>
        );
    },

});

export default Subscribe;
