'use strict';

var Logger = require('dw/system/Logger');
var logger = Logger.getLogger('Redsys', 'redsys');
var RedsysHelper = require('*/cartridge/scripts/redsys/helpers/redsysHelper.js');
var RedsysConstants = require('*/cartridge/scripts/constants/redsysConstants');

/**
 * Creates a object with the information required by Redsys to process the payment
 * @param {string} paymentMethod - Payment method used
 * @param {string} OrderID - The order id for the order
 * @param {string} amount - The amount to pay
 * @returns {Object} Data to send to Redsys / an error object
 */
function getFormValues(paymentMethod, OrderID, amount) {
    var config;
    var formValues = null;

    if (paymentMethod === RedsysConstants.REDSYS_CREDIT_CARD) {
        config = RedsysHelper.getRedsysCreditCardRedirectionConfig(OrderID, amount);
    }

    if (paymentMethod === RedsysConstants.REDSYS_BIZUM) {
        config = RedsysHelper.getBizumConfig(OrderID, amount);
    }

    // Returns null if there is an error getting the payment method configuration
    if (config.error) {
        return null;
    }

    formValues = RedsysHelper.makeParameters(null, paymentMethod, config, OrderID);

    return formValues;
}

/**
 * Generates data required for Redsys to process payment
 * @param {dw.order.Order} orderNo - Customers's order
 * @param {dw.order.Baske} basket - Current basket
 * @returns {Object} Form params
 */
function generateRedsysFormData(orderNo, basket) {
    var amount = basket.totalGrossPrice;
    var redsysPreferences = null;
    var redsysFormParams = {};
    var paymentInstruments = basket.getPaymentInstruments();
    var paymentInstrument = paymentInstruments[0].paymentMethod;

    if (paymentInstrument === RedsysConstants.REDSYS_BIZUM) {
        redsysPreferences = RedsysHelper.getRedsysBizumPreferences();
        amount = !redsysPreferences.limitTotal || redsysPreferences.redirectionUrl === RedsysConstants.REDSYS_MODE_LIVE ? basket.totalGrossPrice : 15.00;
        redsysFormParams = getFormValues(RedsysConstants.REDSYS_BIZUM, orderNo, amount);
    } else if (paymentInstrument === RedsysConstants.REDSYS_CREDIT_CARD) {
        redsysPreferences = RedsysHelper.getRedsysCreditCardPreferences();
        redsysFormParams = getFormValues(RedsysConstants.REDSYS_CREDIT_CARD, orderNo, amount);
    }

    return redsysFormParams;
}

/**
 * Creates a Custom Object to save order data
 * @param {Object} redsysFormData - Data sended to Redsys
 * @param {dw.order.Order} order - Customer's order'
 */
function generateNotificationCustomObj(redsysFormData, order) {
    var CustomObjectMgr = require('dw/object/CustomObjectMgr');
    var Transaction = require('dw/system/Transaction');

    try {
        Transaction.begin();
        var CustomObj = CustomObjectMgr.createCustomObject('RedsysNotifications', order.orderNo);
        // Save orderNo and OrderToken in order to link with payment transaction Bizum
        CustomObj.custom.ds_merchant_parameters = redsysFormData.Ds_MerchantParameters;
        CustomObj.custom.ds_signature = redsysFormData.Ds_Signature;
        CustomObj.custom.orderToken = order.orderToken;
        Transaction.commit();
    } catch (err) {
        logger.error('Error creating RedsysNotifications object: {0}', err);
    }
}

/**
 * Attempts to create an order from the current basket
 * @param {dw.order.Basket} currentBasket - The current basket
 * @param {string} orderNo - The order number to assign to the order
 * @returns {dw.order.Order} The order object created from the current basket
 */
function createOrder(currentBasket, orderNo) {
    var Transaction = require('dw/system/Transaction');
    var OrderMgr = require('dw/order/OrderMgr');
    var order;

    try {
        order = Transaction.wrap(function () {
            return OrderMgr.createOrder(currentBasket, orderNo);
        });
    } catch (error) {
        logger.error('Error creating order to pay with Redsys - InSite in order {0} with error: {1}', orderNo, JSON.stringify(error));
        return null;
    }
    return order;
}

module.exports = {
    getFormValues: getFormValues,
    generateRedsysFormData: generateRedsysFormData,
    generateNotificationCustomObj: generateNotificationCustomObj,
    createOrder: createOrder
};
