'use strict';

var server = require('server');
var CSRFProtection = require('dw/web/CSRFProtection');
var Order = require ('dw/order/Order');
var Resource = require('dw/web/Resource');

var Site = require('dw/system/Site').getCurrent();

/**
 * List and filter returns
 */
server.use('List', server.middleware.https, function (req, res, next) {
	var CustomObjectMgr = require ('dw/object/CustomObjectMgr');
	var PagingModel = require('dw/web/PagingModel');

	var returnsearch =  server.forms.getForm ('returnsearch');

	var query = '';
	var fromdate = new Date (1970, 1, 1);
	var todate = new Date ();

	// Build search query
	if (session.forms.returnsearch.returnID && session.forms.returnsearch.returnID.value) {
		query += (query == '' ? '' : ' AND ') + 'custom.ID = \'' + session.forms.returnsearch.returnID.value + '\'';
	}
	if (session.forms.returnsearch.orderNo && session.forms.returnsearch.orderNo.value) {
		query += (query == '' ? '' : ' AND ') + 'custom.orderNo = \'' + session.forms.returnsearch.orderNo.value + '\'';
	}
	if (session.forms.returnsearch.returnType && session.forms.returnsearch.returnType.value) {
		query += (query == '' ? '' : ' AND ') + 'custom.type_return = \'' + session.forms.returnsearch.returnType.value + '\'';
	}
	if (session.forms.returnsearch.fromdate && session.forms.returnsearch.fromdate.value) {

		// Get given date in GMT
		var cal = new dw.util.Calendar ();
		cal.setTimeZone ('Europe/Madrid');
		cal.set (
			session.forms.returnsearch.fromdate.value.getYear (),
			session.forms.returnsearch.fromdate.value.getMonth (),
			session.forms.returnsearch.fromdate.value.getDate (), 0, 0, 0);
		fromdate = cal.getTime ();
	}
	if (session.forms.returnsearch.todate && session.forms.returnsearch.todate.value) {

		// Get given date in GMT
		var cal = new dw.util.Calendar ();
		cal.setTimeZone ('Europe/Madrid');
		cal.set (
			session.forms.returnsearch.todate.value.getYear (),
			session.forms.returnsearch.todate.value.getMonth (),
			session.forms.returnsearch.todate.value.getDate (), 23, 59, 59);
		todate = cal.getTime ();
	}

	var returns = CustomObjectMgr.queryCustomObjects ("RedsysReturn", query + (query == '' ? '' : ' AND ') + 'creationDate >= {0} AND creationDate <= {1}', 'creationDate desc', fromdate, todate);

	// Init pagination
	var parameterMap = request.httpParameterMap;
    var pageSize = parameterMap.sz.intValue || 10;
    var start = parameterMap.start.intValue || 0;
    var returnsPagingModel = new PagingModel(returns, returns.count);
    returnsPagingModel.setPageSize(pageSize);
    returnsPagingModel.setStart(start);

	var customer = session.customer;

	res.render('returnslist', {
		error: false,
		returns: returnsPagingModel.getPageElements().asList(),
		pagingmodel: returnsPagingModel,
		CurrentForms: session.forms,
		pageurl: dw.web.URLUtils.url('RedsysReturns-List').appendCSRFTokenBM()
	});
	next();
});

/**
 * View a single return
 */
server.use('View', server.middleware.https, function (req, res, next) {
	// Get ID parameter
	var redsysReturnHelper = require('*/cartridge/scripts/helpers/redsysReturnHelper');
	var retID = request.httpParameterMap.ID.value ?  request.httpParameterMap.ID.value : arguments[0];
	if (retID) {
        // Get return
		var Return = redsysReturnHelper.getReturnFromId(retID);
		if (Return) {
			res.render('returnsview', {
                Return: Return,
				retLines: redsysReturnHelper.getReturnLines(Return),
				order: redsysReturnHelper.getOrder(Return)
			});
			next();
		}
	}
});

/**
 * Display order
 */
//function order () {
server.get('Order', server.middleware.https, function (req, res, next) {

	var OrderMgr = require ('dw/order/OrderMgr');
	var SystemObjectMgr = require ('dw/object/SystemObjectMgr');

	// Get order
	var orderNo = request.httpParameterMap.orderNo.value;
	var order = OrderMgr.getOrder (orderNo);

	if (order) {

		var redsysReturnHelper = require('*/cartridge/scripts/helpers/redsysReturnHelper');
		var available = redsysReturnHelper.isAvailableRefund(orderNo);

		res.render('returnsorder', {
			order: order,
			orderHasReturns: available.hasReturns,
			returnable: available.forRefundItems,
			returns: available.returns,
			allowReturn: available
		});
	}
	else {
		res.render('returnsorder', { error: (orderNo ? orderNo : false)});
	}
	next();
});

/**
 * Create a return.
 */
server.post('Generate', server.middleware.https, function (req, res, next) {

	var CSRFProtection = require('dw/web/CSRFProtection');
	var userName = session.getUserName();
	if(!CSRFProtection.validateRequest()) {
		res.json({error: true, csrfToken: true});
	} else {
		var CustomObjectMgr = require('dw/object/CustomObjectMgr');
		var Transaction = require ('dw/system/Transaction');
		var System = require('dw/system/System');
		
		var redsysApi = require('*/cartridge/scripts/redsys/redsysApi');
		var redsysConstants = require('*/cartridge/scripts/constants/redsysConstants');
		var redsysReturnHelper = require('*/cartridge/scripts/helpers/redsysReturnHelper');

		var orderNo = request.httpParameterMap.orderNo.value;
		var data = request.httpParameterMap;
		var nArticles = data.getParameterMap('line_').parameterNames;

		var refundAmount = request.httpParameterMap.refundedAmount.value;
		var refundShipping = request.httpParameterMap.refundedShippingAmount.value =='on' ? true : false;
		var typeReturn = request.httpParameterMap.type_return.value;

		var products = [];
		if(typeReturn=="PRODUCTS") {
			try {
				for(var a=0; a<nArticles.length; a++) {
					var sku = nArticles[a];
					var qty = new Number(request.httpParameterMap["qty_"+sku].value);
					var reason = request.httpParameterMap["reasonExplained_"+sku].value;
					var name = request.httpParameterMap["name"+sku].value;
					var price = request.httpParameterMap["price"+sku].value.split(" ")[1];
					products.push({sku: sku, name: name, reason: reason, qty: qty, price: price});
				}
			} catch(e) {
				var tmp = e.message;
				var tmp2 = "";
			}
		}

		var logCompleto = "\n"+ new Date().toUTCString() + " Devolución creada por: " + userName;
		if(refundShipping==true) {
			logCompleto = logCompleto + "\n"+ new Date().toUTCString() + " Se han devuelto los gastos de envio.";
		}
		if(request.httpParameterMap.comment && request.httpParameterMap.comment.value.length>0) {
			logCompleto = logCompleto + "\n"+ new Date().toUTCString() + " Comentario de creación: " + request.httpParameterMap.comment.value;
		}

		var oReturnData = {
			orderNo: orderNo,
			type: typeReturn,
			returnShippmentCost: refundShipping,
			refundedAmount: refundAmount,
			products: products.length>0 ? products : null,
			log: logCompleto
		};

		var OrderMgr = require ('dw/order/OrderMgr');
		var order = OrderMgr.getOrder (orderNo);
		var jsonResponse = { error: true, strError: "" };

		var trataPeticionResponseObj = redsysApi.trataPeticionRefund(order, new Number(refundAmount));
		var trataPeticionResponse = trataPeticionResponseObj.response;
		var signature = trataPeticionResponseObj.signature;
		if (trataPeticionResponseObj.status === redsysConstants.REDSYS_RESPONSE_FAIL) {
			jsonResponse.error = true;
			jsonResponse.strError = 'Se ha producido un error al crear la devolución en Redsys: ' + trataPeticionResponseObj.message;
		}

		if (trataPeticionResponseObj.status === redsysConstants.REDSYS_RESPONSE_PASS) {
			var CustomObjectMgr = require('dw/object/CustomObjectMgr');
			try {
				oReturnData.redsysResponse = JSON.stringify(trataPeticionResponseObj.response);
				var sReturnID = redsysReturnHelper.doGenerateReturn(orderNo, oReturnData);

				if (null !== sReturnID) {
					var d = new Date ();
					var ret = CustomObjectMgr.getCustomObject ("RedsysReturn", sReturnID);
					if (ret) {
						Transaction.wrap(function() {
							ret.custom.log = (ret.custom.log ? ret.custom.log + "\n" : "") + d.toUTCString () + " Return requested from the Business Manager.";
						});
					}
					jsonResponse.error = false;
					jsonResponse.strError = "";
					jsonResponse.url = require('dw/web/URLUtils').url('RedsysReturns-View', 'ID', sReturnID).appendCSRFTokenBM().toString();
				} else {
					jsonResponse.error = true;
					jsonResponse.strError = "Se ha producido un error en la creación de la devolución."
				}
			} catch (err) {
				jsonResponse.error = true;
				jsonResponse.strError = "Se ha producido un error inesperado en la creación de la devolución en commerce, pero se ha enviado a redsys de forma correcta."
				dw.system.Logger.error('Error inesperado en la creación de la devolución: {0}', err);
			}
		}
	}
	res.json(jsonResponse);
	next();
});

module.exports = server.exports();
