var xhr;
var vue_id = "";

// Only bind to the checkout if it exists.
// Otherwise, the functions are still globally available.
if(document.getElementById("ncms_checkout"))
{
	vue_id = "#ncms_checkout";
}

if(typeof SHOP_CONFIG == "undefined")
{
	SHOP_CONFIG = [];
	SHOP_CONFIG["currency_code"] = "CAD";
}

var ncms_checkout = new Vue({
	el: vue_id,
	data:
	{
		edit: true,
		done: false,
		active_shipping_gateway: null,
		messages: [],
		errors: [],
		order_info:
		{
			cart: [],
			subtotal: 0,
			shipping: 0,
			tax: 0,
			total: 0,
			tax_info: []
		},
		payment_info:
		{
			payment_gateway_id: null,
			payment_gateway: ""
		},
		shipping_info:
		{
			shipping_gateway_id: null,
			shipping_gateway: "",
			name: (typeof USER != "undefined" && USER.user_id != null ? USER.fname + " " + USER.lname : ""),
			phone: (typeof USER != "undefined" && USER.user_id != null ? USER.phone : ""),
			email: (typeof USER != "undefined" && USER.user_id != null ? USER.email : ""),
			postalcode: "",
			address: "",
			city: "",
			province: "",
			country: "CA"
		},
		custom_info: {},
		listeners: []
	},
	methods:
	{
		itemPrice: function(item, formatted)
		{
			if(formatted)
			{
				return "$" + number_format(item.price, 2, ".", ",");
			}
			else
			{
				return Number(item.price);
			}
		},
		itemTotal: function(item, formatted)
		{
			var total = item.price * item.quantity;

			if(formatted)
			{
				return "$" + number_format(total, 2, ".", ",");
			}
			else
			{
				return Number(total);
			}
		},
		itemTax: function(item, tax, formatted)
		{
			var taxes = this.itemTotal(item, false) * tax.tax_percentage;

			if(formatted)
			{
				return "$" + number_format(taxes, 2, ".", ",");
			}
			else
			{
				return Number(taxes);
			}
		},
		taxTotal: function(formatted)
		{
			var taxes = 0;
			var subtotal = this.subtotal() + this.shippingTotal(false);

			for(var i=0; i<this.order_info.tax_info.length; i++)
			{
				taxes += subtotal * this.order_info.tax_info[i].tax_percentage;
			}

			this.order_info.tax = Number(number_format(taxes, 2, ".", ""));

			if(formatted)
			{
				return "$" + number_format(taxes, 2, ".", ",");
			}
			else
			{
				return Number(taxes);
			}
		},
		shippingTotal: function(formatted)
		{
			if(formatted)
			{
				return "$" + number_format(this.order_info.shipping, 2, ".", ",");
			}
			else
			{
				return Number(this.order_info.shipping);
			}
		},
		subtotal: function(formatted)
		{
			var subtotal = 0;

			for(var i=0; i<this.order_info.cart.length; i++)
			{
				subtotal += (this.order_info.cart[i].price * this.order_info.cart[i].quantity);
			}

			this.order_info.subtotal = Number(number_format(subtotal, 2, ".", ""));

			if(formatted)
			{
				return "$" + number_format(subtotal, 2, ".", ",");
			}
			else
			{
				return Number(subtotal);
			}
		},
		total: function(formatted)
		{
			var total = this.subtotal(false) + this.taxTotal(false) + this.shippingTotal(false);

			this.order_info.total = Number(number_format(total, 2, ".", ""));

			if(formatted)
			{
				return "$" + number_format(total, 2, ".", ",");
			}
			else
			{
				return Number(total);
			}
		},
		updateCart: function(cart_id, quantity)
		{
			shopUpdateCart(cart_id, quantity, null);
		},
		postalcodeLookup: function()
		{
			jQuery("label.shop-spinner").append(" <i class='fas fa-spin fa-spinner'></i>");

			jQuery.post
		    (
		        "/shop/geocode",
		        {
		            postalcode: this.shipping_info.postalcode
		        },
		        function(data)
		        {
		        	try
		        	{
		        		ncms_checkout.shipping_info.postalcode = data.postalcode;
		        		ncms_checkout.shipping_info.city       = data.city;
		        		ncms_checkout.shipping_info.province   = data.province;
		        		ncms_checkout.shipping_info.country    = data.country;
		        	}
		        	catch(e){}

		        	jQuery("label.shop-spinner").each(function()
					{
						jQuery(this).find("i").remove();
						jQuery(this).html(jQuery(this).html().trim());
					});

		        	ncms_checkout.updateShippingGateway();
		        	ncms_checkout.updateTaxes();
		        }
		    );
		},
		updateTaxes: function()
		{
			jQuery.post
		    (
		        "/shop/taxes",
		        {
		            country: this.shipping_info.country,
		            province: this.shipping_info.province
		        },
		        function(data)
		        {
		        	if(typeof data == "object")
		        	{
						ncms_checkout.order_info.tax_info = data;
		        	}
		        }
		    );
		},
		updatePaymentGateway: function()
		{
			this.$nextTick(function()
			{
				// External <script> tags have been replaced by <aside src="...">
				jQuery("aside[src]").each(function()
				{
					var s = document.createElement("script");
					s.setAttribute("src", jQuery(this).attr("src"));
					document.body.appendChild(s);
					jQuery(this).detach();
				});

				// Inline <script> tags have been replaced by <aside type="text/javascript">
				jQuery("aside[type]").each(function()
				{
					var s = document.createElement("script");
					s.innerHTML = jQuery(this).html();
					document.body.appendChild(s);
					jQuery(this).detach();
				});
			});

			return;

			/*
			if(this.payment_info.payment_gateway_id <= 0)
			{
				return;
			}

			//attempt to abort any already in progress AJAX requests for shipping
			//this will fail if none are active, so we ignore the exception
			try
			{
				xhr.abort();
			}
			catch(e){}

			jQuery("#payment_gateway").html("<div class='alert alert-success text-center'><i class='fas fa-spin fa-spinner'></i> Loading Payment Options...</div>");

			xhr = jQuery.post
		    (
		        "/shop/payment_gateway/" + this.payment_info.payment_gateway_id, null,
		        function(data)
		        {
		        	var parts = data.split("----------");
		        	jQuery("#payment_gateway").html(parts[0]);
		        	jQuery("#payment_gateway_summary").html(parts[1]);
		        	// ncms_checkout.$forceUpdate();
		        }
		    );*/
		},
		showShippingGateway: function()
		{
			shopDisableContinue("You must choose a shipping method in order to continue.");

			this.updateShippingGateway();
			this.updateTaxes();
		},
		updateShippingGateway: function()
		{
			if(this.shipping_info.shipping_gateway_id <= 0)
			{
				return;
			}

			//attempt to abort any already in progress AJAX requests for shipping
			//this will fail if none are active, so we ignore the exception
			try
			{
				xhr.abort();
			}
			catch(e){}

			shopDisableContinue("You must choose a shipping method in order to continue.");

			jQuery("#shipping_gateway").html("<div class='alert alert-success text-center'><i class='fas fa-spin fa-spinner'></i> Loading Shipping Options...</div>");

			xhr = jQuery.post
		    (
		        "/shop/shipping_rates",
		        {
		            shipping_gateway_id:this.shipping_info.shipping_gateway_id,
		            shipping_address: 	this.shipping_info.address,
		            shipping_city: 		this.shipping_info.city,
		            shipping_province: 	this.shipping_info.province,
		            shipping_postalcode:this.shipping_info.postalcode,
		            shipping_country: 	this.shipping_info.country
		        },
		        function(data)
		        {
		        	jQuery("#shipping_gateway").html(data);

		        	ncms_checkout.updateTaxes();
		        }
		    );
		},
		updateShippingService: function(name)
		{
			shopUpdateShippingService(name);
		},
		updatePaymentService: function(name)
		{
			shopUpdatePaymentService(name);
		},
		confirmOrder: function()
		{
			for(var i=0; i<this.listeners.length; i++)
			{
				// All listeners must return true, otherwise we stop.
				// Only the active gateway gets notified.
				if(this.listeners[i].payment_gateway_id == this.payment_info.payment_gateway_id && !this.listeners[i].callback("confirmOrder"))
				{
					return;
				}
			}

			this.edit = false;
			this.messages = ["Please confirm your order information."];

			this.$nextTick(function()
			{
				jQuery('html, body').animate({
			    	scrollTop: 0
				});
			});
		},
		submitOrder: function()
		{
			for(var i=0; i<this.listeners.length; i++)
			{
				// All listeners must return true, otherwise we stop.
				// Only the active gateway gets notified.
				if(this.listeners[i].payment_gateway_id == this.payment_info.payment_gateway_id && !this.listeners[i].callback("submitOrder"))
				{
					return;
				}
			}

			jQuery("#shop-submit-order").prop("disabled", true);
			jQuery("#shop-submit-order").html("<i class='fas fa-spin fa-spinner'></i> Submitting Order...", true);

			var data = {
				order_info: this.order_info,
				payment_info: this.payment_info,
				shipping_info: this.shipping_info,
				custom_info: this.custom_info
			};

			jQuery.ajax({
			    url: '/shop/process',
			    type: "post",
			    data: jQuery.param(data),
			    dataType: 'json',
			    success: function (data, textStatus, jqXHR)
			    {
			        jQuery("#shop-submit-order").removeAttr("disabled");
					jQuery("#shop-submit-order").removeAttr("title");
					jQuery("#shop-submit-order").html("<i class='fas fa-thumbs-up'></i> Submit Order", true);

			    	if(data.status == 1)
			    	{
			    		ncms_checkout.messages = data.messages;
			    		ncms_checkout.errors   = [];
			    		ncms_checkout.done     = true;
			    		shopGetCart();

			    		ncms_checkout.$nextTick(function()
						{
							jQuery('html, body').animate({
						    	scrollTop: 0
							});
						});
			    	}
			    },
			    error: function (jqXHR, textStatus, errorThrown)
			    {
			    	jQuery("#shop-submit-order").removeAttr("disabled");
					jQuery("#shop-submit-order").removeAttr("title");
					jQuery("#shop-submit-order").html("<i class='fas fa-thumbs-up'></i> Submit Order", true);

			    	var data = "";

			    	try
			    	{
			    		JSON.parse(jqXHR.responseText);
			    	}
			    	catch(e)
			    	{
			    		ncms_checkout.messages = [];
			    		ncms_checkout.errors   = ["The server returned an unknown response. Please try again or contact us to confirm your order."];

			    		return;
			    	}

			    	if(data.status == 0)
			    	{
			    		ncms_checkout.messages = [];
			    		ncms_checkout.errors   = data.errors;
			    	}

		    		ncms_checkout.$nextTick(function()
					{
						jQuery('html, body').animate({
					    	scrollTop: 0
						});
					});
			    }
			});
		},
		editBilling: function()
		{
			this.edit = true;

			this.$nextTick(function()
			{
				jQuery('html, body').animate({
			    	scrollTop: jQuery("#shop_cart_billing")[0].getBoundingClientRect().top - document.body.getBoundingClientRect().top
				});
			});
		},
		editShipping: function()
		{
			this.edit = true;

			this.$nextTick(function()
			{
				jQuery('html, body').animate({
			    	scrollTop: jQuery("#shop_cart_shipping")[0].getBoundingClientRect().top - document.body.getBoundingClientRect().top
				});
			});
		},
		addEventListener: function(payment_gateway_id, func)
		{
			var obj = {payment_gateway_id: payment_gateway_id, callback: func};

			for(var i=0; i<this.listeners.length; i++)
			{
				if(this.listeners[i].payment_gateway_id == payment_gateway_id)
				{
					return;
				}
			}

			this.listeners.push(obj);
		}
	},
	mounted: function()
	{
		if(jQuery(".payment_gateway_radio").size() == 1)
		{
			jQuery(".payment_gateway_radio").click();
		}
		if(jQuery(".shipping_gateway_radio").size() == 1)
		{
			jQuery(".shipping_gateway_radio").click();
		}

		shopGetCart();
		this.updateTaxes();
	}
});

function shopAddToCart(page_id, quantity, product_options, e)
{
	try
	{
		e.preventDefault();
	}
	catch(e){}

	jQuery.ajax({
	    url: '/shop/cart',
	    type: "post",
	    data: jQuery.param({page_id: page_id, quantity: quantity, product_options: product_options}),
	    dataType: 'json',
	    success: function (data)
	    {
	        shopGetCart();

			if(jQuery("#shop-cart-floater").is(':visible'))
			{
				shopCartSummary(jQuery("#shop-cart-floater"), true);

				setTimeout(function()
				{
					shopCartSummary(jQuery("#shop-cart-floater"), true);
				}, 3000);
			}
			else if(jQuery(".shop-cart-button").is(':visible'))
			{
				shopCartSummary(jQuery(".shop-cart-button:visible"), true);

				setTimeout(function()
				{
					shopCartSummary(jQuery(".shop-cart-button:visible"), true);
				}, 3000);
			}
			else
			{
				window.location = SHOP_CONFIG["cart_url"];
			}
	    }
	});
}

function shopUpdateCart(cart_id, quantity, e)
{
	try
	{
		e.preventDefault();
	}
	catch(e){}

	jQuery.ajax({
	    url: '/shop/cart',
	    type: "put",
	    data: jQuery.param({cart_id: cart_id, quantity: quantity}),
	    dataType: 'json',
	    success: function (data)
	    {
	        ncms_checkout.updateShippingGateway();
			ncms_checkout.updateTaxes();
			shopGetCart();
	    }
	});
}

function shopGetCart()
{
	jQuery.ajax({
	    url: '/shop/cart',
	    type: 'get',
	    dataType: 'json',
	    success: function (data)
	    {
			var cart_total                = 0;
			var qty_total                 = 0;
			var details                   = '<div class="form-row mb-2">';
			var summary                   = '';
			ncms_checkout.order_info.cart = data;

			for(var i=0; i<data.length; i++)
			{
				details += '<div class="col-12">' + Number(data[i].quantity) + " x " + data[i].title;

				if(data[i].product_options.length > 0)
				{
					details += "<ul class='shop-cart-summary'>";

					for(var x=0; x<data[i].product_options.length; x++)
					{
						details += "<li>" + data[i].product_options[x] + "</li>";
					}

					details += "</ul>";
				}

				details += '</div><div class="col-6">$' + number_format(Number(data[i].price), 2, ".", ",") + ' each</div><div class="col-6 text-right">$' + number_format(Number(data[i].price) * Number(data[i].quantity), 2, ".", ",") + '</div>';
				details += '<div class="col-12">&nbsp;</div>';
				qty_total += Number(data[i].quantity);
				cart_total += (Number(data[i].quantity) * Number(data[i].price));
			}
			details += '<div class="col-6 text-right">Subtotal</div><div class="col-6 text-right">' + SHOP_CONFIG.currency_code + ' $' + number_format(Number(cart_total), 2, ".", ",") + '</div>';
			details += '</div>';

			summary = '$' + number_format(Number(cart_total), 2, ".", ",");

			jQuery(".shop-cart-summary").html(summary);
			jQuery(".shop-cart-details").html(details);
			jQuery(".shop-cart-quantity").html(qty_total);
	    }
	});
}

function shopCartSummary(jqobj, slidedown)
{
	// On small screens, if there is more than one cart button, use the last one (probably a footer bar).
	if(jQuery(window).width() < 768)
	{
		slidedown = false;

		if(jqobj.length > 1)
		{
			jqobj = jqobj.eq(jqobj.length-1);
		}
	}

	if(typeof jqobj == "undefined" || jqobj.length == 0)
	{
		return false;
	}

	var obj 	= jQuery('#shop-cart-floater-details');
	var bottom 	= jqobj.offset().top - jQuery(window).scrollTop() + jqobj.outerHeight(true);

	if(typeof obj == "undefined" || obj.length == 0)
	{
		return false;
	}

	if(slidedown)
	{
		obj.css({top: bottom}).slideToggle();
	}
	else
	{
		obj.css({bottom: jqobj.outerHeight(true)}).fadeToggle();
	}

	return false;
}

function shopCheckCartButton()
{
    var obj 			= jQuery(".shop-cart-module");
    var top_of_object 	= obj.position().top + obj.outerHeight();
    var top_of_window 	= jQuery(window).scrollTop();

    if(top_of_object < top_of_window && jQuery(window).width() >= 768)
    {
        jQuery('#shop-cart-floater').fadeIn(250);
    }
    else
    {
        jQuery('#shop-cart-floater').fadeOut(250);
    }
}

function shopUpdateShippingCost(new_cost)
{
	ncms_checkout.order_info.shipping = new_cost;
	ncms_checkout.updateTaxes();
}

function shopEnableContinue()
{
	jQuery("#shop_continue").removeAttr("disabled");
	jQuery("#shop_continue").removeAttr("title");
}

function shopDisableContinue(message)
{
	jQuery("#shop_continue").prop("disabled", true);
	jQuery("#shop_continue").attr("title", message);
}

function shopUpdateShippingService(name)
{
	ncms_checkout.shipping_info.shipping_gateway = name;
}

function shopUpdatePaymentService(name)
{
	ncms_checkout.payment_info.payment_gateway = name;
}

function shopAddEventListener(payment_gateway_id, func)
{
	ncms_checkout.addEventListener(payment_gateway_id, func);
}