import _ from 'lodash';
import { ActionTypes } from 'constants/Common';
import dispatcher from 'dispatcher';
import getErrors from 'lib/getErrors';
import licenseApi from 'api/licenses';
import { toCompactObject } from 'records/util';

export default {
    calculate,
    update,
    read,
};

function prepareServiceData(serviceName, serviceData, mapping) {
    const subscribers = {};

    subscribers[serviceName] = serviceData || [];
    if (mapping) {
        subscribers[serviceName] = subscribers[serviceName].map(mapping);
    }

    return subscribers;
}

function pickSubscribersData(data, mapping) {
    const subscribers = _.extend(_.get(data, 'subscribers'), {});

    return Object.keys(subscribers).reduce((result, serviceName) => {
        result.subscribers = _.extend(
            result.subscribers,
            prepareServiceData(serviceName, subscribers[serviceName], mapping)
        );

        return result;
    }, { subscribers: {} });
}

function pickServiceData(args, mapping) {
    // args: [ serviceId: String, serviceData: Object ]
    if (typeof args[0] === 'string') {
        return {
            subscribers: prepareServiceData(args[0], args[1], mapping),
        };
    }

    // args: [ fullData: { subscribers: { <serviceName>: <serviceData> } } ]
    return pickSubscribersData(args[0], mapping);
}

function calculate(serviceSlug, data) {
    const params = pickServiceData([serviceSlug, data], toCompactObject);

    return licenseApi.calculate(serviceSlug, params)
        .then(response => {
            const errors = getErrors(response);

            if (!errors.isEmpty()) {
                return { errors };
            }

            return response;
        });
}

function read(serviceSlug) {
    return licenseApi.read(serviceSlug)
        .then(response => {
            const errors = getErrors(response);

            if (!errors.isEmpty()) {
                return { errors };
            }

            dispatcher.dispatch(ActionTypes.RECEIVE_MIXED_DATA, response);

            return response;
        });
}

function update(serviceSlug, ...args) {
    const params = pickServiceData(args, toCompactObject);

    return licenseApi.update(serviceSlug, params)
        .then(response => {
            const errors = getErrors(response);

            if (!errors.isEmpty()) {
                return { errors };
            }

            response.licenses = pickServiceData(args);
            dispatcher.dispatch(ActionTypes.RECEIVE_MIXED_DATA, response);

            return response;
        });
}
