<?php
class Calendarista_PaymentStripeTmpl extends Calendarista_TemplateBase{
	public $stripeSetting;
	public $currency;
	public $fullName;
	public $firstname;
	public $lastname;
	public $email;
	public $totalAmount;
	public $totalAmountBeforeDeposit;
	public $fullAmountDiscount;
	public $itemName;
	public $stagingId;
	public $country;
	public $seats;
	public function __construct($setting, $stagingId){
		parent::__construct();
		$this->stripeSetting = $setting;
		$this->stagingId = $stagingId;
		if(!has_filter('calendarista_checkout_summary')) {
			return;
		}
		$checkoutSummary = apply_filters('calendarista_checkout_summary', false);
		if($checkoutSummary['totalAmount'] > 0){
			$this->firstname = $checkoutSummary['firstname'];
			$this->lastname = $checkoutSummary['lastname'];
			$this->fullName = sprintf('%s %s', $this->firstname, $this->lastname);
			$this->email = $checkoutSummary['email'];
			$this->totalAmount = self::formatCurrency($checkoutSummary['totalAmount'], $checkoutSummary['currency']);
			$this->totalAmountBeforeDeposit = $checkoutSummary['totalAmountBeforeDeposit'];
			$this->fullAmountDiscount = $checkoutSummary['fullAmountDiscount'];
			$this->currency = $checkoutSummary['currency'];
			$this->seats = $checkoutSummary['seats'];
			$this->itemName = sprintf($this->stringResources['PAYMENT_ITEM_NAME'], $checkoutSummary['serviceName'], $checkoutSummary['availabilityName']);
			$this->confirmUrl = $this->getConfirmUrl($this->requestUrl, null, 'stripe', false);
			$this->country = $checkoutSummary['country'];
			$this->render();
		}
	}
	public static function formatCurrency($val, $currency){
		$currencyDesc = Calendarista_MoneyHelper::getCurrencyByCode($currency);
		if($currencyDesc && $currencyDesc['decimal_digits'] === 0){
			//zero-decimal currencies
			return $val;
		}
		return round($val * 100);
	}
	public function getUpfrontAmount($val){
		$fullAmountDiscount = $this->fullAmountDiscount;
		if($fullAmountDiscount && $this->seats > 1){
			$fullAmountDiscount = $fullAmountDiscount * $this->seats;
		}
		if($fullAmountDiscount > 0 && 
			$this->totalAmountBeforeDeposit > $fullAmountDiscount){
			$discountedValue = $this->totalAmountBeforeDeposit - $fullAmountDiscount;
			return self::formatCurrency($discountedValue, $this->currency);
		}else if($this->totalAmountBeforeDeposit > 0){
			return self::formatCurrency($this->totalAmountBeforeDeposit, $this->currency);
		}
		return $val;
	}
	public function render(){
	?>
		<form action="<?php echo $this->confirmUrl ?>" method="POST"  
			id="payment-operator-<?php echo sprintf('%d-%d', $this->stripeSetting->id, $this->projectId) ?>" 
			data-calendarista-operator-panel="#card_form_stripe_<?php echo $this->uniqueId ?>"
			data-calendarista-payment-operator="stripe" data-calendarista-total-name="total" data-calendarista-original-total="<?php echo $this->totalAmount ?>">
			<input type="hidden" name="itemName" value="<?php echo $this->itemName ?>"/>
			<input type="hidden" name="total" value="<?php echo $this->totalAmount ?>" />
			<input type="hidden" name="_total" value="<?php echo $this->totalAmount ?>" />
			<input type="hidden" name="upfront_amount" value="<?php echo $this->getUpfrontAmount($this->totalAmount) ?>">
			<input type="hidden" name="total_before_deposit" value="<?php echo $this->totalAmountBeforeDeposit ?>" />
			<input type="hidden" name="currency" value="<?php echo $this->currency ?>"/>
			<input type="hidden" name="full_name" value="<?php echo $this->fullName ?>"/>
			<input type="hidden" name="customer_email" value="<?php echo $this->email ?>"/>
			<input type="hidden" name="country" value="<?php echo $this->country ?>"/>
			<input type="hidden" name="stagingId" value="<?php echo $this->stagingId ?>" />
			<input type="hidden" name="action" value="calendarista_stripe_charge" />
			<input type="hidden" name="upfrontPayment" value="0"/>
		</form>
		
		<script type="text/javascript">
			(function($, wp) {
				"use strict";
				var Calendarista = window['Calendarista'] ? window['Calendarista'] : function(){};
				Calendarista.Stripe = function(){
					var cardSelector = '#calendarista_card_element_<?php echo $this->uniqueId ?>'
						, $cardElement
						, elements
						, style = {
							  base: {
								color: '#32325d',
								fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
								fontSmoothing: 'antialiased',
								fontSize: '18px',
								'::placeholder': {
								  color: '#aab7c4'
								}
							  },
							  invalid: {
								color: '#fa755a',
								iconColor: '#fa755a'
							  }
						};
					$cardElement = $(cardSelector);
					if($cardElement.length > 0){
						this.stripe = Stripe('<?php echo $this->stripeSetting->publishableKey ?>');
						elements = this.stripe.elements();
					this.card = elements.create('card', {style: style, hidePostalCode: true});
						this.card.mount(cardSelector);
					}
				};
				Calendarista.Stripe.fullName = function(){
					return '<?php echo $this->decodeString($this->fullName) ?>';
				};
				Calendarista.Stripe.email = function(){
					return '<?php echo $this->decodeString($this->email) ?>';
				};
				Calendarista.Stripe.form = function(){
					return $("#payment-operator-<?php echo sprintf('%d-%d', $this->stripeSetting->id, $this->projectId) ?>");
				};
				Calendarista.Stripe.prevButton = function(){
					return $('#<?php echo $this->uniqueId ?> button[name="prev"]');
				};
				Calendarista.Stripe.prototype.tokenRequest = function(){
					// Set token request parameters
					var context = this
						, $form = Calendarista.Stripe.form();
					Calendarista.Stripe.showSpinner();
					this.stripe.createPaymentMethod('card', this.card, {
						'billing_details': {
							'name': Calendarista.Stripe.fullName()
							, 'email': Calendarista.Stripe.email()
						}
					}).then(function(result) {
						if (result.error) {
						  context.errorCallback(result.error.message);
						} else {
						  // Otherwise send paymentMethod.id to your server (see Step 2)
						  fetch('<?php echo $this->ajaxUrl ?>', {
							method: 'post',
							headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
						  body: $.param(context.toJson([{'name': 'calendarista_nonce', 'value': wp.nonce}, {'name': 'payment_method_id', 'value': result.paymentMethod.id}].concat($form.serializeArray())))
						  }).then(function(result) {
							// Handle server response (see Step 3)
							result.json().then(function(json) {
							  context.handleServerResponse(json);
							})
						  });
						}
					});
				};
				Calendarista.Stripe.prototype.handleServerResponse = function(response) {
					var $form = Calendarista.Stripe.form();
					if (response.error) {
						// Show error from server on payment form
						this.errorCallback(typeof response.error === 'object' ? response.error.message : response.error);
					} else if (response.requires_action) {
						// Use Stripe.js to handle required card action
						this.handleAction(response);
					} else {
						// Show success message
						Calendarista.Stripe.hideSpinner();
						window.location.replace($form.attr('action') + '&invoiceId=' + response.invoiceId + '#CAL' + <?php echo $this->projectId ?>);
					}
				};
				Calendarista.Stripe.prototype.handleAction = function(response) {
					var $form = Calendarista.Stripe.form()
						, context = this;
					this.stripe.handleCardPayment(response.payment_intent_client_secret, this.card, {
						'payment_method_data': {
							'billing_details': {
								'name': Calendarista.Stripe.fullName()
								, 'email': Calendarista.Stripe.email()
							},
						},
					  }).then(function(result){
						if (result.error) {
							context.errorCallback(typeof result.error === 'object' ? result.error.message : result.error);
						} else {
							Calendarista.Stripe.showSpinner();
							// The card action has been handled
							// The PaymentIntent can be confirmed again on the server
							 fetch('<?php echo $this->ajaxUrl ?>', {
								method: 'POST',
								headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
								body: $.param(context.toJson([{'name': 'calendarista_nonce', 'value': wp.nonce}, {'name': 'payment_intent_id', 'value': result.paymentIntent.id}, {'name': 'action', 'value': 'calendarista_stripe_charge'}].concat($form.serializeArray())))
							  }).then(function(confirmResult, x) {
								confirmResult.json().then(function (json) {
									window.location.replace($form.attr('action') + '&invoiceId=' + json.invoiceId + '#CAL' + <?php echo $this->projectId ?>);
								});
							});
						}
					});
				};
				// Called when token creation fails.
				Calendarista.Stripe.prototype.errorCallback = function(errorMsg) {
					var $elem = $('#card_error_container_<?php echo $this->uniqueId ?>')
						, $checkoutButton = $('#<?php echo $this->uniqueId ?> button[name="booknow"]')
						, $prevButton = Calendarista.Stripe.prevButton();
					$checkoutButton.prop('disabled', false).removeClass('ui-state-disabled');
					$prevButton.prop('disabled', false).removeClass('ui-state-disabled');
					Calendarista.Stripe.hideSpinner();
					if(errorMsg){
						$elem.removeClass('hide');
						$elem.html(errorMsg);
					}
				};
				Calendarista.Stripe.prototype.toJson = function(formData){
					var result = {};
					$(formData ).each(function(index, obj){
						result[obj.name] = obj.value;
					});
					return result;
				};
				Calendarista.Stripe.showSpinner = function(){
					var $spinner = $('#spinner_<?php echo $this->uniqueId ?>');
					$spinner.removeClass('calendarista-invisible');
				};
				Calendarista.Stripe.hideSpinner = function(){
					var $spinner = $('#spinner_<?php echo $this->uniqueId ?>');
					$spinner.addClass('calendarista-invisible');
				};
				window['Calendarista'] = Calendarista;
			})(jQuery, window['calendarista_wp_ajax']);
		</script>
	<?php
	}
}?>

