<?php
class Calendarista_WooCommerceHelper{
    public function __construct() {
		add_filter('woocommerce_product_data_tabs', array('Calendarista_WooCommerceHelper', 'wooProductDataTabs'), 10, 1);
		add_filter('product_type_selector', array('Calendarista_WooCommerceHelper', 'wooProductType'));
		add_action('woocommerce_product_data_panels', array('Calendarista_WooCommerceHelper', 'wooProductDataPanels'));
		add_action('plugins_loaded', array('Calendarista_WooCommerceHelper',  'registerCustomProductType'));
		add_filter('woocommerce_add_cart_item_data', array('Calendarista_WooCommerceHelper', 'addItemDataToCart'), 1, 3);
		add_filter('woocommerce_get_cart_item_from_session', array('Calendarista_WooCommerceHelper', 'getCartItemsFromSession'), 1, 3);
		add_filter('woocommerce_cart_item_name', array('Calendarista_WooCommerceHelper', 'cartItemName'), 1, 3);
		add_filter('woocommerce_cart_item_quantity', array('Calendarista_WooCommerceHelper', 'cartItemQuantity'), 1, 3);
		add_filter('woocommerce_checkout_cart_item_quantity', array('Calendarista_WooCommerceHelper', 'cartItemQuantityCheckout'), 1, 3);
		add_action('woocommerce_before_calculate_totals', array('Calendarista_WooCommerceHelper', 'updateCustomPrice'), 1, 1);
		add_filter('woocommerce_cart_item_thumbnail', array('Calendarista_WooCommerceHelper', 'cartItemThumbnail'), 1, 3);
		add_action('woocommerce_single_product_summary', array('Calendarista_WooCommerceHelper', 'addCalendaristaService'), 15);
		add_filter('woocommerce_get_price_html', array('Calendarista_WooCommerceHelper', 'removePriceSingleProduct'), 10, 2);
		add_filter('woocommerce_checkout_get_value' , array('Calendarista_WooCommerceHelper', 'customCheckoutFields'), 10, 2);
		add_action('woocommerce_payment_complete', array('Calendarista_WooCommerceHelper', 'paymentComplete'), 1, 1 );
		add_action('woocommerce_order_status_completed', array('Calendarista_WooCommerceHelper', 'orderStatusCompleted'), 1, 1 );
		add_action('woocommerce_order_status_processing', array('Calendarista_WooCommerceHelper', 'orderStatusProcessing'), 1, 1 );
		add_action('woocommerce_bacs_process_payment_order_status', array('Calendarista_WooCommerceHelper', 'bacsPaymentCompleted'), 10, 2);
		add_action('valid-paypal-standard-ipn-request', array('Calendarista_WooCommerceHelper', 'paypalCompleted'), 10, 1);
		add_action('woocommerce_paypal_express_checkout_valid_ipn_request', array('Calendarista_WooCommerceHelper', 'paypalCompleted'), 10, 1);
		add_action('admin_footer', array('Calendarista_WooCommerceHelper', 'registerEnableProductVisibilityScript'));
		add_action('woocommerce_before_checkout_process', array('Calendarista_WooCommerceHelper', 'beforeCheckout'));
		add_action('woocommerce_new_order_item', array('Calendarista_WooCommerceHelper', 'newOrderItemCreated'), 10, 3);
		add_action('woocommerce_thankyou', array('Calendarista_WooCommerceHelper', 'thankyou'), 10, 1);
	}
	public static function addItemDataToCart($cartItemData, $productId, $variationId) {
		$result = array();
		if(isset($_POST['calendarista_seats'])){
			$result['_calendarista_seats'] = (int)$_POST['calendarista_seats'];
		}
		if(isset($_POST['calendarista_summary'])){
			$result['_calendarista_summary'] = $_POST['calendarista_summary'];
		}
		if(isset($_POST['calendarista_availability_list'])){
			$result['_calendarista_availability_list'] = $_POST['calendarista_availability_list'];
		}
		if(isset($_POST['calendarista_optionals'])){
			$result['_calendarista_optionals'] = $_POST['calendarista_optionals'];
		}
		if(isset($_POST['calendarista_custom_form_elements'])){
			$result['_calendarista_custom_form_elements'] = $_POST['calendarista_custom_form_elements'];
		}
		if(isset($_POST['calendarista_dynamic_fields'])){
			$result['_calendarista_dynamic_fields'] = $_POST['calendarista_dynamic_fields'];
		}
		if(isset($_POST['calendarista_deposit'])){
			$result['_calendarista_deposit'] = $_POST['calendarista_deposit'];
		}
		if(isset($_POST['calendarista_item_name'])){
			$result['_calendarista_item_name'] = $_POST['calendarista_item_name'];
		}
		if(isset($_POST['calendarista_thumbnail'])){
			$result['_calendarista_thumbnail'] = $_POST['calendarista_thumbnail'];
		}
		if(isset($_POST['calendarista_optional_cost'])){
			$result['_calendarista_optional_cost'] = (double)$_POST['calendarista_optional_cost'];
		}
		if(isset($_POST['calendarista_subtotal_amount'])){
			$result['_calendarista_subtotal_amount'] = (double)$_POST['calendarista_subtotal_amount'];
		}
		if(isset($_POST['calendarista_amount'])){
			$result['_calendarista_amount'] = (double)$_POST['calendarista_amount'];
		}
		if(isset($_POST['calendarista_upfront_amount'])){
			$result['_calendarista_upfront_amount'] = (double)$_POST['calendarista_upfront_amount'];
		}
		if(isset($_POST['calendarista_amount_before_deposit'])){
			$result['_calendarista_amount_before_deposit'] = (double)$_POST['calendarista_amount_before_deposit'];
		}
		if(isset($_POST['calendarista_full_amount_discount'])){
			$result['_calendarista_full_amount_discount'] = (double)$_POST['calendarista_full_amount_discount'];
		}
		if(isset($_POST['calendarista_full_amount_discount_label'])){
			$result['_calendarista_full_amount_discount_label'] = $_POST['calendarista_full_amount_discount_label'];
		}
		if(isset($_POST['calendarista_full_amount_paid_label'])){
			$result['_calendarista_full_amount_paid_label'] = $_POST['calendarista_full_amount_paid_label'];
		}
		if(isset($_POST['upfrontPayment'])){
			$result['_upfrontPayment'] = (int)$_POST['upfrontPayment'];
		}
		if(isset($_POST['calendarista_staging_id'])){
			$result['_calendarista_staging_id'] = $_POST['calendarista_staging_id'];
		}
		if(isset($_POST['billing_first_name'])){
			$result['_billing_first_name'] = $_POST['billing_first_name'];
		}
		if(isset($_POST['billing_last_name'])){
			$result['_billing_last_name'] = $_POST['billing_last_name'];
		}
		if(isset($_POST['billing_email'])){
			$result['_billing_email'] = $_POST['billing_email'];
		}
		if(empty($cartItemData)) {
			return $result;
		} else {
			return array_merge($cartItemData, $result);
		}
	}
	//2. This captures the information from the previous function and attaches it to the item.
	public static function getCartItemsFromSession($item, $cartItem, $key) {
		if(array_key_exists('_calendarista_seats', $cartItem)){
			$item['_calendarista_seats'] = (int)$cartItem['_calendarista_seats'];
		}
		if(array_key_exists('_calendarista_summary', $cartItem)){
			$item['_calendarista_summary'] = $cartItem['_calendarista_summary'];
		}
		if(array_key_exists('_calendarista_availability_list', $cartItem)){
			$item['_calendarista_availability_list'] = $cartItem['_calendarista_availability_list'];
		}
		if(array_key_exists('_calendarista_optionals', $cartItem)){
			$item['_calendarista_optionals'] = $cartItem['_calendarista_optionals'];
		}
		if(array_key_exists('_calendarista_custom_form_elements', $cartItem)){
			$item['_calendarista_custom_form_elements'] = $cartItem['_calendarista_custom_form_elements'];
		}
		if(array_key_exists('_calendarista_dynamic_fields', $cartItem)){
			$item['_calendarista_dynamic_fields'] = $cartItem['_calendarista_dynamic_fields'];
		}
		if(array_key_exists('_calendarista_deposit', $cartItem)){
			$item['_calendarista_deposit'] = $cartItem['_calendarista_deposit'];
		}
		if(array_key_exists('_calendarista_item_name', $cartItem)){
			$item['_calendarista_item_name'] = $cartItem['_calendarista_item_name'];
		}
		if(array_key_exists('_calendarista_thumbnail', $cartItem)){
			$item['_calendarista_thumbnail'] = $cartItem['_calendarista_thumbnail'];
		}
		if(array_key_exists('_calendarista_optional_cost', $cartItem)){
			$item['_calendarista_optional_cost'] = (double)$cartItem['_calendarista_optional_cost'];
		}
		if(array_key_exists('_calendarista_subtotal_amount', $cartItem)){
			$item['_calendarista_subtotal_amount'] = (double)$cartItem['_calendarista_subtotal_amount'];
		}
		if(array_key_exists('_calendarista_amount', $cartItem)){
			$item['_calendarista_amount'] = (double)$cartItem['_calendarista_amount'];
		}
		if(array_key_exists('_calendarista_amount_before_deposit', $cartItem)){
			$item['_calendarista_amount_before_deposit'] = (double)$cartItem['_calendarista_amount_before_deposit'];
		}
		if(array_key_exists('_calendarista_full_amount_discount', $cartItem)){
			$item['_calendarista_full_amount_discount'] = (double)$cartItem['_calendarista_full_amount_discount'];
		}
		if(array_key_exists('_calendarista_full_amount_discount_label', $cartItem)){
			$item['_calendarista_full_amount_discount_label'] = $cartItem['_calendarista_full_amount_discount_label'];
		}
		if(array_key_exists('_calendarista_full_amount_paid_label', $cartItem)){
			$item['_calendarista_full_amount_paid_label'] = $cartItem['_calendarista_full_amount_paid_label'];
		}
		if(array_key_exists('_upfrontPayment', $cartItem)){
			$item['_upfrontPayment'] = (double)$cartItem['_upfrontPayment'];
		}
		if(array_key_exists('_calendarista_staging_id', $cartItem)){
			$item['_calendarista_staging_id'] = $cartItem['_calendarista_staging_id'];
		}
		if(isset($_POST['_billing_first_name'])){
			$item['_billing_first_name'] = $cartItem['_billing_first_name'];
		}
		if(isset($_POST['_billing_last_name'])){
			$item['_billing_last_name'] = $cartItem['_billing_last_name'];
		}
		if(isset($_POST['_billing_email'])){
			$item['_billing_email'] = $cartItem['_billing_email'];
		}
		return $item;
	}
	public static function customCheckoutFields($value, $key){
		$wc = WC();
		if(!$wc->session){
			return $value;
		}
		$cart = $wc->session->get('cart');
		if(!$cart || !is_array($cart)){
			return $value;
		}
		$keys = array_keys($cart);
		$lastIndex = count($keys);
		if($lastIndex > 0){
			$item = $cart[$keys[$lastIndex - 1]];
			$firstName = isset($item['_billing_first_name']) ? $item['_billing_first_name'] : null;
			$lastName = isset($item['_billing_last_name']) ? $item['_billing_last_name'] : null;
			$email = isset($item['_billing_email']) ? $item['_billing_email'] : null;

			switch ($key){
				case 'billing_first_name':
					return $firstName;
				break;
				case 'billing_last_name':
					return $lastName;
				break;
				case 'billing_email':
					return $email;
				break;
			}
		}
	}
	public static function beforeCheckout(){
		$wc = WC();
		if(!$wc->session){
			return;
		}
		$cart = $wc->session->get('cart');
		if(!$cart || !is_array($cart)){
			return;
		}
		$errorMessage = null;
		$flag1 = false;
		$flag2 = false;
		foreach($cart as $key=>$item){
			if(isset($item['_calendarista_staging_id'])){
				$stagingId = $item['_calendarista_staging_id'];
				$checkoutHelper = new Calendarista_CheckoutHelper(array('stagingId'=>$stagingId));
				if(!$checkoutHelper->stockValid()){
					WC()->cart->remove_cart_item($key);
					$flag1 = true;
					$errorMessage = $checkoutHelper->getWooCommerceOutOfStockErrorMessage();
					if(!$flag2){
						$flag2 = true;
						$checkoutHelper->notifyOutOfStock();
						$checkoutHelper->deleteFromStaging();
					}
				}
			}
		}
		if($flag1){
			throw new Exception(sprintf($errorMessage, sprintf('<a href="%s" class="wc-backward">Return to shop</a>', esc_url(wc_get_page_permalink('shop')))));
		}
	}
	public static function getUpfrontPaymentNotification($cartItem, $orderCreated = false){
		$upfrontPayment = (double)$cartItem['_upfrontPayment'];
		$fullAmountDiscount = (double)$cartItem['_calendarista_full_amount_discount'];
		$totalAmountBeforeDeposit = (double)$cartItem['_calendarista_amount_before_deposit'];
		$seats = (int)$cartItem['_calendarista_seats'];
		if($fullAmountDiscount && $seats > 1){
			$fullAmountDiscount = $fullAmountDiscount * $seats;
		}
		$label = $orderCreated ? $cartItem['_calendarista_full_amount_paid_label'] : $cartItem['_calendarista_full_amount_discount_label'];
		if($upfrontPayment && ($fullAmountDiscount > 0 && 
			$totalAmountBeforeDeposit > $fullAmountDiscount)){
			$discountedValue = $totalAmountBeforeDeposit - $fullAmountDiscount;
			return sprintf('<span class="calendarista-strikethrough">%s</span>&nbsp;&nbsp;<span class="calendarista-discounted-full-amount">%s</span>&nbsp;&nbsp;<span class="calendarista-discount-msg">%s</span>'
				, Calendarista_MoneyHelper::toShortCurrency($totalAmountBeforeDeposit)
				, Calendarista_MoneyHelper::toShortCurrency($discountedValue)
				, sprintf($label, Calendarista_MoneyHelper::toShortCurrency($fullAmountDiscount))
			);
		}
	}
	public static function cartItemName($productName, $cartItem, $cartItemKey){
		if($cartItem['data']->get_type() === 'calendarista'){
			$generalSetting = Calendarista_GeneralSettingHelper::get();
			$availabilityList = null;
			if(isset($cartItem['_calendarista_availability_list']) && $cartItem['_calendarista_availability_list']){
				$availabilityList = sprintf('<br><span class="calendarista-cart-availability-list">%s</span>', self::deserialize($cartItem['_calendarista_availability_list']));
			}
			$result = sprintf('<p class="calendarista-summary"><span class="calendarista-cart-item-heading"><strong>%s</strong></span><br><span class="calendarista-cart-summary">%s</span>%s</p>', 
					$cartItem['_calendarista_item_name'], self::deserialize($cartItem['_calendarista_summary']), $availabilityList);
			
			$result .= self::deserialize($cartItem['_calendarista_optionals']);
			if($generalSetting->includeCustomFieldsWooCommerce){
				$result .= sprintf('<p class="calendarista-form-fields">%s</p>', self::deserialize($cartItem['_calendarista_custom_form_elements']));
			}
			if($generalSetting->includeGuestsWooCommerce){
				$result .= sprintf('<p class="calendarista-guests">%s</p>', self::deserialize($cartItem['_calendarista_dynamic_fields']));
			}
			if(isset($cartItem['_upfrontPayment'])){
				$upfrontPayment = self::getUpfrontPaymentNotification($cartItem);
				if($upfrontPayment){
					$result .= sprintf('<p class="calendarista-upfront-payment">%s</p>', $upfrontPayment);
				}else if($cartItem['_calendarista_deposit']){
					$result .= sprintf('<p class="calendarista-deposit">%s</p>', self::deserialize($cartItem['_calendarista_deposit']));
				}
			}
			return $result;
		}
		return $productName;
	}
	public static function updateCustomPrice($cart_object){
		foreach ($cart_object->cart_contents as $cart_item_key=>$cart_item){
			if($cart_item['data']->get_type() === 'calendarista' && isset($cart_item['_upfrontPayment'])){
				$upfrontPayment = (int)$cart_item['_upfrontPayment'];
				$amount = $upfrontPayment ? $cart_item['_calendarista_upfront_amount'] : $cart_item['_calendarista_amount'];
				$cart_item['data']->set_price($amount);
			}
		}
	}
	protected static function getWooCalculatedTotals($orderId){
		$order = wc_get_order($orderId);
		$result = array('discountMode'=>null, 'discount'=>null, 'totalAmount'=>$order->get_total());
		$wc = WC();
		$appliedCoupons = $wc->cart->applied_coupons;
		// Coupons used in the order LOOP (as they can be multiple)
		foreach($appliedCoupons as $couponName){
			// Retrieving the coupon ID
			$couponPost = get_page_by_title($couponName, OBJECT, 'shop_coupon');
			$couponId = $couponPost->ID;

			// Get an instance of WC_Coupon object in an array(necesary to use WC_Coupon methods)
			$coupon = new WC_Coupon($couponId);
			$discountType = $coupon->get_discount_type();
			// Now you can get type in your condition
			if (strpos($discountType, 'percent') !== false || strpos($discountType, 'fixed') !== false){
				$result['discountMode'] = strpos($discountType, 'percent') !== false ? 0 : 1;
				$result['discount'] = $coupon->get_amount();
			}
			break;
		}
		return $result;
	}
	public static function paypalCompleted($posted_data){
		if(!empty($posted_data['custom'])){
			$status = strtolower($posted_data['payment_status']);
			// Sandbox fix.
			if((empty( $posted_data['pending_reason']) || 'authorization' !== $posted_data['pending_reason']) && 
				isset($posted_data['test_ipn']) && 1 == $posted_data['test_ipn'] && 'pending' == $posted_data['payment_status']){
				$status = 'completed';
			}
			$custom = json_decode($posted_data['custom']);
			if (($custom && is_object($custom) && $status == 'completed')){
				$orderId  = $custom->order_id;
				self::thankyou($orderId, Calendarista_PaymentStatus::PAID, false/*verifyStatus*/);
			}
		}
	}
	public static function bacsPaymentCompleted($status, $order){
		$orderId = $order->get_order_number();
		self::thankyou($orderId, Calendarista_PaymentStatus::UNPAID);
	}
	public static function paymentComplete($orderId){
		self::thankyou($orderId, Calendarista_PaymentStatus::PAID);
	}
	public static function orderStatusCompleted($orderId){
		self::thankyou($orderId, Calendarista_PaymentStatus::PAID);
	}
	public static function orderStatusProcessing($orderId){
		self::thankyou($orderId, Calendarista_PaymentStatus::PAID);
	}
	public static function thankyou($orderId, $paymentStatus = Calendarista_PaymentStatus::PAID, $verifyStatus = true){
		if (!$orderId){
			return;
		}
		$order = wc_get_order($orderId);
		$orderStatus  = $order->get_status();
		$generalSetting = Calendarista_GeneralSettingHelper::get();
		
		if($verifyStatus){
			if($generalSetting->wooCommerceProcessingStatusOnly && !in_array($orderStatus, array('processing'))){
				return;
			}
			if(in_array($orderStatus, array('failed', 'cancelled'))){
				return;
			}
		}
		// Allow code execution only once 
		if(!get_post_meta($orderId, '_thankyou_action_done', true )){
			self::orderReceived($orderId, $paymentStatus, $verifyStatus);
			$order->update_meta_data('_thankyou_action_done', true);
			$order->save();
		}
	}
	public static function newOrderItemCreated($orderItemId, $item, $orderId){
		$itemType = $item->get_type();
		$itemId = $item->get_id();
		if ($itemType == 'line_item'){
			$values = $item->legacy_values;
			$product = wc_get_product($item->get_product_id());
			if(!$product){
				return;
			}
			$productType = $product->get_type();
			if($productType != 'calendarista'){
				return;
			}
			if(isset($values['_calendarista_summary'])){
				$generalSetting = Calendarista_GeneralSettingHelper::get();
				$availabilityList = null;
				if($values['_calendarista_availability_list']){
					$availabilityList = sprintf('<br><span class="calendarista-cart-availability-list">%s</span>', self::deserialize($values['_calendarista_availability_list']));
				}
				$itemDetails = sprintf('<div style="clear:both"><span class="calendarista-cart-item-heading">%s</span><br><span class="calendarista-cart-summary">%s</span>%s</div>'
					, $values['_calendarista_item_name']
					, self::deserialize($values['_calendarista_summary'])
					, $availabilityList
				);
				$itemDetails .= self::deserialize($values['_calendarista_optionals']);
				if($generalSetting->includeCustomFieldsWooCommerce){
					$itemDetails .= sprintf('<p>%s</p>', self::deserialize($values['_calendarista_custom_form_elements']));
				}
				if(isset($values['_upfrontPayment'])){
					$upfrontPayment = self::getUpfrontPaymentNotification($values, true);
					if($upfrontPayment){
						$itemDetails .= sprintf('<p class="calendarista_upfront_payment">%s</p>', $upfrontPayment);
					}else if($values['_calendarista_deposit']){
						$itemDetails .= sprintf('<p class="calendarista_deposit">%s</p>', self::deserialize($values['_calendarista_deposit']));
					}
				}
				wc_add_order_item_meta($orderItemId, __('Booking Summary', 'calendarista'), $itemDetails);
			}
			if(isset($values['_calendarista_staging_id'])){
				wc_add_order_item_meta($itemId, '_calendarista_staging_id', $values['_calendarista_staging_id']);
			}
			if(isset($values['_upfrontPayment'])){
				wc_add_order_item_meta($itemId, '_upfrontPayment', $values['_upfrontPayment']);
			}
			if(isset($values['_calendarista_seats'])){
				$seats = $values['_calendarista_seats'];
				if($seats){
					$seats = (int)$seats;
					$item->set_quantity($seats);
					$item->save();
				}
				wc_add_order_item_meta($itemId, '_calendarista_seats', $values['_calendarista_seats']);
			}
		}
	}
	public static function orderReceived($orderId, $paymentStatus, $updateStatus = true){
		$wcOrder = wc_get_order($orderId);
		$transactionId = get_post_meta($orderId, '_transaction_id', true);
		$items = $wcOrder->get_items();
		$generalSetting = Calendarista_GeneralSettingHelper::get();
		$flag1 = false;
		foreach ($items as $item) {
			$itemId = $item->get_id();
			$productId = $item->get_product_id();
			$stagingId = wc_get_order_item_meta($itemId, '_calendarista_staging_id', true); 
			$seats = wc_get_order_item_meta($itemId, '_calendarista_seats', true); 
			$upfrontPayment = wc_get_order_item_meta($itemId, '_upfrontPayment', true); 
			if(!$stagingId){
				continue;
			}
			$product = wc_get_product($productId);
			if(!$product){
				continue;
			}
			$taxRates = WC_Tax::get_rates($product->get_tax_class());
			$taxRate = null;
			if (!empty($taxRates)){
				$tr = reset($taxRates);
				if($tr){
					$taxRate = $tr['rate'];
				}
			}
			$productType = $product->get_type();
			if($productType != 'calendarista'){
				continue;
			}
			$wooData = self::getWooCalculatedTotals($orderId);
			$paymentMethodTitle = get_post_meta($orderId, '_payment_method_title', true);
			if(!$paymentMethodTitle){
				$paymentMethodTitle = sprintf('WooCommerce %s', get_post_meta($orderId, '_payment_method', true));
			}
			$paymentDate = new Calendarista_DateTime();
			$checkoutHelper = new Calendarista_CheckoutHelper(array(
				'stagingId'=>$stagingId
				, 'paymentOperator'=>$paymentMethodTitle
				, 'paymentDate'=>$paymentDate
				, 'paymentStatus'=>$paymentStatus
				, 'wooCommerceOrderId'=>$orderId
				, 'transactionId'=>$transactionId
				, 'wooDiscountMode'=>$wooData['discountMode']
				, 'wooDiscount'=>$wooData['discount']
				, 'wooTotalAmount'=>$wooData['totalAmount']
				, 'wooTaxValue'=>$taxRate
				, 'upfrontPayment'=>$upfrontPayment
			));
			$order = $checkoutHelper->log();
			if(!$order){
				wc_delete_order_item_meta($itemId, '_calendarista_staging_id');
				wc_delete_order_item_meta($itemId, '_calendarista_seats');
				wc_delete_order_item_meta($itemId, '_upfrontPayment');
				continue;
			}
			wc_add_order_item_meta($itemId, 'ID', $order->invoiceId);
			Calendarista_CheckoutHelper::confirmAndNotify($order->id, false);
			wc_delete_order_item_meta($itemId, '_calendarista_staging_id');
			wc_delete_order_item_meta($itemId, '_calendarista_seats');
			wc_delete_order_item_meta($itemId, '_upfrontPayment');
			$flag1 = true;
		}
		if($flag1){
			do_action('calendarista_after_payment', $order->id, Calendarista_PaymentOperator::WOOCOMMERCE);
			if($generalSetting->autoCompleteWooCommerceOrder && $updateStatus){
				$wcOrder->update_status('completed', null, true/* true = manual update*/);
			}
		}
	}
	public static function cartItemThumbnail($result, $cart_item, $cart_item_key){
		if($cart_item['data']->get_type() === 'calendarista' && $cart_item['_calendarista_thumbnail']){
			return sprintf('<img src="%s" alt="Placeholder" width="250" class="wp-post-image" height="">', $cart_item['_calendarista_thumbnail']);
		}
		return $result;
	}
	public static function cartItemQuantityCheckout($result, $cartItem, $cart_item_key){
		if($cartItem['data']->get_type() === 'calendarista'){
			$quantity = isset($cartItem['_calendarista_seats']) && (int)$cartItem['_calendarista_seats'] > 0 ? $cartItem['_calendarista_seats'] : 1;
			return ' <strong class="product-quantity">' . sprintf( '&times; %s', $quantity) . '</strong>';
		}
		return $result;
	}
	public static function cartItemQuantity($result, $cart_item_key, $cartItem){
		if($cartItem['data']->get_type() === 'calendarista'){
			$quantity = isset($cartItem['_calendarista_seats']) && (int)$cartItem['_calendarista_seats'] > 0 ? $cartItem['_calendarista_seats'] : 1;
			return ' <strong class="product-quantity">' . sprintf( '&times; %s', $quantity) . '</strong>';
		}
		return $result;
	}
	public static function logUnregisterdOrders(){
		$args = array('type'=>'calendarista', 'return'=>'ids');
		$products = wc_get_products($args);
		$limibByDay = boolval(get_option('calendarista_woo_order_limit_by_day'));
		$args = array();
		//if this is the first time, we retrieve all orders
		if($limibByDay){
			$seconds = 259200;//last 3 days
			$args = array(
				'date_created' => '>' . (time() - $seconds)
			);
		}else{
			update_option('calendarista_woo_order_limit_by_day', true);
		}
		$generalSetting = Calendarista_GeneralSettingHelper::get();
		$orders = wc_get_orders($args);
		foreach($orders as $order){
			$orderStatus  = $order->get_status();
			if($generalSetting->wooCommerceProcessingStatusOnly && !in_array($orderStatus, array('processing'))){
				continue;
			}
			if(in_array($orderStatus, array('failed', 'cancelled'))){
				continue;
			}
			$flag1 = false;
			$items = $order->get_items();
			if (count($items) > 0) {
				foreach($items as $item){
					$productId = $item->get_product_id();
					if(in_array($productId, $products)){
						$flag1 = true;
						break;
					}
				}
				if($flag1){
					$paymentMethod = $order->get_payment_method();
					$paymentStatus = Calendarista_PaymentStatus::PAID;
					if(in_array($paymentMethod, array('bacs'))){
						$paymentStatus = Calendarista_PaymentStatus::UNPAID;
					}
					$orderId = $order->get_order_number();
					if(!get_post_meta($orderId, '_thankyou_action_done', true )){
						self::orderReceived($orderId, $paymentStatus);
						$order->update_meta_data('_thankyou_action_done', true);
						$order->save();
					}
				}
			}
		}
	}
	public static function registerCustomProductType(){
		include('WC_Product_Calendarista.php');
	}
	public static function wooProductDataPanels(){
		$url = admin_url() . 'admin.php?page=calendarista-index';
		$link = sprintf('<a href="%s" target="_blank">%s</a>', $url, __('Services', 'calendarista'));
		?>
		<div id="calendarista_product_data" class="panel woocommerce_options_panel calendarista_product_data">
			<div class="show_if_calendarista">
				<span class="description"><strong><?php echo __('Calendarista setup', 'calendarista')?></strong></span>
				<ol>
					<li><?php echo sprintf(__('After creating this product, click the %s tab in Calendarista.', 'calendarista'), $link) ?></li>
					<li><?php echo __('Look for the payment option on the selected service.', 'calendarista') ?></li>
					<li><?php echo __('Select, [Enable payments and cart system through WooCommerce].', 'calendarista') ?></li>
				</ol>
			</div>
		</div>
		<?php
	}
	public static function wooProductType( $types ){
		Calendarista_WooCommerceHelper::createProductType();
		$types[ 'calendarista' ] = __('Calendarista Product', 'calendarista');
		return $types;
	}
	public static function wooProductDataTabs($tabs){
		$tabs['calendarista'] = array(
			'label'    => __('Instructions', 'calendarista'),
			'target'   => 'calendarista_product_data',
			'class'    => array('hide_if_grouped', 'hide_if_external', 'hide_if_simple', 'hide_if_variable', 'show_if_calendarista'),
			'priority' => 1,
		);
		$tabs['general']['class'][] = 'show_if_simple show_if_variable show_if_external';
		return $tabs;
	}
	public static function createProductType(){
		if(!term_exists('calendarista')){
			wp_insert_term(
			  'calendarista',
			  'product_type',
			  array(
				'description'=> 'Calendarista product type',
				'slug' => 'calendarista'
			  )
			);
		}
	}
	public static function removePriceSingleProduct($price, $instance){
		global $post;
		if(!$post){
			return $price;
		}
        $postId = (int)$post->ID;
		if(!self::calendaristaProductType($postId)){
			return $price;
		}
		return '';
	}
	public static function getServiceByProduct($productId){
		$projectRepo = new Calendarista_ProjectRepository();
		return $projectRepo->getProjectByWoo($productId);
	}
	public static function addCalendaristaService(){
		global $post;
		if(!$post){
			return;
		}
		$generalSetting = Calendarista_GeneralSettingHelper::get();
		if(!$generalSetting->addBookingFormWooProduct){
			return;
		}
        $postId = $post->ID;
		$projects = self::getServiceByProduct($postId);
		if($projects){
			$render = new Calendarista_Render();
			// we support multi availability by default in this case.
			echo $render->booking($projects, false/*enableMultipleBooking*/, false, false);
		}
	}
	public static function calendaristaProductType($postId){
		$calendaristaTypeProducts = self::getProducts();
		if ($calendaristaTypeProducts->have_posts()){
			foreach ($calendaristaTypeProducts->posts as $post){
				if((int)$post->ID == $postId){
					return true;
				}
			}
		}
		return false;
	}
	public static function getProducts(){
		$queryArgs = array(
			'post_type'=>'product'
			, 'nopaging'=>true
			, 'suppress_filters'=>true
			, 'tax_query'=>array(
				array(
				'taxonomy'=>'product_type'
				, 'field'=>'slug'
				, 'terms'=>'calendarista'
			))
		);
		$result = new WP_Query($queryArgs);
		return $result;
	}
	public static function registerEnableProductVisibilityScript() {
		?>
		<script type='text/javascript'>
			jQuery(document).ready(function($){
				var $productType = $('select[name="product-type"]')
					, $priceField = $('#_regular_price')
					, $generalTab = $('.general_options.general_tab')
					, $generalProductData = $('.product_data_tabs .general_tab')
					, $optionsGroup = $('#general_product_data .options_group.show_if_simple.show_if_external.show_if_variable')
					, $inventoryTab = $('.inventory_options.inventory_tab')
					, $inventoryProductData = $('.product_data_tabs .inventory_tab');
				$generalTab.addClass('show_if_calendarista').show();
				$generalProductData.addClass('show_if_calendarista').show();
				$optionsGroup.addClass('show_if_calendarista').show();
				$inventoryTab.addClass('show_if_calendarista').show();
				$inventoryProductData.addClass('show_if_calendarista').show();
				onProductTypeChange($productType.val());
				$productType.on('change', function(){
					onProductTypeChange($(this).val());
				});
				function onProductTypeChange(val){
					if(val == 'calendarista'){
						$priceField.val(0);
					}
				}
			});
		</script>
	<?php 
	}
	public static function wooCommerceActive(){
		// Makes sure the plugin is defined before trying to use it
		include_once(ABSPATH . 'wp-admin/includes/plugin.php');
		if(is_plugin_active('woocommerce/woocommerce.php') || is_plugin_active_for_network('woocommerce/woocommerce.php')){
			return true;
		}
		return false;
	}
	public static function deserialize($value){
		if(!$value){
			return '';
		}
		return unserialize(stripslashes($value));
	}
	public static function setCheckoutUrl(){
		if(!Calendarista_AjaxHelper::doingAjax() && class_exists('WooCommerce')){
			//our ajax calls happen early to avoid getting taxed by fat plugins 
			//slowing us down, so saving the checkout url for use via ajax 
			$generalSetting = Calendarista_GeneralSettingHelper::get();
			$generalSetting->wooCommerceCheckoutUrl = wc_get_checkout_url();
			$generalSetting->wooCommerceCartUrl = wc_get_cart_url();
			$repo = new Calendarista_GeneralSettingsRepository();
			if($generalSetting->id === -1){
				$repo->insert($generalSetting);
				return;
			}
			$repo->update($generalSetting);
		}
	}
	public static function ensureWooCommerceInitiated(){
		if(!self::wooCommerceActive()){
			return false;
		}
		if (!function_exists('WC') || !class_exists('WooCommerce', false)){
			//our ajax calls are quite early and some setups may not have woocommerce initiated, so initialize manually
			//$woo = ABSPATH . 'wp-content/plugins/woocommerce/woocommerce.php';
			//include_once $woo;
			return false;
		}
		return true;
	}
	public static function wooCommerceInitiated(){
		return self::ensureWooCommerceInitiated();
	}
}
?>