import React from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import { block } from 'bem-cn';
import { Link, Button, Spin } from 'lego-on-react';
import { SERVICES_WITHOUT_TURNING_OFF, SERVICES_IN_BETA } from 'constants/Services';
import StoreMixin from 'lib/StoreMixin';
import { i18n } from 'lib/i18n';
import Url from 'lib/Url';
import notify from 'services/notify';
import SubscriptionActions from 'actions/Subscription';
import ServiceActions from 'actions/Services';

import ConfigStore from 'stores/Config';
import PermissionStore from 'stores/Permissions';
import AuthStore from 'stores/Auth';
import ServiceStore from 'stores/Services';
import OrganizationStore from 'stores/Organizations';

import ServiceBadge from 'components/ServiceBadge';
import { Beta, ServiceIcon } from 'components/Icon';

import './index.css';

const bService = block('service-header');

export default React.createClass({

    mixins: [PureRenderMixin, StoreMixin],

    getStoreState() {
        const serviceSlug = this.props.serviceSlug;

        return {
            ready: AuthStore.isServiceReady(serviceSlug),
            enabled: AuthStore.isServiceEnabled(serviceSlug),
            isBusy: false,
        };
    },

    componentDidMount() {
        this.mounted = true;
        this.subscribe([AuthStore, PermissionStore, OrganizationStore]);
        SubscriptionActions.trackServiceStatus(this.props.serviceSlug);
    },

    componentDidUpdate(prevProps) {
        if (prevProps.serviceSlug !== this.props.serviceSlug) {
            this.setState(this.getStoreState());
            SubscriptionActions.stopServiceStatusTracking();
            SubscriptionActions.trackServiceStatus(this.props.serviceSlug);
        }
    },

    componentWillUnmount() {
        this.mounted = false;
        SubscriptionActions.stopServiceStatusTracking();
    },

    _toggleService() {
        const { enabled: isEnabled } = this.state;
        const { serviceSlug } = this.props;

        if (this._isBusy()) {
            return;
        }

        return ServiceActions.toggle({
            serviceSlug,
            isEnabled,
            onSubmit: this._onToggleSubmit,
        });
    },

    _onToggleSubmit(params) {
        const { enabled } = this.state;
        const { serviceSlug } = this.props;

        this.setState({ isBusy: true });

        SubscriptionActions.toggleService(serviceSlug, !enabled, params)
            .then(response => {
                if (response && response.errors) {
                    notify(response.errors.get('_common'), 'error');
                }
            })
            .catch(() => {
                notify(i18n('service_subscription.common.status.failed_to_enable'), 'error');
            })
            .finally(() => {
                if (this.mounted) {
                    this.setState({
                        isBusy: false,
                    });
                }
            });
    },

    _isBusy() {
        if (this.state && this.state.isBusy) {
            return this.state.isBusy;
        }

        return !this.state.ready;
    },

    _renderActions() {
        const { serviceSlug, action, hideMainAction } = this.props;
        const { enabled } = this.state;
        const { url } = ServiceStore.getService(serviceSlug);

        const mainActionUrlParams = {
            nickname: AuthStore.getUser().getNickname(),
            org_id: AuthStore.getOrganizationId(),
            uid: AuthStore.getUserId(),
        };
        const mainActionPattern = ConfigStore.get(`ui.serviceActions.${serviceSlug}`);
        const mainActionUrl = mainActionPattern && Url.build(mainActionPattern, mainActionUrlParams);
        const isToggleable = SERVICES_WITHOUT_TURNING_OFF.indexOf(serviceSlug) === -1 &&
            PermissionStore.allowsManageServices();

        let actions = [];

        const mainAction = action || mainActionUrl &&
            (
                <Link
                    theme="normal"
                    cls={bService('main-action')}
                    url={mainActionUrl}
                    text={i18n(`dashboard.card.${serviceSlug}.action`)}
                />
            );

        if (!this._isBusy()) {
            if (enabled) {
                if (!AuthStore.isExternalAdmin()) {
                    actions.push(
                        !hideMainAction && mainAction,
                        <Link
                            theme="normal"
                            url={url}
                            text={i18n(`service_page.${serviceSlug}.go`) ||
                                i18n('service_page.default.go')}
                        />
                    );
                }

                if (isToggleable) {
                    actions.push(
                        <Link
                            theme="black"
                            text={i18n(`service_page.${serviceSlug}.action.disable`) ||
                                i18n('service_page.default.action.disable')}
                            onClick={this._toggleService}
                        />
                    );
                }
            } else if (isToggleable) {
                actions.push(
                    <Button
                        theme="action"
                        size="m"
                        onClick={this._toggleService}
                        text={i18n(`service_page.${serviceSlug}.action.enable`) ||
                            i18n('service_page.default.action.enable')}
                    />
                );
            }
        } else {
            actions.push(<Spin progress />);
        }

        if (actions.length) {
            return (
                <div className={bService('actions')}>
                    {actions.map((item, index) => (
                        <div className={bService('action')} key={`action-${index}`}>
                            {item}
                        </div>
                    ))}
                </div>
            );
        }
    },

    _renderStatus() {
        const { serviceSlug } = this.props;
        const { enabled } = this.state;
        const isBusy = this._isBusy();

        let status = i18n(`service_page.${serviceSlug}.enabling`) || i18n('service_page.default.enabling');

        if (isBusy && enabled) {
            status = i18n(`service_page.${serviceSlug}.disabling`) || i18n('service_page.default.disabling');
        } else if (!isBusy && enabled) {
            status = i18n(`service_page.${serviceSlug}.enabled`) || i18n('service_page.default.enabled');
        } else if (!isBusy) {
            status = i18n(`service_page.${serviceSlug}.disabled`) || i18n('service_page.default.disabled');
        }

        return (
            <div
                className={bService('status', {
                    active: enabled,
                    process: isBusy,
                })}
            >
                {status}
            </div>
        );
    },

    render() {
        const { serviceSlug, showBadge } = this.props;
        const { name } = ServiceStore.getService(serviceSlug);
        const description = i18n(`service_page.${serviceSlug}.description`);

        return (
            <div className={bService()}>
                <div className={bService('top')}>
                    <div className={bService('heading')}>
                        <ServiceIcon
                            cls={bService('icon')}
                            serviceSlug={serviceSlug}
                        />
                        <div className={bService('info')}>
                            <div className={bService('title')}>
                                {name}
                                {SERVICES_IN_BETA.indexOf(serviceSlug) !== -1 &&
                                <Beta width="15" height="15" cls={bService('beta-badge')} />}
                                {showBadge &&
                                <ServiceBadge
                                    cls={bService('badge')}
                                    serviceSlug={serviceSlug}
                                    hidePricing
                                    size="m"
                                />}
                            </div>
                            {this._renderStatus()}
                        </div>
                    </div>
                    {this._renderActions()}
                </div>
                <div className={bService('description')} dangerouslySetInnerHTML={{ __html: description }} />
            </div>
        );
    },

});
