<?php 
namespace WCQT\classes\com;

class Order
{
	var $countries;
	var $statuses = array('wc-new-quote', 'wc-on-hold-quote', 'wc-expired-quote', 'wc-accepted-quote', 'wc-rejected-quote', 'wc-rejected-quote-2'); 
	var $notification_statuses = array('wc-new-quote', 'wc-expired-quote', 'wc-accepted-quote', 'wc-rejected-quote', 'wc-rejected-quote-2', 'wc-expiring-quote'); 
	public function __construct()
	{
		//Custom status
		add_filter( 'woocommerce_register_shop_order_post_statuses', array( $this, 'get_quote_statuses' ) );
		add_filter( 'wc_order_statuses', array( $this, 'add_custom_order_status' ) );
		add_filter( 'wc_order_is_editable',  array( $this, 'order_is_editable' ), 10, 2 );
		add_filter(	'woocommerce_valid_order_statuses_for_payment',array(&$this, 'valid_order_statuses_for_payment') ,10,2);
		add_action( 'admin_head', array( $this, 'menu_new_quotes_count' ) );
	}
	function menu_new_quotes_count()
	{
		global $submenu, $menu;
		$count = $this->count_new_quotes();
		
		foreach($menu as $key => $menu_voice)
			if($menu[$key][2] == 'wcqt-woocommerce-quote')
			{
				$menu[$key][0] .= " <span class='update-plugins count-$count'><span class='plugin-count'>" . $count . "</span></span>";
				//return;
			}
			
		foreach($submenu as $key => $menu_voice)
			if($key == 'wcqt-woocommerce-quote')
				foreach($menu_voice as $menu_voice_key => $sub_menu)
				{
					if($menu_voice[$menu_voice_key][2] == 'woocommerce-quote-quotes-table-page')
						$submenu[$key][$menu_voice_key][0] .= " <span class='update-plugins count-$count'><span class='plugin-count'>" . $count . "</span></span>";
				//return;
				}		
	}
	public function count_new_quotes()
	{
		$args = array('post_status'   => 'wc-new-quote',
					  'post_type'     => 'shop_order',
					  'fields' => 'ids'
				);
				
			
		
		$result = get_posts( $args ); //num of post with new messages
		return count($result); 
	}
	public function get_lang($order)
	{
		global $wcqt_wpml_model;
		
		$wc_order = is_object($order) ? $order : wc_get_order($order);
		$default = $wcqt_wpml_model->get_default_language_code(); //exameple en;

		if(!isset($order) || $order == false)
			return $default;
		
		$result = $wc_order->get_meta('wpml_language');
		$result = !$result || !is_string($result) || $result == "" ? $default : $result;
		
		return strtolower($result);
	}
	function get_order_details_page_url($order)
	{
		global $wcqt_option_model;
		$options = $wcqt_option_model->get_options();
		
		$order_url = $order->get_customer_id() ? get_permalink( get_option('woocommerce_myaccount_page_id') ).wcqt_get_value_if_set($options, array('my_account', 'endpoint', 'quote_details'), "view-quote")."/".$order->get_id() : //$order->get_view_order_url()
												 $order->get_checkout_order_received_url( ); 
												 
		return $order_url;
	}
	public function notification_can_be_sent($order, $status_string = "")
	{
		if(!$order)
			return false;
		
		$status = $status_string == "" ? $order->get_status() : $status_string;
		if(!in_array("wc-".$status, $this->notification_statuses))
			return false;
		
		if(boolval($order->get_meta("wcqt_{$status}_notification")))
			return false;
		
		$order->add_meta_data("wcqt_{$status}_notification", true, true);
		$order->save();
		return true;
	}
	public function get_customer_quotes($customer_id = null, $paginate = false, $current_page = 1)
	{
		$customer_id = $customer_id ? $customer_id : get_current_user_id();
		if(!$customer_id)
			return array();
		
		$args = array(
			'status' => $this->get_statuses(),
			'page'     => $current_page,
			'paginate' => $paginate,
		);
		$orders = wc_get_orders( $args );
		return $orders;
	}
	public function get_order_fields_list($type = "all")
	{
		$this->countries = new \WC_Countries();
		$result = array();
		switch($type)
		{
			case "all": $billing = $this->countries->get_address_fields( $this->countries->get_base_country(),"billing_");
						foreach($billing as $key => $data)	
								$billing[$key]['type'] = esc_html__('Billing', 'woocommerce-quote');
						$shipping = $this->countries->get_address_fields( $this->countries->get_base_country(),"shipping_");
						foreach($shipping as $key => $data)	
								$shipping[$key]['type'] = esc_html__('Shipping', 'woocommerce-quote');
						$result = array_merge($billing, $shipping);
						$result['order_note'] = array('label' => "note", 'type' => esc_html__('Order', 'woocommerce-quote'));
			break;
			case "billing": $result = $this->countries->get_address_fields( $this->countries->get_base_country(),"billing_");
							$billing['type'] = esc_html__('Billing', 'woocommerce-quote');
			break;
			case "billing": $result = $this->countries->get_address_fields( $this->countries->get_base_country(),"shipping_");
							$billing['type'] = esc_html__('Shipping', 'woocommerce-quote');
			break;
		}
		
		return $result;
	}
	public function get_notification_statuses()
	{
		return array('accepted-quote', 'new-quote', 'rejected-quote', 'rejected-quote-2');
	}
	public function reject_quote($order, $send_notification = false)
	{
		global $wcqt_email_model;
		$order = is_int($order) ? wc_get_order($order) : $order;
		$order->update_status("wc-rejected-quote-2");
		
		
		if($send_notification)
			$wcqt_email_model->send($order, "rejected-quote-2");
	}
	public function is_quote($order)
	{
		$order = is_int($order) ? wc_get_order($order) : $order;
		return !$order || in_array("wc-".$order->get_status(), $this->statuses);
	}
	public function valid_order_statuses_for_payment($statuses, $order = null)
	{
		$statuses[] = 'accepted-quote';
		
		return $statuses;
	}
	function get_statuses()
	{
		return $this->statuses;
	}
	
	function get_quote_statuses( $order_statuses = array() )
	{
    
	    // Status must start with "wc-"
	   $order_statuses['wc-new-quote'] = array(                                 
	   'label'                     => esc_html__( 'New Quote Request', 'woocommerce-quote' ),
	   'public'                    => true,                                 
	   'exclude_from_search'       => false,                                 
	   'show_in_admin_all_list'    => true,                                 
	   'show_in_admin_status_list' => true,                                 
	   'label_count'               => _n_noop( 'New Quote Request <span class="count">(%s)</span>', 'New Quote Requests <span class="count">(%s)</span>', 'woocommerce-quote' ),                              
	   );    
		
		$order_statuses['wc-on-hold-quote'] = array(                                 
	   'label'                     => esc_html__( 'On Hold Quote', 'woocommerce-quote' ),
	   'public'                    => true,                                 
	   'exclude_from_search'       => false,                                 
	   'show_in_admin_all_list'    => true,                                 
	   'show_in_admin_status_list' => true,                                 
	   'label_count'               => _n_noop( 'On Hold Quote <span class="count">(%s)</span>', 'On Hold Quotes <span class="count">(%s)</span>', 'woocommerce-quote' ),                              
	   );	  
	   $order_statuses['wc-accepted-quote'] = array(                                 
	   'label'                     => esc_html__( 'Accepted quote', 'Order status', 'woocommerce' ),
	   'public'                    => true,                                 
	   'exclude_from_search'       => false,                                 
	   'show_in_admin_all_list'    => true,                                 
	   'show_in_admin_status_list' => true,                                 
	   'label_count'               => _n_noop( 'Accepted Quote <span class="count">(%s)</span>', 'Accepted Quotes <span class="count">(%s)</span>', 'woocommerce-quote' ),                              
	   ); 
	   
	   $order_statuses['wc-rejected-quote'] = array(                                 
	   'label'                     => esc_html__( 'Rejected Quote', 'Order status', 'woocommerce' ),
	   'public'                    => true,                                 
	   'exclude_from_search'       => false,                                 
	   'show_in_admin_all_list'    => true,                                 
	   'show_in_admin_status_list' => true,                                 
	   'label_count'               => _n_noop( 'Rejected Quote <span class="count">(%s)</span>', 'Rejected Quotes <span class="count">(%s)</span>', 'woocommerce-quote' ),                              
	   ); 
	   $order_statuses['wc-rejected-quote-2'] = array(                                 
	   'label'                     => esc_html__( 'Rejected Quote by the customer', 'Order status', 'woocommerce' ),
	   'public'                    => true,                                 
	   'exclude_from_search'       => false,                                 
	   'show_in_admin_all_list'    => true,                                 
	   'show_in_admin_status_list' => true,                                 
	   'label_count'               => _n_noop( 'Rejected Quote by the customer <span class="count">(%s)</span>', 'Rejected Quotes by the customer <span class="count">(%s)</span>', 'woocommerce-quote' ),                              
	   ); 
	   
	   $order_statuses['wc-expired-quote'] = array(                                 
	   'label'                     => esc_html__( 'Expired Quote', 'Order status', 'woocommerce' ),
	   'public'                    => true,                                 
	   'exclude_from_search'       => false,                                 
	   'show_in_admin_all_list'    => true,                                 
	   'show_in_admin_status_list' => true,                                 
	   'label_count'               => _n_noop( 'Expired Quote <span class="count">(%s)</span>', 'Expired Quotes <span class="count">(%s)</span>', 'woocommerce-quote' ),                              
	   ); 
		
	   return $order_statuses; 
	
	}
	function order_is_editable( $editable, $order ) 
	{
		$editable_statuses = array();
		foreach($this->get_statuses() as $status)
			if($status != 'wc-accepted-quote')
				$editable_statuses[] = str_replace("wc-", "", $status);
			
		if ( in_array($order->get_status(), $editable_statuses ) )
			$editable = true;
		
		return $editable;
	}
	function add_custom_order_status( $order_statuses ) 
	{      
	   $order_statuses['wc-new-quote'] = esc_html__( 'New Quote Request', 'woocommerce-order-approval' );       
	   $order_statuses['wc-on-hold-quote'] = esc_html__( 'On Hold Quote', 'woocommerce-order-approval' );       
	   $order_statuses['wc-expired-quote'] = esc_html__( 'Expired quote', 'woocommerce-order-approval' );       
	   $order_statuses['wc-rejected-quote'] = esc_html__( 'Rejected Quote', 'woocommerce-order-approval' );       
	   $order_statuses['wc-rejected-quote-2'] = esc_html__( 'Rejected Quote by the Customer', 'woocommerce-order-approval' );       
	   $order_statuses['wc-accepted-quote'] = esc_html__( 'Accepted Quote', 'woocommerce-order-approval' );       
	   return $order_statuses;
	}
	function perform_cron_jobs()
	{
		global $wpdb, $wcqt_time_model, $wcqt_option_model, $wcqt_email_model;
		$post_table = $wpdb->prefix . 'posts';
		$postmeta_table = $wpdb->prefix . 'postmeta';
		$options = $wcqt_option_model->get_options();
		
		//Automatic expire and approval management
		$approval_time_type = wcqt_get_value_if_set($options, array('expire_approval', 'approval', 'type'), "hours");
		$approval_time_value = wcqt_get_value_if_set($options, array('expire_approval',  'approval', 'value'), 0 );
		//Expiring quotes notification 
		$expiring_time_value = wcqt_get_value_if_set($options, array('expire_time_notification', 'approval', 'value'), 0 );
		$expiring_date_value = wcqt_get_value_if_set($options, array('expire_time_notification', 'approval', 'type'), "hours");
		$query = "SELECT orders.ID, orders.post_date as date, orders.post_status as status, meta_table.meta_value as expiring_date
				  FROM $post_table orders 
				  LEFT JOIN $postmeta_table AS meta_table ON orders.ID = meta_table.post_id AND meta_table.meta_key = 'wcqt_expire_datetime'
				  WHERE orders.post_type = 'shop_order'  
					    AND orders.post_status IN('wc-new-quote','wc-accepted-quote')";
		$results = $wpdb->get_results( $query, ARRAY_A  ); 
		
		
		foreach($results as $result)
		{
			if($result['status'] == 'wc-new-quote')
			{
				//1: mark quotes as expired if expiring date has passed
				if($result['expiring_date'] && strtotime($wcqt_time_model->now()) > strtotime($result['expiring_date']))
				{
					$post_data = array(
						'ID' => $result['ID'],
						'post_status' => "wc-expired-quote"
					);
					wp_update_post($post_data);
				}
				//2: automatically approve quotes (according to settings)
				elseif($approval_time_value > 0 && strtotime($wcqt_time_model->add_time_to_time($result['date'],$approval_time_value." ".$approval_time_type)) < strtotime($wcqt_time_model->now()))
				{
					$post_data = array(
						'ID' => $result['ID'],
						'post_status' => "wc-accepted-quote"
						);
					wp_update_post($post_data);				
				}
			}
			elseif($result['status'] == 'wc-accepted-quote')
			{
				//3: send notification for accepted quotes that are going to expire
				if($expiring_time_value > 0 && $result['expiring_date'] && (strtotime($wcqt_time_model->add_time_to_time($wcqt_time_model->now(),$expiring_time_value." ".$expiring_date_value)) >= strtotime($result['expiring_date'])) && 
																		   (strtotime($wcqt_time_model->now()) < strtotime($result['expiring_date'])))
					$wcqt_email_model->trigger_expiring_quote_notification($result['ID']);
			}
			
		}
		
		
		
		
	}
	public function get_input_fields_data($order)
	{
		return $order->get_meta('wcqt_input_fields_data');
	}
	public function get_form_data($order)
	{
		return $order->get_meta('wcqt_form_data');
	}
	public function update_message($order, $message)
	{
		$order = is_int($order) ? wc_get_order($order) : $order;
		$order->add_meta_data('wcqt_msg', $message, true);
		$order->save();
	}
	public function get_message($order)
	{
		$order = is_int($order) ? wc_get_order($order) : $order;
		return $order->get_meta('wcqt_msg');
	}
	public function update_expiring_date($order, $expire_datetime, $save = false)
	{
		$order = is_int($order) ? wc_get_order($order) : $order;
		$old_value = $order->get_meta('wcqt_expire_datetime');
		$order->add_meta_data('wcqt_expire_datetime', $expire_datetime, true);
		
		if($old_value !=  $expire_datetime)
			$order->add_meta_data("wcqt_expiring-quote_notification", false, true);
		
		if($save)
			$order->save();
	}
	public function get_expiring_date($order, $format_date = true)
	{
		global $wcqt_time_model;
		$datetime = $order->get_meta('wcqt_expire_datetime');
		if(!$datetime)
			return array('date' => "", 'time' => "", 'datetime' => "");
		
		$split = $datetime ? explode(" ",$datetime) : array(0 => "", 1 => "");
		$datetime =  $format_date ? $wcqt_time_model->get_date_time_according_wordpress_settings($datetime) : $format_date;
		
		return array('date'=> $split[0], 'time' => $split[1], 'datetime' => $datetime ? $datetime : "");
	}
	public function create_quote($form_data)
	{
		global $wcqt_session_model, $wcqt_option_model, $wcqt_wpml_model, $wcqt_session_model, $wcqt_input_field_model, $wcqt_time_model, $wcqt_email_model;
		
		$products_to_quote = $wcqt_session_model->get_quote_list(); 
		$options = $wcqt_option_model->get_options();
		$input_fields = $wcqt_option_model->get_form_options();
		$default_lang = $wcqt_wpml_model->get_default_language_code();
		$current_lang = $wcqt_wpml_model->get_current_language_code();
		
		$result = array("code" => 1, 'messages' => array());
		if(empty($products_to_quote))
		{
			$result['messages'][] = array('message' => wcqt_get_value_if_set($options, array('quote_page', 'texts', 'no_product_error', $current_lang), esc_html__("Please select at least one product to quote.", 'woocommerce-quote')), 'notice_type' => 'error');
			return $result;
		}
			
		//Validation
		$error = false;
		foreach($input_fields as $field_id => $field_data)
			if(isset($form_data[$field_id]))
			{
				switch($field_data['type'])
				{
					case 'email': $is_valid = \WC_Validation::is_email($form_data[$field_id]);
								 if(!$is_valid && $form_data[$field_id] != "") //if email is empty, it is ok (required check is performed via frontend)
								 {
									 $error = true;
									 $result['code'] = 3;
									 $result['messages'][] = array('message' => sprintf(esc_html__('Invalid email address for the %s field.', 'woocommerce-quote'), $field_data['label'][$current_lang]), 'notice_type' => 'error');
								 }
									
					break;
				}
			}
		if($error)
		{
			return $result;
		}
		
		//Quote creation
		$order = wc_create_order();
		$order->add_meta_data('wcqt_input_fields_data',$input_fields, true);
		$order->add_meta_data('wcqt_form_data', $form_data, true);
		
		foreach($input_fields as $field_id => $field_data)
			if(isset($form_data[$field_id]))
			{
				$value_raw = $form_data[$field_id];
				$value = $wcqt_input_field_model->get_value_by_type($value_raw, $field_data['type']);
				$connects_to = wcqt_get_value_if_set($field_data, 'connects_to', "none");
				
				if($connects_to != 'none')
				{	
					$method_name = "set_".$connects_to;
					if(is_callable( array( $order, $method_name ) ))
					{
						if($field_data['type'] == 'country-state')
						{
							switch ($connects_to):
								case "billing_country": $order->set_billing_country($value_raw['country']); if(isset($value_raw['state'])) $order->set_billing_state($value_raw['state']);
								break;
								case "shipping_country": $order->set_shipping_country($value_raw['country']); if(isset($value_raw['state'])) $order->set_shipping_state($value_raw['state']);
								break;
							endswitch;
						}							
						else
							$order->$method_name($value);
					}
						
				}
				
			}
		//products
		foreach($products_to_quote as $product)
		{
			$product_id = $product['variation_id'] ? $product['variation_id'] : $product['product_id'];
			$wc_product = wc_get_product($product_id);
			$quantity = $wc_product->get_sold_individually() ? 1 : $product['quantity'];
			$order->add_product( wc_get_product( $product_id),  $product['quantity']);
		}		
		$wcqt_session_model->delete_quote_list();
		$order->set_customer_id( get_current_user_id() );
		$order->set_status( 'wc-new-quote' );
		$order->calculate_totals();
		
		//Expire management 
		if( ($expire_value = wcqt_get_value_if_set($options, array('expire_approval',  'expire', 'value'), 0 )) != 0)
		{
			$expire_datetime = $wcqt_time_model->add_time_to_now($expire_value." ".wcqt_get_value_if_set($options, array('expire_approval', 'expire', 'type'), "hours"));
			$this->update_expiring_date($order, $expire_datetime);
		}
		else 
			$this->update_expiring_date($order, "");
		
		
		$order->save();
		
		//Quote submitted notification to the customer
		$wcqt_email_model->send($order, "new-quote", "customer");
		
		$result['messages'][] = array('message' => wcqt_get_value_if_set($options, array('quote_page', 'texts', 'successfully_submitted', $current_lang), esc_html__("Quote successfully submitted!", 'woocommerce-quote')), 'notice_type' => 'success');
		$result['code'] = 2;
		return $result;
	}
}
?>