"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const config = require("config");
const sdk_1 = require("../sdk");
const customers_1 = require("../../tools/customers");
const crypto_1 = require("../../tools/crypto");
const orders_1 = require("./orders");
const customers_2 = require("./customers");
var Carts;
(function (Carts) {
    function create(token) {
        return __awaiter(this, void 0, void 0, function* () {
            const { customerId, authToken, isAnonymous } = crypto_1.getTokenData(token);
            let params = {
                currency: config.get('store.defaultCurrency')
            };
            if (!isAnonymous) {
                const customer = yield customers_2.findCustomerById(customerId);
                params = Object.assign({}, params, { customerEmail: customer.email, currency: customers_1.getCustomerCurrency(customer), shippingAddress: customers_1.getCustomerShippingAddress(customer) });
            }
            return sdk_1.clientExecute({
                uri: sdk_1.getServices().myCarts.build(),
                method: sdk_1.methods.POST,
                body: params,
                token: authToken
            });
        });
    }
    Carts.create = create;
    function createFromOrder(orderId, token) {
        return orders_1.Orders.findById(orderId, token).then(order => {
            const { authToken } = crypto_1.getTokenData(token);
            return sdk_1.clientExecute({
                uri: sdk_1.getServices().myCarts.build(),
                method: sdk_1.methods.POST,
                token: authToken,
                body: {
                    currency: order.totalPrice.currencyCode,
                    customerEmail: order.customerEmail,
                    shippingAddress: order.shippingAddress
                }
            }).then(cart => addLineItems(cart.id, cart.version, order.lineItems.map(li => ({
                productId: li.productId,
                variantId: li.variant.id,
                quantity: li.quantity
            })), token));
        });
    }
    Carts.createFromOrder = createFromOrder;
    function findById(cartId, token) {
        const { authToken } = crypto_1.getTokenData(token);
        return sdk_1.clientExecute({
            uri: sdk_1.getServices()
                .myCarts.byId(cartId)
                .build(),
            method: sdk_1.methods.GET,
            token: authToken
        });
    }
    Carts.findById = findById;
    function findActiveCart(token) {
        const { authToken } = crypto_1.getTokenData(token);
        return sdk_1.clientExecute({
            uri: sdk_1.getServices().activeCart.build(),
            method: sdk_1.methods.GET,
            token: authToken
        });
    }
    Carts.findActiveCart = findActiveCart;
    function updateByActions(cartId, cartVersion, actions, token) {
        if (!Array.isArray(actions)) {
            actions = [actions];
        }
        const { authToken } = crypto_1.getTokenData(token);
        return sdk_1.clientExecute({
            uri: sdk_1.getServices()
                .myCarts.byId(cartId)
                .build(),
            method: sdk_1.methods.POST,
            token: authToken,
            body: {
                version: typeof cartVersion === 'string' ? Number(cartVersion) : cartVersion,
                actions
            }
        });
    }
    Carts.updateByActions = updateByActions;
    function addLineItems(cartId, cartVersion, lineItems, token) {
        if (!Array.isArray(lineItems)) {
            lineItems = [lineItems];
        }
        return updateByActions(cartId, cartVersion, lineItems.map(li => (Object.assign({ action: 'addLineItem' }, li))), token);
    }
    Carts.addLineItems = addLineItems;
    function changeLineItemQuantity(cartId, cartVersion, action, token) {
        return updateByActions(cartId, cartVersion, [
            Object.assign({ action: 'changeLineItemQuantity' }, action)
        ], token);
    }
    Carts.changeLineItemQuantity = changeLineItemQuantity;
    function removeLineItem(cartId, cartVersion, lineItemId, token) {
        return updateByActions(cartId, cartVersion, [
            {
                action: 'removeLineItem',
                lineItemId
            }
        ], token);
    }
    Carts.removeLineItem = removeLineItem;
    function setShippingAddress(cartId, cartVersion, address, token) {
        return updateByActions(cartId, cartVersion, {
            action: 'setShippingAddress',
            address
        }, token);
    }
    Carts.setShippingAddress = setShippingAddress;
    function setBillingAddress(cartId, cartVersion, address, token) {
        return updateByActions(cartId, cartVersion, {
            action: 'setBillingAddress',
            address
        }, token);
    }
    Carts.setBillingAddress = setBillingAddress;
    function setShippingMethod(cartId, cartVersion, shippingMethodId, token) {
        const shippingMethod = {
            typeId: 'shipping-method',
            id: shippingMethodId
        };
        return updateByActions(cartId, cartVersion, {
            action: 'setShippingMethod',
            shippingMethod
        }, token);
    }
    Carts.setShippingMethod = setShippingMethod;
})(Carts = exports.Carts || (exports.Carts = {}));
//# sourceMappingURL=carts.js.map