// Miva Merchant
//
// This file and the source codes contained herein are the property of
// Miva, Inc.  Use of this file is restricted to the specific terms and
// conditions in the License Agreement associated with this file.  Distribution
// of this file or portions of this file for uses not covered by the License
// Agreement is not allowed without a written agreement signed by an officer of
// Miva, Inc.
//
// Copyright 1998-2025 Miva, Inc.  All rights reserved.
// http://www.miva.com
//

(function( obj, eventType, fn )
{
	if ( obj.addEventListener )
	{
		obj.addEventListener( eventType, fn, false );
	}
	else if ( obj.attachEvent )
	{
		obj.attachEvent( 'on' + eventType, fn );
	}
})( window, 'load', function()
{
	var i, i_len, elements;

	if ( window.ApplePaySession && ApplePaySession.canMakePayments() )
	{
		elements = document.querySelectorAll( '[data-mm-applepay-button]' );

		for ( i = 0, i_len = elements.length; i < i_len; i++ )
		{
			elements[ i ].style.display = '';
		}
	}
});

function ApplePayUI_Begin( button_element, type, applepay_paymentrequest )
{
	if ( !applepay_paymentrequest )
	{
		return;
	}

	ui = new ApplePayUI( button_element, applepay_paymentrequest, type );
}

function ApplePayUI( button_element, request, type )
{
	var self = this;

	this.button_element						= button_element;
	this.request							= request;
	this.type								= type;
	this.product_add_form					= null;
	this.current_shipping_method			= null;

	if ( this.type === 'product' )
	{
		this.product_add_form				= this.FindAndValidateProductAddForm();
		if ( !this.product_add_form )
		{
			return;
		}
	}

	this.session							= new ApplePaySession( ApplePaySession.supportsVersion( 3 ) ? 3 : 1, this.request );

	this.session.onvalidatemerchant			= function( event ) { self.OnValidateMerchant( event ); };
	this.session.onshippingcontactselected	= function( event ) { self.OnShippingContactSelected( event ); };
	this.session.onshippingmethodselected	= function( event ) { self.OnShippingMethodSelected( event ); };
	this.session.onpaymentauthorized		= function( event ) { self.OnPaymentAuthorized( event ); };
	this.session.oncancel					= function( event ) { ApplePay_Cancel( function( response ) { ; } ) };

	this.session.begin();
}

ApplePayUI.prototype.FindAndValidateProductAddForm = function()
{
	var form;

	for ( form = this.button_element.parentNode; form && form.nodeName != 'FORM'; form = form.parentNode )
	{
		;
	}

	if ( !form )								return;
	if ( !this.FormIsProductAdd( form ) )		return;

	return form;
}

ApplePayUI.prototype.FormIsProductAdd = function( form )
{
	return form.elements[ 'Quantity' ] && form.elements[ 'Product_Code' ] && form.elements[ 'Action' ] &&
		   form.elements[ 'Action' ].value === 'ADPR';
}

ApplePayUI.prototype.FormGatherInputElements = function( parent_element )
{
	var i, j, elements, field, type, output_array;

	output_array	= new Array();
	elements		= parent_element.getElementsByTagName( "input" );

	for ( i = 0; i < elements.length; i++ )
	{
		type		= elements[ i ].type.toLowerCase();

		if ( ( type == 'text' ) || ( type == 'number' ) || ( type == 'tel' ) || ( type == 'hidden' ) )
		{
			field		= new Object();
			field.name	= elements[ i ].name;
			field.value	= elements[ i ].value;

			output_array.push( field );
		}
		else if ( ( type == 'checkbox' ) || ( type == 'radio' ) )
		{
			if ( elements[ i ].checked )
			{
				field		= new Object();
				field.name	= elements[ i ].name;
				field.value	= elements[ i ].value;

				output_array.push( field );
			}
		}
	}

	elements = parent_element.getElementsByTagName( "textarea" );
	for ( i = 0; i < elements.length; i++ )
	{
		field		= new Object();
		field.name	= elements[ i ].name;
		field.value	= elements[ i ].value;

		output_array.push( field );
	}

	elements = parent_element.getElementsByTagName( "select" );
	for ( i = 0; i < elements.length; i++ )
	{
		if ( elements[ i ].selectedIndex >= 0 && elements[ i ].options[ elements[ i ].selectedIndex ] )
		{
			if ( !elements[ i ].multiple )
			{
				field		= new Object();
				field.name	= elements[ i ].name;
				field.value	= elements[ i ].options[ elements[ i ].selectedIndex ].value;

				output_array.push( field );
			}
			else
			{
				for ( j = 0; j < elements[ i ].options.length; j++ )
				{
					if ( !elements[ i ].options[ j ].selected )	continue;

					field		= new Object();
					field.name	= elements[ i ].name;
					field.value = elements[ i ].options[ j ].value;

					output_array.push( field );
				}
			}
		}
	}

	output_array = output_array.filter( function( field )
	{
		var name = field.name.toLowerCase();

		if ( name == 'quantity'							||
			 name == 'product_code'						||
			 name == 'product_subscription_term_id'		||
			 name.indexOf( 'product_attributes[' ) == 0 )
		{
			return true;
		}

		return false;
	} );

	return output_array;
}

ApplePayUI.prototype.OnValidateMerchant = function( event )
{
	var self = this;
	var fields, validate;

	validate = function()
	{
		ApplePay_ValidateMerchant( event.validationURL, function( response )
		{
			if ( !response.success )
			{
				self.session.abort();

				if ( response.error_message.indexOf( 'License is blacklisted' ) != -1 )
				{
					self.button_element.style.display = 'none';
				}
				else
				{
					alert( response.error_message );
				}

				return;
			}

			self.session.completeMerchantValidation( response.data );
		} );
	};

	if ( !this.product_add_form )
	{
		return validate();
	}

	fields					= this.FormGatherInputElements( this.product_add_form );
	this.product_add_form	= null;

	ApplePay_SetBasketProduct( fields, function( response )
	{
		if ( !response.success )
		{
			self.session.abort();
			alert( response.error_message );

			return;
		}

		validate();
	} );
}

ApplePayUI.prototype.OnShippingContactSelected = function( event )
{
	var i;
	var self = this;

	ApplePay_ShippingContactSelected( event.shippingContact, this.current_shipping_method ? this.current_shipping_method.identifier : '', function( response )
	{
		if ( !response.success )
		{
			if ( !ApplePaySession.supportsVersion( 3 ) )
			{
				self.session.completeShippingContactSelection( ApplePaySession.STATUS_INVALID_SHIPPING_POSTAL_ADDRESS, [], self.request.total, self.request.lineItems );
			}
			else
			{
				self.session.completeShippingContactSelection(
					{
						errors:		[ new ApplePayError( "addressUnserviceable", "name", response.error_message ) ],
						newTotal:	self.request.total
					}
				);
			}

			return;
		}

		self.request.shippingMethods	= response.data.shippingMethods;
		self.request.total				= response.data.total;
		self.request.lineItems			= response.data.lineItems;

		if ( self.current_shipping_method )
		{
			for ( i = 1; i < self.request.shippingMethods.length; i++ )
			{
				if ( self.request.shippingMethods[ i ].identifier === self.current_shipping_method.identifier )
				{
					self.request.shippingMethods.splice( 0, 0, self.request.shippingMethods.splice( i, 1 )[ 0 ] );
					break;
				}
			}
		}

		self.session.completeShippingContactSelection( ApplePaySession.STATUS_SUCCESS, self.request.shippingMethods, self.request.total, self.request.lineItems );
	} );
}

ApplePayUI.prototype.OnShippingMethodSelected = function( event )
{
	var self = this;

	ApplePay_ShippingMethodSelected( event.shippingMethod, function( response )
	{
		if ( !response.success )
		{
			self.session.completeShippingMethodSelection( ApplePaySession.STATUS_FAILURE, self.request.total, self.request.lineItems );
			return;
		}

		self.current_shipping_method	= event.shippingMethod;
		self.request.total				= response.data.total;
		self.request.lineItems			= response.data.lineItems;

		self.session.completeShippingMethodSelection( ApplePaySession.STATUS_SUCCESS, self.request.total, self.request.lineItems );
	} );
}

ApplePayUI.prototype.OnPaymentAuthorized = function( event )
{
	var self = this;
	var errors, i, i_len;
	var form, session_id, checkout_session_id, applepay_checkout;

	ApplePay_PaymentAuthorized( event.payment, function( response )
	{
		if ( !response.success )
		{
			if ( !ApplePaySession.supportsVersion( 3 ) )
			{
				self.session.completePayment( ApplePaySession.STATUS_FAILURE );
			}
			else
			{
				errors = new Array();

				if ( response.error_fields )
				{
					for ( i = 0, i_len = response.error_fields.length; i < i_len; i++ )
					{
						if ( response.error_fields[ i ] === 'Ship_FirstName' )		errors.push( new ApplePayError( 'shippingContactInvalid', 'name',			'Invalid first name' ) );
						else if ( response.error_fields[ i ] === 'Ship_LastName' )	errors.push( new ApplePayError( 'shippingContactInvalid', 'name',			'Invalid last name' ) ) ;
						else if ( response.error_fields[ i ] === 'Ship_Email' )		errors.push( new ApplePayError( 'shippingContactInvalid', 'emailAddress',	'Invalid email address' ) ) ;
						else if ( response.error_fields[ i ] === 'Ship_Phone' )		errors.push( new ApplePayError( 'shippingContactInvalid', 'phoneNumber',	'Invalid phone number' ) ) ;
						else if ( response.error_fields[ i ] === 'Ship_Address1' )	errors.push( new ApplePayError( 'shippingContactInvalid', 'postalAddress',	'Invalid address' ) ) ;
						else if ( response.error_fields[ i ] === 'Ship_Address2' )	errors.push( new ApplePayError( 'shippingContactInvalid', 'postalAddress',	'Invalid address' ) ) ;
						else if ( response.error_fields[ i ] === 'Ship_City' )		errors.push( new ApplePayError( 'shippingContactInvalid', 'subLocality',	'Invalid city' ) ) ;
						else if ( response.error_fields[ i ] === 'Ship_State' )		errors.push( new ApplePayError( 'shippingContactInvalid', 'locality',		'Invalid state' ) ) ;
						else if ( response.error_fields[ i ] === 'Ship_Zip' )		errors.push( new ApplePayError( 'shippingContactInvalid', 'postalCode',		'Invalid postal code' ) ) ;
						else if ( response.error_fields[ i ] === 'Ship_Country' )	errors.push( new ApplePayError( 'shippingContactInvalid', 'country',		'Invalid country' ) ) ;
						else if ( response.error_fields[ i ] === 'Bill_FirstName' )	errors.push( new ApplePayError( 'billingContactInvalid', 'name',			'Invalid first name' ) );
						else if ( response.error_fields[ i ] === 'Bill_LastName' )	errors.push( new ApplePayError( 'billingContactInvalid', 'name',			'Invalid last name' ) ) ;
						else if ( response.error_fields[ i ] === 'Bill_Email' )		errors.push( new ApplePayError( 'billingContactInvalid', 'emailAddress',	'Invalid email address' ) ) ;
						else if ( response.error_fields[ i ] === 'Bill_Phone' )		errors.push( new ApplePayError( 'billingContactInvalid', 'phoneNumber',		'Invalid phone number' ) ) ;
						else if ( response.error_fields[ i ] === 'Bill_Address1' )	errors.push( new ApplePayError( 'billingContactInvalid', 'postalAddress',	'Invalid address' ) ) ;
						else if ( response.error_fields[ i ] === 'Bill_Address2' )	errors.push( new ApplePayError( 'billingContactInvalid', 'postalAddress',	'Invalid address' ) ) ;
						else if ( response.error_fields[ i ] === 'Bill_City' )		errors.push( new ApplePayError( 'billingContactInvalid', 'subLocality',		'Invalid city' ) ) ;
						else if ( response.error_fields[ i ] === 'Bill_State' )		errors.push( new ApplePayError( 'billingContactInvalid', 'locality',		'Invalid state' ) ) ;
						else if ( response.error_fields[ i ] === 'Bill_Zip' )		errors.push( new ApplePayError( 'billingContactInvalid', 'postalCode',		'Invalid postal code' ) ) ;
						else if ( response.error_fields[ i ] === 'Bill_Country' )	errors.push( new ApplePayError( 'billingContactInvalid', 'country',			'Invalid country' ) ) ;
					}
				}

				if ( errors.length == 0 )
				{
					errors.push( new ApplePayError( 'unknown', 'name', response.error_message ) );
				}

				self.session.completePayment(
					{
						status:	ApplePaySession.STATUS_FAILURE,
						errors: errors
					}
				);
			}

			return;
		}

		self.session.completePayment( ApplePaySession.STATUS_SUCCESS );

		form						= document.createElement( 'form' );
		form.method					= 'POST';
		form.action					= response.data.invoice_url;

		session_id					= document.createElement( 'input' );
		session_id.type				= 'hidden';
		session_id.name				= 'Session_ID';
		session_id.value			= response.data.session_id;

		checkout_session_id			= document.createElement( 'input' );
		checkout_session_id.type	= 'hidden';
		checkout_session_id.name	= 'Checkout_Session_ID';
		checkout_session_id.value	= response.data.checkout_session_id;

		applepay_checkout			= document.createElement( 'input' );
		applepay_checkout.type		= 'hidden';
		applepay_checkout.name		= 'ApplePay_Checkout';
		applepay_checkout.value		= '1';

		form.appendChild( session_id );
		form.appendChild( checkout_session_id );
		form.appendChild( applepay_checkout );

		document.body.appendChild( form );
		form.submit();
	} );
}

// AJAX Calls
///////////////////////////////////////////////

function ApplePay_SetBasketProduct( fields, callback )
{
	return AJAX_Call_Module_FieldList( callback,
									   'runtime',
									   'applepay',
									   'SetBasketProduct',
									   '',
									   fields );
}

function ApplePay_ValidateMerchant( url, callback )
{
	return AJAX_Call_Module( callback,
							 'runtime',
							 'applepay',
							 'ValidateMerchant',
							 'ValidationURL=' + encodeURIComponent( url ) );
}

function ApplePay_ShippingContactSelected( contact, shippingmethod, callback )
{
	return AJAX_Call_Module( callback,
							 'runtime',
							 'applepay',
							 'ShippingContactSelected',
							 'Ship_City='		+ encodeURIComponent( contact.locality )					+
							 '&Ship_State='		+ encodeURIComponent( contact.administrativeArea )			+
							 '&Ship_Zip='		+ encodeURIComponent( contact.postalCode )					+
							 '&Ship_Country='	+ encodeURIComponent( contact.countryCode.toUpperCase() )	+
							 '&ShippingMethod='	+ encodeURIComponent( shippingmethod ) );
}

function ApplePay_ShippingMethodSelected( method, callback )
{
	return AJAX_Call_Module( callback,
							 'runtime',
							 'applepay',
							 'ShippingMethodSelected',
							 'ShippingMethod=' + encodeURIComponent( method.identifier ) );
}

function ApplePay_PaymentAuthorized( payment, callback )
{
	var ship_addr1, ship_addr2, bill_addr1, bill_addr2;

	ship_addr1 = '';
	ship_addr2 = '';
	bill_addr1 = '';
	bill_addr2 = '';

	if ( payment.shippingContact.addressLines.length != 2 ) 
	{
		ship_addr1 = payment.shippingContact.addressLines.join( ',' );
	}
	else
	{
		ship_addr1 = payment.shippingContact.addressLines[ 0 ];
		ship_addr2 = payment.shippingContact.addressLines[ 1 ];
	}

	if ( payment.billingContact.addressLines.length != 2 ) 
	{
		bill_addr1 = payment.billingContact.addressLines.join( ',' );
	}
	else
	{
		bill_addr1 = payment.billingContact.addressLines[ 0 ];
		bill_addr2 = payment.billingContact.addressLines[ 1 ];
	}

	return AJAX_Call_Module( callback,
							 'runtime',
							 'applepay',
							 'PaymentAuthorized',
							 'Ship_FirstName='		+ encodeURIComponent( payment.shippingContact.givenName )					+
							 '&Ship_LastName='		+ encodeURIComponent( payment.shippingContact.familyName )					+
							 '&Ship_Email='			+ encodeURIComponent( payment.shippingContact.emailAddress )				+
							 '&Ship_Phone='			+ encodeURIComponent( payment.shippingContact.phoneNumber )					+
							 '&Ship_Address1='		+ encodeURIComponent( ship_addr1 )											+
							 '&Ship_Address2='		+ encodeURIComponent( ship_addr2 )											+
							 '&Ship_City='			+ encodeURIComponent( payment.shippingContact.locality )					+
							 '&Ship_State='			+ encodeURIComponent( payment.shippingContact.administrativeArea )			+
							 '&Ship_Zip='			+ encodeURIComponent( payment.shippingContact.postalCode )					+
							 '&Ship_Country='		+ encodeURIComponent( payment.shippingContact.countryCode.toUpperCase() )	+
							 '&Bill_FirstName='		+ encodeURIComponent( payment.billingContact.givenName )					+
							 '&Bill_LastName='		+ encodeURIComponent( payment.billingContact.familyName )					+
							 '&Bill_Address1='		+ encodeURIComponent( bill_addr1 )											+
							 '&Bill_Address2='		+ encodeURIComponent( bill_addr2 )											+
							 '&Bill_City='			+ encodeURIComponent( payment.billingContact.locality )						+
							 '&Bill_State='			+ encodeURIComponent( payment.billingContact.administrativeArea )			+
							 '&Bill_Zip='			+ encodeURIComponent( payment.billingContact.postalCode )					+
							 '&Bill_Country='		+ encodeURIComponent( payment.billingContact.countryCode.toUpperCase() )	+
							 '&Payment_Token='		+ encodeURIComponent( JSON.stringify( payment.token ) ) );
}

function ApplePay_Cancel( callback )
{
	return AJAX_Call_Module( callback,
							 'runtime',
							 'applepay',
							 'Cancel',
							 '' );
}
