<?php

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

/**
 * Implements DateBook_WC_Subscription_Order Class
 *
 * @class   DateBook_WC_Subscription_Order
 * @package DateBook WooCommerce Subscription
 * @since   3.0
 */
if ( ! class_exists( 'DateBook_WC_Subscription_Order' ) ) {

	/**
	 * Class DateBook_WC_Subscription_Order
	 */
	class DateBook_WC_Subscription_Order {

		/**
		 * Single instance of the class
		 *
		 */
		protected static $instance;

		public $post_type_name = 'datebook_subscribe';

		public $subscription_meta = array();

		/**
		 * Returns single instance of the class
		 *
		 */
		public static function get_instance() {
			if ( is_null( self::$instance ) ) {
				self::$instance = new self();
			}

			return self::$instance;
		}

		/**
		 * Constructor
		 *
		 */
		public function __construct() {

			// Disable all payment gateways on the checkout page and replace the "Pay" button by "Place order"
			add_action( 'woocommerce_init', array( $this, 'datebook_woocommerce_free_for_gender') );

			add_action( 'woocommerce_new_order_item', array( $this, 'add_subscription_order_item_meta' ), 20, 3 );
			add_action( 'woocommerce_checkout_order_processed', array( $this, 'get_extra_subscription_meta' ), 10, 2 );

			// Add subscriptions from orders
			add_action( 'woocommerce_checkout_order_processed', array( $this, 'check_order_for_subscription' ), 100, 2 );

			// Start subscription after payment received. Set the member and payment to active status
			add_action( 'woocommerce_payment_complete', array( $this, 'payment_complete' ) );
			add_action( 'woocommerce_order_status_completed', array( $this, 'payment_complete' ) );

			// Set the member and payment to pending status
			add_action( 'woocommerce_order_status_pending', array( $this, 'payment_pending') );
			add_action( 'woocommerce_order_status_failed', array( $this, 'payment_pending') );
			add_action( 'woocommerce_order_status_on-hold', array( $this, 'payment_pending') );
			
			// Note that it’s woocommerce_order_status_on-hold, not on_hold.
			add_action( 'woocommerce_order_status_processing', array( $this, 'payment_pending') );
			add_action( 'woocommerce_order_status_refunded', array( $this, 'payment_pending') );
			add_action( 'woocommerce_order_status_cancelled', array( $this, 'payment_pending') );

			// add_action( 'wp_loaded', array( $this, 'renew_order') , 30 );

		}



		/**
		 * Remove payment gateways on checkout page if subscription is free for gender
		 *
		 */
		public function datebook_woocommerce_free_for_gender() {

			//if(!is_super_admin()){

				WC()->session = new WC_Session_Handler();
				WC()->session->init();

				$cart_data = WC()->session->get('cart');

				if (isset($cart_data) && is_array($cart_data) && !empty($cart_data)) {

					global $current_user;
					wp_get_current_user();
					$current_user_id = DateBook_Utilities::datebook_replace_user_by_admin($current_user->ID, 1);
					
					$subscription_plan_id = 0;

					$member = datebook_get_member($current_user_id);

					$profile_id = get_user_meta($current_user_id, 'profile_postid', true );

					$gender = get_post_meta($profile_id, 'gender', true);

					$all_splans = get_option('datebook_subscription_plans');

					foreach($cart_data as $key => $value){

						if (isset($value['product_id'])) {

							foreach($all_splans as $plan_key => $plan_value){

								if (isset($plan_value['active']) && $plan_value['active'] == 1) {

									if (isset($plan_value['wc_subscription_product']) && $plan_value['wc_subscription_product'] == $value['product_id']) {

										$subscription_plan_id = $plan_key;

									}
								}
							}

							if(isset($all_splans[$subscription_plan_id]['free_for_gender'][$gender])){
								add_filter( 'woocommerce_cart_needs_payment', '__return_false' );
							}
						}
					}
				}
			//}
		}


		/**
		 * Save the options of subscription in an array with order item id
		 *
		 */
		public function add_subscription_order_item_meta( $item_id, $item, $order_id) {
			if( isset( $item->legacy_cart_item_key) ){
				$this->cart_item_order_item[ $item->legacy_cart_item_key ] = $item_id;
			}
		}


		/**
		 * Save some info if a subscription is in the cart
		 *
		 */
		public function get_extra_subscription_meta( $order_id, $posted ) {

			if ( ! DateBook_WC_Start()->cart_has_subscriptions() ) {
				return;
			}


			$this->actual_cart = WC()->session->get( 'cart' );

			add_filter('wcaddon_price_check', '__return_false' );

			foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {

				$product = $cart_item['data'];
				$id      = $product->get_id();

				if ( DateBook_WC_Start()->is_subscription( $product ) ) {


					$new_cart = new WC_Cart();

					$subscription_info = array(
						'shipping' => array(),
						'taxes' => array(),
					);

					if ( isset( $cart_item['variation'] ) ) {
						$subscription_info['variation'] = $cart_item['variation'];
					}

					$new_cart_item_key = $new_cart->add_to_cart(
						$cart_item['product_id'],
						$cart_item['quantity'],
						( isset( $cart_item['variation_id'] ) ? $cart_item['variation_id'] : '' ),
						( isset( $cart_item['variation'] ) ? $cart_item['variation'] : '' ),
						$cart_item
					);

					$new_cart = apply_filters( 'wcaddon_add_cart_item_data', $new_cart, $new_cart_item_key, $cart_item );

					$new_cart_item_keys = array_keys( $new_cart->cart_contents );

					$applied_coupons = WC()->cart->get_applied_coupons();

					foreach ( $new_cart_item_keys as $new_cart_item_key ) {
						//shipping
						if ( $new_cart->needs_shipping() && $product->needs_shipping() ) {
							if ( method_exists( WC()->shipping, 'get_packages' ) ) {
								$packages = WC()->shipping->get_packages();

								foreach ( $packages as $key => $package ) {
									if ( isset( $package['rates'][ $posted['shipping_method'][ $key ] ] ) ) {
										if ( isset( $package['contents'][ $cart_item_key ] ) || isset( $package['contents'][ $new_cart_item_key ] ) ) {
											// This shipping method has the current subscription
											$shipping['method']      = $posted['shipping_method'][ $key ];
											$shipping['destination'] = $package['destination'];

											break;
										}
									}
								}


								if (  isset( $shipping ) ) {
									// Get packages based on renewal order details
									$new_packages = apply_filters( 'woocommerce_cart_shipping_packages', array(
										0 => array(
											'contents'        => $new_cart->get_cart(),
											'contents_cost'   => isset( $new_cart->cart_contents[ $new_cart_item_key ]['line_total'] ) ? $new_cart->cart_contents[ $new_cart_item_key ]['line_total'] : 0,
											'applied_coupons' => $new_cart->applied_coupons,
											'destination'     => $shipping['destination'],
										),
									) );

									//subscription_shipping_method_temp
									$save_temp_session_values = array(
										'shipping_method_counts'  => WC()->session->get( 'shipping_method_counts' ),
										'chosen_shipping_methods' => WC()->session->get( 'chosen_shipping_methods' ),
									);

									WC()->session->set( 'shipping_method_counts', array( 1 ) );
									WC()->session->set( 'chosen_shipping_methods', array( $shipping['method'] ) );

									add_filter( 'woocommerce_shipping_chosen_method', array( $this, 'change_shipping_chosen_method_temp' ) );
									$this->subscription_shipping_method_temp = $shipping['method'];

									WC()->shipping->calculate_shipping( $new_packages );

									remove_filter( 'woocommerce_shipping_chosen_method', array( $this, 'change_shipping_chosen_method_temp' ) );

									unset( $this->subscription_shipping_method_temp );
								}
							}

						}

						foreach ( $applied_coupons as $coupon_code ) {
							$coupon        = new WC_Coupon( $coupon_code );
							$coupon_type   = $coupon->get_discount_type();
							$coupon_amount = $coupon->get_amount();
							$valid   = datebook_wc_coupon_is_valid( $coupon, WC()->cart );
							if ( $valid && in_array( $coupon_type, array( 'recurring_percent', 'recurring_fixed' ) ) ) {

								$price     = $new_cart->cart_contents[ $new_cart_item_key ]['line_subtotal'];
								$price_tax = $new_cart->cart_contents[ $new_cart_item_key ]['line_subtotal_tax'];

								switch ( $coupon_type ) {
									case 'recurring_percent':
										$discount_amount     = round( ( $price / 100 ) * $coupon_amount, WC()->cart->dp );
										$discount_amount_tax = round( ( $price_tax / 100 ) * $coupon_amount, WC()->cart->dp );
										break;
									case 'recurring_fixed':
										$discount_amount     = ( $price < $coupon_amount ) ? $price : $coupon_type;
										$discount_amount_tax = 0;
										break;
								}

								$subscription_info['coupons'][] = array(
									'coupon_code'         => $coupon_code,
									'discount_amount'     => $discount_amount * $cart_item['quantity'],
									'discount_amount_tax' => $discount_amount_tax * $cart_item['quantity']
								);

								$new_cart->applied_coupons[]    = $coupon_code;
								$new_cart->coupon_subscription  = true;

							}
						}

						if ( ! empty( $new_cart->applied_coupons ) ) {
							WC()->cart->discount_cart       = 0;
							WC()->cart->discount_cart_tax   = 0;
							WC()->cart->subscription_coupon = 1;
						}

						$new_cart->calculate_totals();

						// Recalculate totals
						//save some order settings
						$subscription_info['order_shipping']     = wc_format_decimal( $new_cart->shipping_total );
						$subscription_info['order_shipping_tax'] = wc_format_decimal( $new_cart->shipping_tax_total );
						$subscription_info['cart_discount']      = wc_format_decimal( $new_cart->get_cart_discount_total() );
						$subscription_info['cart_discount_tax']  = wc_format_decimal( $new_cart->get_cart_discount_tax_total() );
						$subscription_info['order_discount']     = $new_cart->get_total_discount();
						$subscription_info['order_tax']          = wc_format_decimal( $new_cart->tax_total );
						$subscription_info['order_subtotal']     = wc_format_decimal( $new_cart->subtotal, get_option( 'woocommerce_price_num_decimals' ) );
						$subscription_info['order_total']        = wc_format_decimal( $new_cart->total, get_option( 'woocommerce_price_num_decimals' ) );
						$subscription_info['line_subtotal']      = wc_format_decimal( $new_cart->cart_contents[$new_cart_item_key]['line_subtotal'] );
						$subscription_info['line_subtotal_tax']  = wc_format_decimal( $new_cart->cart_contents[$new_cart_item_key]['line_subtotal_tax'] );
						$subscription_info['line_total']         = wc_format_decimal( $new_cart->cart_contents[$new_cart_item_key]['line_total'] );
						$subscription_info['line_tax']           = wc_format_decimal( $new_cart->cart_contents[$new_cart_item_key]['line_tax'] );
						$subscription_info['line_tax_data']      = $new_cart->cart_contents[$new_cart_item_key]['line_tax_data'];

					}


					// Get shipping details
					if ( $product->needs_shipping() ) {

						if ( isset( $shipping['method'] ) && isset( WC()->shipping->packages[0]['rates'][ $shipping['method'] ] ) ) {

							$method = WC()->shipping->packages[0]['rates'][ $shipping['method'] ];
							$subscription_info['shipping'] = array(
								'name'      => $method->label,
								'method_id' => $method->id,
								'cost'      => wc_format_decimal( $method->cost ),
								'taxes'     => $method->taxes,
							);

							// Set session variables to original values and recalculate shipping for original order which is being processed now
							WC()->session->set( 'shipping_method_counts', $save_temp_session_values['shipping_method_counts'] );
							WC()->session->set( 'chosen_shipping_methods', $save_temp_session_values['chosen_shipping_methods'] );
							WC()->shipping->calculate_shipping( WC()->shipping->packages );
						}

					}

					//CALCULATE TAXES
					$taxes = $new_cart->get_cart_contents_taxes();
					$shipping_taxes = $new_cart->get_shipping_taxes();

					foreach ( $new_cart->get_tax_totals() as $rate_key => $rate ) {

						$rate_args = array(
							'name'                => $rate_key,
							'rate_id'             => $rate->tax_rate_id,
							'label'               => $rate->label,
							'compound'            => absint( $rate->is_compound ? 1 : 0 ),

						);

						$rate_args['tax_amount']          = wc_format_decimal( isset( $taxes[ $rate->tax_rate_id ] ) ? $taxes[ $rate->tax_rate_id ] : 0 );
						$rate_args['shipping_tax_amount'] = wc_format_decimal( isset( $shipping_taxes[ $rate->tax_rate_id ] ) ? $shipping_taxes[ $rate->tax_rate_id ] : 0 );

						$subscription_info['taxes'][] = $rate_args;
					}

					$subscription_info['payment_method'] = '';
					$subscription_info['payment_method_title'] = '';
					if ( isset( $posted['payment_method'] ) && $posted['payment_method'] ) {
						$enabled_gateways = WC()->payment_gateways->get_available_payment_gateways();

						if ( isset( $enabled_gateways[$posted['payment_method']] ) ) {
							$payment_method = $enabled_gateways[$posted['payment_method']];
							$payment_method->validate_fields();
							$subscription_info['payment_method']       = $payment_method->id;
							$subscription_info['payment_method_title'] = $payment_method->get_title();
						}
					}

					if ( isset( $this->cart_item_order_item[ $cart_item_key ] ) ) {
						$order_item_id =  $this->cart_item_order_item[ $cart_item_key ];
						$this->subscriptions_info['order'][$order_item_id] = $subscription_info;
						wc_add_order_item_meta( $order_item_id, '_subscription_info', $subscription_info, true );
					}

				}

			}

			WC()->session->set( 'cart', $this->actual_cart ) ;
		}


		/**
		 * Check in the order if there's a subscription and create it
		 *
		 */
		public function check_order_for_subscription( $order_id, $posted ) {

			global $current_user;
			wp_get_current_user();
			$current_user_id = DateBook_Utilities::datebook_replace_user_by_admin($current_user->ID, 1);

			$order          = wc_get_order( $order_id );
			$order_items    = $order->get_items();
			$order_args     = array();
			$user_id        = method_exists( $order, 'get_customer_id' ) ? $order->get_customer_id() : datebook_get_prop( $order, '_customer_user', true );
			$order_currency = method_exists( $order, 'get_currency' ) ? $order->get_currency() : datebook_get_prop( $order, '_order_currency' );
			//check id the the subscriptions are created
			$subscriptions = datebook_get_prop( $order, 'subscriptions', true );

			if ( empty( $order_items ) || ! empty( $subscriptions ) ) {
				return;
			}

			$subscriptions = datebook_get_prop( $order, 'subscriptions', true );
			$subscriptions = is_array( $subscriptions ) ? $subscriptions : array();

			foreach ( $order_items as $key => $order_item ) {

				$_product = $order_item->get_product();

				if ( $_product == false ) {
					continue;
				}

				$id = $_product->get_id();

				$args = array();

				if ( DateBook_WC_Start()->is_subscription( $id ) ) {

					if ( ! isset( $this->subscriptions_info['order'][ $key ] ) ) {
						continue;
					}

					$subscription_info = $this->subscriptions_info['order'][ $key ];

					$max_length        = datebook_get_prop( $_product, '_wcaddon_max_length' );
					$price_is_per      = datebook_get_prop( $_product, '_wcaddon_price_is_per' );
					$price_time_option = datebook_get_prop( $_product, '_wcaddon_price_time_option' );
					$fee               = datebook_get_prop( $_product, '_wcaddon_fee' );
					$duration          = ( empty( $max_length ) ) ? '' : datebook_wc_get_timestamp_from_option( 0, $max_length, $price_time_option );

					// DOWNGRADE PROCESS
					// Set a trial period for the new downgrade subscription so the next payment will be due at the expiration date of the previous subscription
					if ( get_user_meta( $current_user_id, 'wcaddon_trial_' . $id, true ) != '' ) {
						$trial_info        = get_user_meta( $current_user_id, 'wcaddon_trial_' . $id, true );
						$trial_period      = $trial_info['trial_days'];
						$trial_time_option = 'days';
					} else {
						$trial_period      = datebook_get_prop( $_product, '_wcaddon_trial_per' );
						$trial_time_option = datebook_get_prop( $_product, '_wcaddon_trial_time_option' );
					}

					//if this subscription is a downgrade the old subscription will be cancelled
					$subscription_to_update_id = get_user_meta( $current_user_id, 'wcaddon_downgrade_' . $id, true );
					if ( $subscription_to_update_id != '' ) {
						$args_cancel_subscription = array(
							'subscription_to_cancel' => $subscription_to_update_id,
							'process_type'           => 'downgrade',
							'product_id'             => $id,
							'user_id'                => $current_user_id
						);

						$order_args['_wcaddon_subscritpion_to_cancel'] = $args_cancel_subscription;
					}

					// UPGRADE PROCESS
					// if we are in the upgrade process and the prorate must be done
					$subscription_old_id       = $pay_gap = '';
					$prorate_length            = datebook_get_prop( $_product, '_wcaddon_prorate_length' );
					$gap_payment               = datebook_get_prop( $_product, '_wcaddon_gap_payment' );
					$subscription_upgrade_info = get_user_meta( $current_user_id, 'wcaddon_upgrade_' . $id, true );

					if ( ! empty( $subscription_upgrade_info ) ) {
						$subscription_old_id = $subscription_upgrade_info['subscription_id'];
						$pay_gap             = $subscription_upgrade_info['pay_gap'];
						$trial_period        = '';

						//if this subscription is an upgrade the old subscription will be cancelled
						if ( $subscription_old_id != '' ) {
							$args_cancel_subscription = array(
								'subscription_to_cancel' => $subscription_old_id,
								'process_type'           => 'upgrade',
								'product_id'             => $id,
								'user_id'                => $current_user_id
							);

							$order_args['_wcaddon_subscritpion_to_cancel'] = $args_cancel_subscription;
						}

					}

					if ( $prorate_length == 'yes' && ! empty( $max_length ) && $subscription_old_id != '' ) {

						$old_sub = datebook_wc_get_subscription( $subscription_old_id );
						$activity_period = $old_sub->get_activity_period();

						if ( $price_time_option == $old_sub->price_time_option ) {
							$new_max_length = $max_length - ceil( $activity_period / datebook_wc_get_timestamp_from_option( 0, 1, $old_sub->price_time_option ) );
						} else {
							$new_duration   = datebook_get_days( $duration - $activity_period );
							$new_max_length = $new_duration / datebook_wc_get_timestamp_from_option( 0, 1, $price_time_option );
						}

						$max_length = abs( $new_max_length );
					}

					if ( $gap_payment == 'yes' && $pay_gap > 0 ) {
						//change the fee of the subscription adding the total amount of the previous rates
						$fee = $pay_gap;
					}


					// fill the array for subscription creation
					$args = array(
						'product_id'              => $order_item['product_id'],
						'variation_id'            => $order_item['variation_id'],
						'variation'               => ( isset( $subscription_info['variation'] ) ? $subscription_info['variation'] : '' ),
						'product_name'            => $order_item['name'],

						//order details
						'order_id'                => $order_id,
						'order_item_id'           => $key,
						'order_ids'               => array( $order_id ),
						'line_subtotal'           => $subscription_info['line_subtotal'],
						'line_total'              => $subscription_info['line_total'],
						'line_subtotal_tax'       => $subscription_info['line_subtotal_tax'],
						'line_tax'                => $subscription_info['line_tax'],
						'line_tax_data'           => $subscription_info['line_tax_data'],
						'cart_discount'           => $subscription_info['cart_discount'],
						'cart_discount_tax'       => $subscription_info['cart_discount_tax'],
						'coupons'                 => ( isset( $subscription_info['coupons'] ) ) ? $subscription_info['coupons'] : '',
						'order_total'             => $subscription_info['order_total'],
						'subscription_total'      => $subscription_info['order_total'],
						'order_tax'               => $subscription_info['order_tax'],
						'order_subtotal'          => $subscription_info['order_subtotal'],
						'order_discount'          => $subscription_info['order_discount'],
						'order_shipping'          => $subscription_info['order_shipping'],
						'order_shipping_tax'      => $subscription_info['order_shipping_tax'],
						'subscriptions_shippings' => $subscription_info['shipping'],
						'payment_method'          => $subscription_info['payment_method'],
						'payment_method_title'    => $subscription_info['payment_method_title'],
						'order_currency'          => $order_currency,
						'prices_include_tax'      => datebook_get_prop( $order, '_prices_include_tax' ),
						//user details
						'quantity'                => $order_item['qty'],
						'user_id'                 => $user_id,
						'customer_ip_address'     => datebook_get_prop( $order, '_customer_ip_address' ),
						'customer_user_agent'     => datebook_get_prop( $order, '_customer_user_agent' ),
						//item subscription detail
						'price_is_per'            => $price_is_per,
						'price_time_option'       => $price_time_option,
						'max_length'              => $max_length,
						'trial_per'               => $trial_period,
						'trial_time_option'       => $trial_time_option,
						'fee'                     => $fee,
						'num_of_rates'            => ( $max_length && $price_is_per ) ? $max_length / $price_is_per : ''
					);

					$subscription = new DateBook_WC_Subscription( '', $args );

					if ( $subscription->id ) {
						$subscriptions[]             = $subscription->id;
						$order_args['subscriptions'] = $subscriptions;
						//$order->add_order_note( sprintf( esc_html__( 'A new subscription #%d has been created from this order', 'datebook' ), $subscription->id ) );

						$product_id = ( $subscription->variation_id ) ? $subscription->variation_id : $subscription->product_id;
						delete_user_meta( $subscription->user_id, 'wcaddon_trial_' . $product_id );
					}
				}
			}
			
			if ( $order_args ) {
				datebook_save_prop( $order, $order_args, false, true );
			}
		}


		/**
		 * Second step. Update subscription in database. Activate
		 * 
		 * @access public
		 * @param $args
		 */
		public function payment_complete( $order_id ) {

			$order = wc_get_order( $order_id );
			$subscriptions = datebook_get_prop( $order, 'subscriptions', true );

			if ( $subscriptions != '' ) {
				foreach ( $subscriptions as $subscription_id ) {

					// Get member data
					$current_user_id = get_post_meta($subscription_id, 'user_id', true);
					$member_subscriptions = datebook_get_member_subscriptions( array( 'user_id' => $current_user_id ) );
					$status = isset($member_subscriptions[0]->status) ? $member_subscriptions[0]->status : NULL;

					$profile_id = isset($member_subscriptions[0]->payment_profile_id) && $member_subscriptions[0]->payment_profile_id > 0 ? $member_subscriptions[0]->payment_profile_id : NULL;

					// Get payment id
					$get_payment_id = get_post_meta($profile_id, 'payment_id', true);

					$payment = datebook_get_payment($get_payment_id);

					$current_user_id = isset($payment->user_id) && $payment->user_id > 0 ? $payment->user_id : (isset($current_user_id) && $current_user_id > 0 ? $current_user_id : NULL);
					$profile_id = isset($payment->profile_id) && $payment->profile_id > 0 ? $payment->profile_id : (isset($member_subscriptions[0]->payment_profile_id) && $member_subscriptions[0]->payment_profile_id > 0 ? $member_subscriptions[0]->payment_profile_id : NULL);

					// Get temporary payment data from database
					$payment_data = array(
						'user_id' => $current_user_id, 
						'subscription_plan_id' => $payment->subscription_id, 
						'plan_price_period' => $payment->plan_price_period, 
						'price' => $payment->amount, 
						'starts' => $payment->start_date, 
						'ends' => $payment->expiration_date, 
						'start_date' => $payment->start_date, 
						'expiration_date' => $payment->expiration_date, 
						'status' => 'active', 
						'profile_id' => $profile_id, 
						'payment_gateway' => $payment->payment_gateway
					);

					if($status == 'active' || $status == 'completed'){

						// Update profile subscription data
						$add_subscription_to_profile = DateBook_Profile_Subscription::add_new_subscription_plan_to_profile($payment_data);

					}

					// Set the member to active
					foreach( $member_subscriptions as $member_subscription ) {
						// Update subscription
						$member_subscription->update($payment_data);
					}

					// Set the payment to active
					$payment->update( array( 'status' => 'completed' ) );

					// Let's activate profile after payment is made
					$activate_profile_after_payment = DateBook_Profile_Subscription::activate_profile_after_payment($payment_data);

					$subscription = new DateBook_WC_Subscription( $subscription_id );
					$renew_order  = $subscription->renew_order;

					if ( $renew_order != 0 && $renew_order == $order_id ) {
						$subscription->update_subscription( $order_id );
					} elseif ( $renew_order == 0 ) {
						$subscription->start_subscription( $order_id );
					}

				}
			}
		}


		public function payment_pending( $order_id ) {

			// Get an instance of the WC_Product object
			$order = wc_get_order( $order_id );
			
			$subscriptions = datebook_get_prop( $order, 'subscriptions', true );

			if ( $subscriptions != '' ) {

				/*global $current_user;
				wp_get_current_user();
				$current_user_id = DateBook_Utilities::datebook_replace_user_by_admin($current_user->ID, 1);

				$member = datebook_get_member($current_user_id);

				$profile_id = get_user_meta($current_user_id, 'profile_postid', true );

				$gender = get_post_meta($profile_id, 'gender', true);

				$all_splans = get_option('datebook_subscription_plans');*/

				foreach ( $subscriptions as $subscription_id ) {

					// Set the member to pending
					//$current_user_id = get_post_meta($subscription_id, "user_id", true);
					//$member_subscriptions = datebook_get_member_subscriptions( array( 'user_id' => $current_user_id ) );
					//foreach( $member_subscriptions as $member_subscription ) {
						// Update subscription
						//$member_subscription->update( array( 'status' => 'pending' ) );
					//}

					// Set the payment to active
					$get_payment_id = get_post_meta($subscription_id, 'payment_id', true);
					$payment = datebook_get_payment( $get_payment_id );
					$payment->update( array( 'status' => 'pending' ) );

					$subscription = new DateBook_WC_Subscription( $subscription_id );
					$renew_order  = $subscription->renew_order;
					
					if ( $renew_order != 0 && $renew_order == $order_id ) {
						$subscription->update_subscription( $order_id );
					} elseif ( $renew_order == 0 ) {
						$subscription->start_subscription( $order_id );
					}


					/*if(isset($member->subscriptions[0]['subscription_plan_id'])){
						if(isset($all_splans[$member->subscriptions[0]['subscription_plan_id']]['free_for_gender'][$gender])){
							$order->update_status( 'completed' );
						}
					}*/
				}
			}
		}


		public function renew_order( $subscription_id ) {

			$subscription   = new DateBook_WC_Subscription( $subscription_id );
			$status         = $this->get_renew_order_status( $subscription );
			$renew_order_id = $subscription->can_be_create_a_renew_order();

			if ( $renew_order_id && is_int( $renew_order_id ) ) {
				return $renew_order_id;
			}elseif( $renew_order_id === false ){
				return false;
			}

			if ( apply_filters( 'wcaddon_skip_create_renew_order', false, $subscription ) ) {
				return false;
			}

			$or_status = 'renew';

			$order = wc_create_order( $args = array(
				'status'      => $or_status,
				'customer_id' => $subscription->user_id
			) );

			$args = array(
				'subscriptions'  => array( $subscription_id ),
				'payment_method' => $subscription->payment_method,
				'order_currency' => $subscription->order_currency
			);

			if ( method_exists( $order, 'set_customer_note' ) ) {
				$parent_order  = wc_get_order( $subscription->order_id );
				$customer_note = datebook_get_prop( $parent_order, 'customer_note' );
				$args['customer_note'] = $customer_note;

			}

			// get billing
			$billing_fields = $subscription->get_address_fields( 'billing' );
			// get shipping
			$shipping_fields = $subscription->get_address_fields( 'shipping' );

			$args = array_merge( $args, $shipping_fields, $billing_fields );

			foreach ( $billing_fields as $key => $field ) {
				$set = 'set_' . $key;
				method_exists( $order, $set ) && $order->$set( $field );
			}

			foreach ( $shipping_fields as $key => $field ) {
				$set = 'set_' . $key;
				method_exists( $order, $set ) && $order->$set( $field );
			}

			datebook_set_prop( $order, $args );

			$order_id = datebook_get_order_id( $order );

			foreach ( $args as $key => $value  ) {
				if( $key == 'subscriptions'){
					add_post_meta( $order_id, $key, $value );
				}
				update_post_meta( $order_id, '_'.$key, $value );
			}

			$_product = wc_get_product( ( isset( $subscription->variation_id ) && !empty( $subscription->variation_id ) ) ? $subscription->variation_id : $subscription->product_id );

			$total = 0;
			$tax_total = 0;

			$variations = array();

			$item_id = $order->add_product(
				$_product,
				$subscription->quantity,
				array(
					'variation' => $variations,
					'totals'    => array(
						'subtotal'     => $subscription->line_subtotal,
						'subtotal_tax' => $subscription->line_subtotal_tax,
						'total'        => $subscription->line_total,
						'tax'          => $subscription->line_tax,
						'tax_data'     => maybe_unserialize($subscription->line_tax_data)
					)
				)
			);

			if ( !$item_id ) {
				throw new Exception( sprintf( esc_html__( 'Error %d: unable to create the order. Please try again.','datebook'), 402 ) );
			} else {
				$total     += floatval( $subscription->line_total );
				$tax_total += floatval( $subscription->line_tax );
				$metadata  = get_metadata( 'order_item', $subscription->order_item_id );

				if ( $metadata ) {
					foreach ( $metadata as $key => $value ) {
						if ( apply_filters( 'wcaddon_renew_order_item_meta_data', is_array( $value ) && count( $value ) == 1, $subscription->order_item_id, $key, $value ) ) {
							add_metadata( 'order_item', $item_id, $key, maybe_unserialize( $value[0] ), true );
						}
					}
				}
			}

			$shipping_cost = 0;

			//Shipping
			if ( ! empty( $subscription->subscriptions_shippings ) ) {

				$shipping_item_id = wc_add_order_item( $order_id, array(
					'order_item_name' => $subscription->subscriptions_shippings['name'],
					'order_item_type' => 'shipping',
				) );

				$shipping_cost     = $subscription->subscriptions_shippings['cost'];
				$shipping_cost_tax = 0;

				wc_add_order_item_meta( $shipping_item_id, 'method_id', $subscription->subscriptions_shippings['method_id'] );
				wc_add_order_item_meta( $shipping_item_id, 'cost', wc_format_decimal( $shipping_cost ) );
				wc_add_order_item_meta( $shipping_item_id, 'taxes', $subscription->subscriptions_shippings['taxes'] );

				if ( ! empty( $subscription->subscriptions_shippings['taxes'] ) ) {
					foreach ( $subscription->subscriptions_shippings['taxes'] as $tax_cost ) {
						$shipping_cost_tax += $tax_cost;
					}
				}

				if ( version_compare( WC()->version, '2.7.0', '>=' ) ) {
					$order->set_shipping_total( $shipping_cost );
					$order->set_shipping_tax( $subscription->subscriptions_shippings['taxes'] );
					$order->save();
				} else {
					$order->set_total( wc_format_decimal( $shipping_cost ), 'shipping' );
				}
			}else{
				do_action('wcaddon_add_custom_shipping_costs', $order, $subscription );
			}

			$cart_discount_total = 0;
			$cart_discount_total_tax = 0;

			//coupons
			if( !empty( $subscription->coupons) ){
				foreach( $subscription->coupons  as $coupon ){
					$order->add_coupon( $coupon['coupon_code'], $coupon['discount_amount'],  $coupon['discount_amount_tax']);
					$cart_discount_total += $coupon['discount_amount'];
					$cart_discount_total_tax += $coupon['discount_amount_tax'];
				}
			}
			
			$order->set_discount_total($cart_discount_total);

			if ( isset( $subscription->subscriptions_shippings['taxes'] ) && $subscription->subscriptions_shippings['taxes'] ) {
				/**
				 * this fixes the shipping taxes removed form WC settings
				 * if in a previous tax there was the taxes this will be forced
				 * even if they are disabled for the shipping
				 */
				add_action( 'woocommerce_find_rates', array( $this, 'add_shipping_tax'), 10 );
			}
			$order->update_taxes();
			$order->calculate_totals();

			$order_id = datebook_get_order_id( $order );
			//attach the new order to the subscription
			$subscription->order_ids[] = $order_id;

			update_post_meta( $subscription->id,'order_ids', $subscription->order_ids );

			//$order->add_order_note( sprintf( esc_html__( 'This order has been created to renew subscription #%s', 'datebook' ), admin_url( 'post.php?post=' . $subscription->id . '&action=edit' ), $subscription->id));

			$subscription->set( 'renew_order', $order_id );

			datebook_save_prop( $order, array( 'status' => $status, 'is_a_renew' => 'yes') );

			return $order_id;

		}


		public function get_renew_order_status( $subscription = null ){

			$new_status = 'on-hold';

			if ( ! is_null( $subscription ) && $subscription->payment_method == 'bacs' ) {
				$new_status = 'pending';
			}

			//the status must be register as wc status
			$status = apply_filters( 'wcaddon_renew_order_status', $new_status, $subscription );

			return $status;
		}
		
		

	}
}

/**
 * Unique access to instance of DateBook_WC_Subscription_Order class
 *
 */
function DateBook_WC_Subscription_Order() {
	return DateBook_WC_Subscription_Order::get_instance();
}