import Immutable from 'immutable';
import React from 'react';
import { TRIAL_STATUS } from 'constants/Services';
import StoreMixin from 'lib/StoreMixin';
import { i18n, formatDate, formatCurrency, pluralize } from 'lib/i18n';
import Url from 'lib/Url';

import SubscriptionStore from 'stores/Subscription';
import ServiceStore from 'stores/Services';
import AuthStore from 'stores/Auth';
import { ServiceIcon } from 'components/Icon';

import Link from 'ui/Link';

const DISPLAYED_SERVICES = ['tracker', 'wiki', 'forms'];

function getReadinessStatusMap() {
    return new Immutable.Map(
        DISPLAYED_SERVICES.map(item => [item, (AuthStore.getService(item) || {}).ready])
    );
}

function isOnTrial(key) {
    return AuthStore.getServiceTrialStatus(key) === TRIAL_STATUS.IN_PROGRESS;
}

const Services = React.createClass({

    mixins: [StoreMixin],

    getStoreState() {
        const services = DISPLAYED_SERVICES.map(key => ServiceStore.getService(key));

        return {
            services,
            nextPaymentDate: SubscriptionStore.get('current.next_act_date'),
            ready: getReadinessStatusMap(),
        };
    },

    componentDidMount() {
        this.subscribe([ServiceStore, AuthStore, SubscriptionStore]);
    },

    _shouldRenderItem(item) {
        if (!item || !item.available) {
            return false;
        }

        const pricing = SubscriptionStore.getPricing(item.key);

        return item.key === 'connect' || (
            this.state.ready.get(item.key) &&
            !isOnTrial(item.key) &&
            pricing && pricing.total !== undefined
        );
    },

    _renderItemPricing(item) {
        const base = 'balance__list-item';
        const pricing = SubscriptionStore.getPricing(item.key);

        let contentKey = {
            price: 'balance.services.monthly_price.per_subscription',
            persons: 'balance.services.subscriptions',
        };

        if (item.key === 'connect') {
            contentKey = {
                price: 'balance.services.monthly_price.per_person',
                persons: 'balance.services.persons',
            };
        }

        const content = {};
        const component = {};

        content.price = i18n(contentKey.price, {
            price: formatCurrency(
                typeof pricing.per_user_with_discount === 'number' ?
                    pricing.per_user_with_discount :
                    pricing.per_user,
                pricing.currency
            ),
        });

        if (pricing.users_count) {
            content.priceNote = i18n('balance.services.current_subscriptions', {
                n_subscriptions: pluralize(
                    pricing.users_count,
                    i18n(contentKey.persons)
                ),
            });
            component.priceNote = (
                <div className={`${base}__price-note`}>
                    <Link to={Url.getServiceSettingsUrl('tracker')}>
                        <span dangerouslySetInnerHTML={{ __html: content.priceNote }} />
                    </Link>
                </div>
            );
        }

        const className = [
            `${base}__pricing`,
            typeof pricing.total_with_discount === 'number' && `${base}__pricing_discounted`,
        ].filter(Boolean).join(' ');

        return (
            <div className={className}>
                <div
                    className={`${base}__price`}
                    dangerouslySetInnerHTML={{ __html: content.price }}
                />
                {component.priceNote}
            </div>
        );
    },

    _renderItem(item) {
        const base = 'balance__list-item';

        if (!this._shouldRenderItem(item)) {
            return null;
        }

        return (
            <div className="balance__list-item" id={item.key} key={item.key}>
                <div className={`${base}__icon`}>
                    <ServiceIcon
                        cls={`${base}__icon-image`}
                        serviceSlug={item.key}
                    />
                </div>
                <div className={`${base}__body`}>
                    <div className={`${base}__title`}>
                        <Link to={item.url}>{item.name}</Link>
                    </div>
                    {this._renderItemPricing(item)}
                </div>
            </div>
        );
    },

    _renderPlanDetails() {
        if (SubscriptionStore.getPlan() !== 'paid') {
            return null;
        }

        return this._renderItem({
            key: 'connect',
            name: i18n('balance.services.name.connect'),
            url: Url.getPath('admin', 'subscription', 'services'),
            available: true,
        });
    },

    render() {
        const { services, nextPaymentDate } = this.state;

        let title = i18n('balance.services.title');
        let description;

        const components = {
            services: services.map(this._renderItem),
            planDetails: this._renderPlanDetails(),
        };

        if (!components.services.length) {
            title = i18n('balance.services.placeholder.title');
            description = i18n('balance.services.placeholder.description', {
                services_url: Url.getPath('admin', ''),
            });
        } else if (nextPaymentDate) {
            description = i18n('balance.services.description', {
                chargeoff_date: formatDate(nextPaymentDate),
            });
        }

        return (
            <div className="balance__list">
                <h2 className="balance__list__title">
                    {title}
                </h2>
                <div
                    className="balance__list__description"
                    dangerouslySetInnerHTML={{ __html: description }}
                />
                <div className="balance__list__items">
                    {components.services}
                    {components.planDetails}
                </div>
            </div>
        );
    },

});

export default Services;
