"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const querystring_1 = require("querystring");
const Cache = require("node-cache");
const uuid = require("uuid/v4");
const omit = require("lodash/omit");
const sdk_1 = require("../sdk");
const crypto_1 = require("../../tools/crypto");
const query_1 = require("../../tools/query");
const customerCache = new Cache({
    stdTTL: 60 * 15
});
const userScopes = [
    'manage_my_orders',
    'manage_my_profile',
    'manage_my_shopping_lists',
    'view_products',
    'manage_my_profile',
    'manage_my_payments'
];
function findCustomerById(customerId) {
    const cached = customerCache.get(customerId);
    if (cached) {
        return Promise.resolve(cached);
    }
    return sdk_1.clientExecute({
        uri: sdk_1.getServices()
            .customers.byId(customerId)
            .build(),
        method: sdk_1.methods.GET
    }).then(customer => {
        customerCache.set(customer.id, customer);
        return customer;
    });
}
exports.findCustomerById = findCustomerById;
var Customers;
(function (Customers) {
    function obtainTokenForLoggedInCustomer(email, password, loginResult) {
        const config = sdk_1.getConfig();
        const scopes = userScopes
            .map(scope => `${scope}:${config.projectKey}`)
            .join(' ');
        return sdk_1.authenticatedFormRequest({
            uri: `${config.authHost}/oauth/${config.projectKey}/customers/token`,
            method: sdk_1.methods.POST,
            body: querystring_1.stringify({
                grant_type: 'password',
                username: email,
                password,
                scope: scopes
            })
        }, true).then(tokenResult => ({
            token: crypto_1.encryptTokenResponse(tokenResult, loginResult.customer.id),
            customer: omit(loginResult.customer, ['password']),
            cart: loginResult.cart || null
        }));
    }
    function login(email, password, token) {
        return sdk_1.clientExecute({
            uri: sdk_1.getServices().login.build(),
            method: sdk_1.methods.POST,
            body: {
                email,
                password,
                anonymousId: crypto_1.getAnonymousIdFromToken(token)
            }
        }).then(loginResult => obtainTokenForLoggedInCustomer(email, password, loginResult));
    }
    Customers.login = login;
    function register(customerData, token) {
        return sdk_1.clientExecute({
            uri: sdk_1.getServices().customers.build(),
            method: sdk_1.methods.POST,
            body: Object.assign({}, customerData, { anonymousId: crypto_1.getAnonymousIdFromToken(token) })
        }).then(loginResult => {
            const { email, password } = customerData;
            return obtainTokenForLoggedInCustomer(email, password, loginResult);
        });
    }
    Customers.register = register;
    function loginAnonymously() {
        const anonymousId = uuid();
        const config = sdk_1.getConfig();
        return sdk_1.authenticatedFormRequest({
            uri: `${config.authHost}/oauth/${config.projectKey}/anonymous/token`,
            method: sdk_1.methods.POST,
            body: querystring_1.stringify({
                grant_type: 'client_credentials',
                anonymous_id: anonymousId
            })
        }).then(tokenResult => ({
            token: crypto_1.encryptTokenResponse(tokenResult, anonymousId, true),
            anonymousId
        }));
    }
    Customers.loginAnonymously = loginAnonymously;
    function fetchAll(token, options = {}) {
        const { page, perPage, sortPath, ascending } = query_1.getDefaults(options);
        return sdk_1.clientExecute({
            uri: sdk_1.getServices()
                .customers.page(page)
                .perPage(perPage)
                .sort(sortPath, ascending)
                .build(),
            method: sdk_1.methods.GET,
            token
        });
    }
    Customers.fetchAll = fetchAll;
    function findById(customerId, token) {
        return sdk_1.clientExecute({
            uri: sdk_1.getServices()
                .customers.byId(customerId)
                .build(),
            method: sdk_1.methods.GET,
            token
        });
    }
    Customers.findById = findById;
    function update(customerId, customerVersion, actions, token) {
        return sdk_1.clientExecute({
            uri: sdk_1.getServices()
                .customers.byId(customerId)
                .build(),
            method: sdk_1.methods.POST,
            token,
            body: {
                version: customerVersion,
                actions
            }
        });
    }
    Customers.update = update;
    function remove(customerId, customerVersion, token) {
        return sdk_1.clientExecute({
            uri: sdk_1.getServices()
                .customers.byId(customerId)
                .withVersion(customerVersion)
                .build(),
            method: sdk_1.methods.DELETE,
            token
        });
    }
    Customers.remove = remove;
})(Customers = exports.Customers || (exports.Customers = {}));
//# sourceMappingURL=customers.js.map