import React from 'react';
import { Select, TextInput, Button, Link } from 'lego-on-react';
import { block } from 'bem-cn';
import Modal from 'components2/Modal';
import InlineError from 'components2/InlineError';
import sender from 'api2/sender';
import settings, { saveSetting } from 'api2/settings';
import { SessionStore, ConfigStore, UserSettingsStore } from 'lib2/stores';
import { i18n } from 'i18n2';

import './index.css';

const b = block('news-mail-modal');

function isEmailValid(value) {
    return value && value.includes('@') && value.lastIndexOf('.') > value.indexOf('@');
}

function toEmail(login) {
    return login && !login.includes('@') ? `${login}@yandex.${ConfigStore.get('app.tld')}` : login;
}

function getFirstVisit() {
    return UserSettingsStore.get('news_mail_subscription.first_visit') ||
        UserSettingsStore.get('first_visit');
}

const DAY = 86400000;

// показываем окно обеления рассылок:
// через 3 дня после создания организации,
// через 7 дней после последнего показа
const PERIOD_BEFORE_FIRST_VISIT = 3 * DAY;
const PERIOD_AFTER_LAST_SHOWN = 7 * DAY;

function shouldRenderModal() {
    if (!ConfigStore.get('ui.showSubscriptionForm')) {
        return false;
    }

    let firstVisit = getFirstVisit();
    let {
        declined,
        confirm,
        last_shown: lastShown,
    } = UserSettingsStore.get('news_mail_subscription') || {};

    // настройки не загрузились / первый визит / отказался / уже подписан
    if (UserSettingsStore.get('broken') || !firstVisit || declined || confirm) {
        return false;
    }

    if (Date.now() - firstVisit < PERIOD_BEFORE_FIRST_VISIT) {
        return false;
    }

    return !lastShown || Date.now() - lastShown > PERIOD_AFTER_LAST_SHOWN;
}

export default class extends React.PureComponent {
    constructor(props) {
        super(props);

        this.state = {
            mode: 'promo',
            presetEmails: [],
            presetEmail: '',
            customEmail: '',
        };

        this._update = this._update.bind(this);
        this._initEmailInput = this._initEmailInput.bind(this);
        this._onPresetEmailChange = this._onPresetEmailChange.bind(this);
        this._onCustomEmailChange = this._onCustomEmailChange.bind(this);

        this._onSubmit = this._onSubmit.bind(this);
        this._onDecline = this._onDecline.bind(this);
        this._onDone = this._onDone.bind(this);
    }

    componentDidMount() {
        let presetEmails = Object.values(SessionStore.get('map'))
            .map(({ login }) => {
                let email = toEmail(login);

                return { val: email, text: email };
            });

        this.setState({
            presetEmails,
            presetEmail: toEmail(SessionStore.get('current.login')),
            valid: true,
        });

        if (getFirstVisit()) {
            this._update();
        } else {
            this._userSettingsStoreListener = UserSettingsStore.onChange(this._update);

            settings.send('GET').then(({ body }) => {
                UserSettingsStore.mergeState(body);
            });

            saveSetting('first_visit', Date.now());
        }
    }

    componentWillUnmount() {
        if (this._userSettingsStoreListener) {
            this._userSettingsStoreListener.remove();
        }
    }

    _update() {
        let shouldRender = shouldRenderModal();

        if (shouldRender && this.state.shouldRender === undefined) {
            saveSetting('news_mail_subscription', { last_shown: Date.now() });
        }

        this.setState({
            shouldRender,
        });
    }

    _initEmailInput(element) {
        if (element) {
            element.focus();
        }
    }

    _onPresetEmailChange([value]) {
        this.setState({
            presetEmail: value,
            valid: value !== '*',
        });
    }

    _onCustomEmailChange(value) {
        this.setState({
            customEmail: value,
            valid: isEmailValid(value),
        });
    }

    _onSubmit() {
        const { service, listId } = ConfigStore.get('sender.newsList') || {};

        let { presetEmail, customEmail } = this.state;
        let submit;

        this.setState({
            busy: true,
        });

        if (!presetEmail || presetEmail === '*') {
            // custom email, введённый вручную:
            // подписка по схеме double opt-in
            submit = sender.send('POST', `/api/0/${service}/maillist/${listId}/subscription/request`, {
                body: JSON.stringify({
                    to_email: customEmail,
                    args: JSON.stringify({
                        lang: ConfigStore.get('app.locale'),
                        tld: ConfigStore.get('app.tld'),
                    }),
                }),
            });
        } else {
            // подтверждённый preset email из мультиавторизации:
            // добавление в список рассылок
            submit = sender.send('PUT', `/api/0/${service}/maillist/${listId}/subscription`, {
                body: JSON.stringify({
                    email: presetEmail,
                }),
            });
        }

        submit
            .then(({ ok }) => {
                if (!ok) {
                    return this.setState({
                        error: i18n('news_mail_subscription.errors.something_wrong_error'),
                    });
                }

                this.setState({
                    mode: 'success',
                });

                saveSetting('news_mail_subscription', { confirm: true });
            })
            .finally(() => {
                this.setState({
                    busy: false,
                });
            });
    }

    _onDecline() {
        saveSetting('news_mail_subscription', { declined: true });

        this._onDone();
    }

    _onDone() {
        this.setState({
            shouldRender: false,
        });

        if (this.props.onDone) {
            this.props.onDone();
        }
    }

    render() {
        let { props } = this;
        let {
            mode,
            presetEmail,
            presetEmails,
            customEmail,
            valid,
            error,
            busy,
            shouldRender,
        } = this.state;

        return (
            <Modal
                visible={props.visible === undefined ? shouldRender : props.visible}
                cls={b({ mode })}
            >
                <Modal.Title>
                    {i18n(`news_mail_subscription.title.${mode}`)}
                </Modal.Title>
                <Modal.Body>
                    <div className={b('description')}>
                        {i18n(`news_mail_subscription.description.${mode}`)}
                    </div>
                    {mode !== 'success' &&
                    <div className={b('preset-emails')}>
                        <Select
                            cls={b('preset-emails-select')}
                            theme="normal"
                            type="radio"
                            size="m"
                            width="max"
                            maxHeight={140}
                            val={presetEmail}
                            onChange={this._onPresetEmailChange}
                        >
                            <Select.Group>
                                {presetEmails.map(({ val, text }) => (
                                    <Select.Item val={val} key={val}>
                                        {text}
                                    </Select.Item>
                                ))}
                            </Select.Group>
                            <Select.Group>
                                <Select.Item val="*">
                                    {i18n('news_mail_subscription.add_email')}
                                </Select.Item>
                            </Select.Group>
                        </Select>
                    </div>}
                    {presetEmail === '*' && mode !== 'success' &&
                    <div className={b('custom-email')}>
                        <TextInput
                            theme="normal"
                            size="m"
                            cls={b('custom-email-input')}
                            text={customEmail}
                            autoComplete={false}
                            onChange={this._onCustomEmailChange}
                            placeholder={i18n('news_mail_subscription.email_placeholder')}
                            ref={this._initEmailInput}
                        />
                    </div>}
                    {error &&
                    <InlineError cls={b('error')}>
                        {error}
                    </InlineError>}
                </Modal.Body>
                <Modal.Actions>
                    <Button
                        size="m"
                        theme="action"
                        width="max"
                        cls={b('button', { role: 'submit' })}
                        text={i18n(`news_mail_subscription.button.${mode}`)}
                        onClick={mode === 'promo' ? this._onSubmit : this._onDone}
                        disabled={!valid}
                    />
                    {mode !== 'success' &&
                    <Link
                        theme="black"
                        cls={b('link', { role: 'skip' })}
                        text={i18n('news_mail_subscription.skip_link')}
                        onClick={this._onDone}
                    />}
                    {mode !== 'success' &&
                    <Link
                        theme="ghost"
                        cls={b('link', { role: 'decline' })}
                        text={i18n('news_mail_subscription.decline_link')}
                        onClick={this._onDecline}
                    />}
                </Modal.Actions>
                <Modal.Busy visible={busy} />
            </Modal>
        );
    }
}
