import React from 'react';
import { Link, Button, Spin } from 'lego-on-react';
import block from 'bem-cn';
import getService from 'lib2/getService';
import toggleService from 'lib2/toggleService';
import hasPermission from 'lib2/hasPermission';
import { ServiceStore } from 'lib2/stores';
import metrika from 'api2/metrika';
import { i18n } from 'i18n2';

const b = block('service-toggle');

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

        this.state = {};

        this._onEnableClick = this._onEnableClick.bind(this);
        this._onDisableClick = this._onDisableClick.bind(this);
    }

    componentDidMount() {
        this._update();
        this._storeListener = ServiceStore.onChange(() => this._update());
    }

    componentWillUnmount() {
        this._storeListener.remove();
    }

    componentDidUpdate(prevProps) {
        if (this.props.serviceSlug !== prevProps.serviceSlug) {
            this._update();
        }
    }

    _update() {
        let { enabled, ready } = getService(this.props.serviceSlug);

        this.setState({
            enabled,
            ready,
        }, () => {
            let { pending, pendingLocked } = this.state;

            if (pending && !pendingLocked) {
                this.setState({
                    pending: false,
                });
            }
        });
    }

    _onToggle(targetStatus) {
        let { serviceSlug } = this.props;

        toggleService({
            serviceSlug,
            targetStatus,
            // модальное сообщение принято
            onConfirm: () => this.setState({
                // запускаем запрос на переключение сервиса, ставим отметку pending
                // до получения данных о статусе сервиса из поллинга
                pending: true,
                // не разрешаем снимать отметку pending внутри this._update, если
                // this._update вызван до окончания запроса на переключение сервиса
                // (например, на итерации поллинга во время запроса на переключение)
                pendingLocked: true,
                // закрываем модальное окно
                modalOpen: false,
            }),
            // модальное сообщение не принято
            onCancel: () => this.setState({
                // закрываем модальное окно
                modalOpen: false,
            }),
            // после завершения запроса на переключение сервиса
            onToggle: () => this.setState({
                // разрешаем снимать отметку pending внутри this._update
                pendingLocked: false,
            }),
        })
            .then(output => {
                if (output && output.ModalComponent) {
                    this.setState({ ...output, modalOpen: true });
                }
            });

        metrika.send(
            targetStatus ? 'Подключить сервис' : 'Отключить сервис',
            serviceSlug,
            window.location.pathname
        );
    }

    _onEnableClick() {
        this._onToggle(true);
    }

    _onDisableClick() {
        this._onToggle(false);
    }

    render() {
        if (!hasPermission('manage_services')) {
            return null;
        }

        let { serviceSlug } = this.props;
        let { pending, ready } = this.state;

        if (pending || !ready) {
            return <Spin progress />;
        }

        let { enabled, ModalComponent, modalProps, modalOpen } = this.state;
        let service = getService(serviceSlug);

        let modal = ModalComponent &&
            <ModalComponent
                {...modalProps}
                visible={modalOpen}
                key="modal"
            />;

        if (enabled && service.can_be_disabled) {
            return [
                <Link
                    theme="black"
                    text={i18n(`service_page.${serviceSlug}.action.disable`) ||
                        i18n('service_page.default.action.disable')}
                    onClick={this._onDisableClick}
                    key="disable"
                    cls={b({ type: 'disable' })}
                />,
                modal,
            ];
        }

        if (!enabled && service.can_be_enabled) {
            return [
                <Button
                    theme="action"
                    size="m"
                    text={i18n(`service_page.${serviceSlug}.action.enable`) ||
                        i18n('service_page.default.action.enable')}
                    onClick={this._onEnableClick}
                    key="enable"
                    cls={b({ type: 'enable' })}
                />,
                modal,
            ];
        }

        return null;
    }
}
