<?php
/**
* The Coupon class.
*
* Used to define functions related with coupon creation and management
*
*
* @since      9.4
* @package    CartBounty Pro - Save and recover abandoned carts for WooCommerce
* @subpackage CartBounty Pro - Save and recover abandoned carts for WooCommerce/includes
* @author     Streamline.lv
*/
class CartBounty_Pro_Coupons{

	/**
	 * The admin handler that manages the plugin's settings, options, and backend functionality.
	 *
	 * @since    10.9
	 * @access   protected
	 * @var      CartBounty_Pro_Admin    $admin    Provides methods to control and extend the plugin's admin area.
	 */
	protected $admin = null;

	/**
	 * The automation handler that manages the plugin's abandoned cart reminder automation functionality.
	 *
	 * @since    10.9
	 * @access   protected
	 * @var      CartBounty_Pro_Automation    $automation    Provides methods to control and extend the plugin's automations.
	 */
	protected $automation = null;

	/**
	 * Get the admin handler (lazy-loaded).
	 * Creates the connector on first use and then reuses the same instance.
	 *
	 * @since 10.9
	 * @access protected
	 * @return CartBounty_Pro_Admin
	 */
	protected function admin(){
		
		if( $this->admin === null ){
			$this->admin = new CartBounty_Pro_Admin( CARTBOUNTY_PRO_PLUGIN_NAME_SLUG, CARTBOUNTY_PRO_VERSION_NUMBER );
		}

		return $this->admin;
	}

	/**
	 * Get the automation handler (lazy-loaded).
	 * Creates the connector on first use and then reuses the same instance.
	 *
	 * @since 10.9
	 * @access protected
	 * @return CartBounty_Pro_Automation
	 */
	protected function automation(){
		
		if( $this->automation === null ){
			$this->automation = new CartBounty_Pro_Automation();
		}

		return $this->automation;
	}

	/**
	* Run the coupon functionality and returns array consisting of coupon code with coupon expiration time
	* Returns false in case the coupon could not be generated / used or a coupon code in case the coupon code is valid for the given cart and can be used
	*
	* @since    9.4
	* @return   boolean or array
	* @param    string     $recovery             Recovery type e.g. ActiveCampaign, WordPress, MailChimp
	* @param    string     $option               Option data field name for storing values
	* @param    integer    $step_nr              Automation step number
	* @param    object     $cart                 Cart data
	*/
	public function get_coupon( $recovery, $option, $step_nr, $cart ){
		$result = false;
		$generate = false;
		$coupon_enabled = $this->coupon_enabled( $recovery, $option, $step_nr );
		$admin = $this->admin();

		if( !$coupon_enabled ){ //If coupon disabled, exit
			$this->update_cart_coupon( $code = false, $recovery, $step_nr, $cart ); //Remove coupon code from the user in case coupons are disabled
			return $result;
		}

		if( $coupon_enabled == 'generate_new' ){ //Generate new coupon code
			$generate = true;
			$code = $this->create_coupon( $recovery, $option, $step_nr, $cart );

		}else{ //Use existing coupon code
			$code = $admin->get_item_name_by_id( $coupon_enabled, 'shop_coupon' );
		}

		if( empty( $code ) ){
			return $result;
		}

		$code = strtolower( $code ); //Making sure the coupon code is lowercase and consistent with how WooCommerce saves them
		$can_apply_coupon_code = $this->can_apply_coupon_code( $cart, $recovery, $option, $step_nr, $code );
		
		if( $can_apply_coupon_code['success'] ){ //If coupon code can be applied to given abandoned cart
			$this->update_cart_coupon( $code, $recovery, $step_nr, $cart ); //Save coupon code in the database accordingly to the recovery option that was used
			$generate_coupon = $this->get_coupon_settings( $recovery, $option, $step_nr, 'generate_coupon' );
			$result = array(
				'coupon_code'			=> $code,
				'generate'				=> $generate_coupon,
				'coupon_expiry'			=> $this->get_coupon_expiration_date( $code ),
				'coupon_description'	=> $this->get_coupon_settings( $recovery, $option, $step_nr, 'coupon_description' )
			);

		}else{ //If coupon code was not valid for the current abandoned cart
			$this->update_cart_coupon( false, $recovery, $step_nr, $cart ); //Remove coupon code from user in case coupon not applicable
			
			if( $generate ){ //If we previously generated coupon code - must delete it as the cart will not be able to apply it
				$coupon_id = $this->get_coupon_id( $code );
				wp_delete_post( $coupon_id, true );
			}

			if( isset( $can_apply_coupon_code['message'] ) ){
				$result = array(
					'error_message' => $can_apply_coupon_code['message']
				);
			}
		}

		return $result;
	}

	/**
	* Returning coupon generation defaults
	*
	* @since    9.3
	* @return   array or string
	* @param    string     $value                Value to return
	*/
	public function get_defaults( $value = false ){
		$defaults = array(
			'discount_type'				=> 'percent',
			'coupon_amount'				=> 0,
			'coupon_shipping'			=> false,
			'coupon_expiry'				=> 604800000, //One week
			'minimum_spend'				=> '',
			'minimum_spend_label'		=> esc_attr__('No minimum', 'woo-save-abandoned-carts'),
			'maximum_spend'				=> '',
			'maximum_spend_label'		=> esc_attr__('No maximum', 'woo-save-abandoned-carts'),
			'coupon_individual'			=> false,
			'coupon_sale'				=> false,
			'email_restriction'			=> 'any_email',
			'usage_limit_per_user'		=> apply_filters( 'cartbounty_pro_coupon_usage_limit_per_user', 0 ),
			'usage_limit'				=> apply_filters( 'cartbounty_pro_coupon_usage_limit', 1 ),
			'coupon_description'		=> esc_attr__( 'Please use the following coupon code to get a discount on your purchase.', 'woo-save-abandoned-carts' ),
			'prevent_repeats'			=> false,
			'excluded_emails_phones' 	=> ''
		);

		if($value){ //If a single value should be returned
			if(isset($defaults[$value])){ //Checking if value exists
				$defaults = $defaults[$value];
			}
		}

		return $defaults;
	}

	/**
	* Return coupon settings depending from the recovery type and step number
	*
	* @since    9.4
	* @return   array
	* @param    string     $recovery             Recovery type e.g. ActiveCampaign, WordPress etc.
	* @param    string     $option               Option data field name for storing values
	* @param    integer    $step_nr              Automation step number
	* @param    string     $value                Value to return
	*/
	public function get_coupon_settings( $recovery, $option, $step_nr, $value = false ){
		$settings = array();
		$automation = $this->automation();
		$saved_options = get_option($option);
		$coupon = (object)$saved_options;

		if( $automation->multi_step_automation( $recovery ) ){ //In case we are working with multi-step automations - must take into account that options are set in arrays
			$step_nr = str_replace(array( '[', ']' ), '', $step_nr); //Removing array brackets that have been added before
			$coupon = (object)$saved_options[$step_nr];
		}

		if( isset($coupon->generate_coupon) ){ //If coupon generation enabled
			$settings['generate_coupon'] = $coupon->generate_coupon;
		}else{
			$settings['generate_coupon'] = false;
		}

		if( !empty($coupon->existing_coupon) ){ //If existing coupon is set
			$settings['existing_coupon'] = $coupon->existing_coupon;
		}else{
			$settings['existing_coupon'] = '';
		}

		if( !empty($coupon->discount_type) ){ //If discount type is empty or is not set
			$settings['discount_type'] = $coupon->discount_type;
		}else{
			$settings['discount_type'] = $this->get_defaults( 'discount_type' );
		}

		if( !empty($coupon->coupon_amount) ){ //If custom amount is set
			$settings['coupon_amount'] = $coupon->coupon_amount;
		}else{
			$settings['coupon_amount'] = $this->get_defaults( 'coupon_amount' );
		}

		if( isset($coupon->coupon_shipping) ){ //If coupon free shiping enabled
			$settings['coupon_shipping'] = $coupon->coupon_shipping;
		}else{
			$settings['coupon_shipping'] = $this->get_defaults( 'coupon_shipping' );
		}

		$settings['coupon_expiry'] = $this->get_defaults( 'coupon_expiry' );
		if( !empty($coupon->coupon_expiry) ){ //If coupon expiry value is not empty
			$settings['coupon_expiry'] = $coupon->coupon_expiry;
		}elseif(isset($coupon->coupon_expiry) ){ //If the value is set
			if( $coupon->coupon_expiry == '0' ){
				$settings['coupon_expiry'] = $coupon->coupon_expiry;
			}
		}

		if( !empty($coupon->coupon_prefix) ){ //If custom prefix is set
			$settings['coupon_prefix'] = $coupon->coupon_prefix;
		}else{
			$settings['coupon_prefix'] = '';
		}

		if( !empty($coupon->minimum_spend) ){ //If minimum coupon spend is set
			$settings['minimum_spend'] = $coupon->minimum_spend;
		}else{
			$settings['minimum_spend'] = $this->get_defaults( 'minimum_spend' );
		}

		if( !empty($coupon->maximum_spend) ){ //If maximum coupon spend is set
			$settings['maximum_spend'] = $coupon->maximum_spend;
		}else{
			$settings['maximum_spend'] = $this->get_defaults( 'maximum_spend' );
		}

		if( isset($coupon->coupon_individual) ){ //If coupon free shiping enabled
			$settings['coupon_individual'] = $coupon->coupon_individual;
		}else{
			$settings['coupon_individual'] = $this->get_defaults( 'coupon_individual' );
		}

		if( isset($coupon->coupon_sale) ){ //If coupon free shiping enabled
			$settings['coupon_sale'] = $coupon->coupon_sale;
		}else{
			$settings['coupon_sale'] = $this->get_defaults( 'coupon_sale' );
		}

		if( !empty($coupon->coupon_include_products) ){ //If the selected products array is not empty
			$settings['coupon_include_products'] = $coupon->coupon_include_products;
		}else{
			$settings['coupon_include_products'] = array();
		}

		if( !empty($coupon->coupon_exclude_products) ){ //If the selected products array is not empty
			$settings['coupon_exclude_products'] = $coupon->coupon_exclude_products;
		}else{
			$settings['coupon_exclude_products'] = array();
		}

		if( !empty($coupon->coupon_include_categories) ){ //If the selected categories array is not empty
			$settings['coupon_include_categories'] = $coupon->coupon_include_categories;
		}else{
			$settings['coupon_include_categories'] = array();
		}

		if( !empty($coupon->coupon_exclude_categories) ){ //If the selected categories array is not empty
			$settings['coupon_exclude_categories'] = $coupon->coupon_exclude_categories;
		}else{
			$settings['coupon_exclude_categories'] = array();
		}

		if( !empty($coupon->email_restriction) ){ //If email_restrictions are not empty
			$settings['email_restriction'] = $coupon->email_restriction;
		}else{
			$settings['email_restriction'] = $this->get_defaults( 'email_restriction' );
		}

		if( !empty($coupon->coupon_description) ){ //If custom prefix is set
			$settings['coupon_description'] = $coupon->coupon_description;
		}else{
			$settings['coupon_description'] = '';
		}

		if( !empty($coupon->excluded_emails_phones) ){ //If excluded emails are set
			$settings['excluded_emails_phones'] = $coupon->excluded_emails_phones;
		}else{
			$settings['excluded_emails_phones'] = $this->get_defaults( 'excluded_emails_phones' );
		}

		if( isset($coupon->prevent_repeats) ){ //If repeat coupons enabled
			$settings['prevent_repeats'] = $coupon->prevent_repeats;
		}else{
			$settings['prevent_repeats'] = $this->get_defaults( 'prevent_repeats' );
		}

		if($value){ //If a single value should be returned
			if(isset($settings[$value])){ //Checking if value exists
				$settings = $settings[$value];
			}
		}

		return $settings;
	}

	/**
	* Check if coupon enabled for the given recovery automation and step.
	* Returns dalse or a string "generate_new" or existing coupon code
	*
	* @since    9.4
	* @return   boolean or string
	* @param    string     $recovery             Recovery type e.g. ActiveCampaign, WordPress, MailChimp
	* @param    string     $option               Option data field name for storing values
	* @param    integer    $step_nr              Automation step number
	*/
	function coupon_enabled( $recovery, $option, $step_nr ){
		$enabled = false;
		$settings = (object)$this->get_coupon_settings( $recovery, $option, $step_nr );

		if( $settings->generate_coupon ){ //If coupon generation enabled
			$enabled = 'generate_new';

		}elseif( !empty($settings->existing_coupon) ){ //If existing coupon added, return existing coupon code
			$enabled = $settings->existing_coupon;
		}

		return $enabled;
	}

	/**
	* Create a new coupon. Returns coupon code value
	*
	* @since    9.4
	* @return   string
	* @param    string     $recovery             Recovery type e.g. ActiveCampaign, WordPress, MailChimp
	* @param    string     $option               Option data field name for storing values
	* @param    integer    $step_nr              Automation step number
	* @param    object     $cart                 Cart data
	*/
	private function create_coupon( $recovery, $option, $step_nr, $cart ){
		
		if( !$cart ) return; //If cart does not exist - exit and do not update as this is request is coming from email Preview

		$admin = $this->admin();
		$coupon_code = $this->generate_coupon_code( $recovery, $option, $step_nr ); //Generate new coupon code

		$coupon = array(
			'post_title'	=> $coupon_code,
			'post_content'	=> '',
			'post_status'	=> 'publish',
			'post_author'	=> apply_filters( 'cartbounty_pro_coupon_author_id', 1 ),
			'post_type'		=> 'shop_coupon',
		);

		$coupon_id = wp_insert_post( $coupon, $wp_error = true );

		if( is_wp_error( $coupon_id ) ){
			$admin->log( 'notice', sprintf( 'Coupons: Error creating coupon for cart ID = %d. Reason - %s', esc_html( $cart->id ), wp_strip_all_tags( $coupon_id->get_error_message() ) ) );
			return;
		}

		$coupon_settings = $this->get_coupon_settings( $recovery, $option, $step_nr );
		$coupon_expiry = $coupon_settings['coupon_expiry'];
		$coupon_expiry = $admin->convert_milliseconds_to_minutes( $coupon_expiry );
		$email_restriction = $coupon_settings['email_restriction'];

		if( $coupon_expiry ){ //If expiration date is set
			$coupon_expiry = date( 'Y-m-d', strtotime( '+'. $coupon_expiry .' minutes + 1 day' ) ); //Converting selected time interval to a date. Adding + 1 day so the coupon would expire on the end of the date that is displayed instead of the beginning
		}

		$coupon_meta = array(
			'discount_type'             => $coupon_settings['discount_type'],
			'coupon_amount'             => $coupon_settings['coupon_amount'],
			'individual_use'            => $coupon_settings['coupon_individual'] ? 'yes' : 'no',
			'usage_limit'               => $this->get_defaults('usage_limit'),
			'usage_limit_per_user'      => $this->get_defaults('usage_limit_per_user'),
			'expiry_date'               => $coupon_expiry,
			'free_shipping'             => $coupon_settings['coupon_shipping'] ? 'yes' : 'no',
			'minimum_amount'            => $coupon_settings['minimum_spend'],
			'maximum_amount'            => $coupon_settings['maximum_spend'],
			'exclude_sale_items'        => $coupon_settings['coupon_sale'] ? 'yes' : 'no',
			'cartbounty_pro_coupon'     => 1
		);

		if( $email_restriction != 'any_email' && !empty( $cart->email ) ){
			$coupon_meta['customer_email'] = $cart->email;
		}

		if( !empty( $coupon_settings['coupon_exclude_products'] ) ){
			$coupon_meta['exclude_product_ids'] = $coupon_settings['coupon_exclude_products'];
		}

		if( !empty( $coupon_settings['coupon_exclude_categories'] ) ){
			$coupon_meta['exclude_product_categories'] = $coupon_settings['coupon_exclude_categories'];
		}

		if( !empty( $coupon_settings['coupon_include_products'] ) ){
			$coupon_meta['product_ids'] = $coupon_settings['coupon_include_products'];
		}

		if( !empty( $coupon_settings['coupon_include_categories'] ) ){
			$coupon_meta['product_categories'] = $coupon_settings['coupon_include_categories'];
		}

		foreach( $coupon_meta as $key => $value ){
			update_post_meta( $coupon_id, $key, $value );
		}

		return $coupon_code;
	}

	/**
	* Generating unique coupon code
	*
	* @since    9.4
	* @return   string
	* @param    string     $recovery             Recovery type e.g. ActiveCampaign, WordPress, MailChimp
	* @param    string     $option               Option data field name for storing values
	* @param    integer    $step_nr              Automation step number
	* @param    string     $prefix               Use the prefix in case it is provided. Necessary in case of Email preview
	*/
	public function generate_coupon_code( $recovery, $option, $step_nr, $prefix = false ){
		$code = '';
		$coupon_prefix = $this->get_coupon_settings( $recovery, $option, $step_nr, 'coupon_prefix' );
		if($prefix || $prefix === ''){ //If prefix is set or it is empty
			$coupon_prefix = $prefix;
		}
		$length = apply_filters( 'cartbounty_pro_coupon_length', 12 );
		$allowed_characters = apply_filters( 'cartbounty_pro_coupon_characters', '23456789ABCEFGHJKLMNPRSTUVWXYZabcefghjkmnprstuvwxyz' );

		while ($length){ //Generate random coupon code
			$length = $length - 1;
			$code .= substr(str_shuffle($allowed_characters), 0, 1);
		}

		$code = implode( apply_filters( 'cartbounty_pro_coupon_separator', '_' ), str_split( $code, 5 ) ); //transform the code into a more readable and user friendly format
		return $coupon_prefix . $code;
	}

	/**
	* Get coupon ID from coupon code
	*
	* @since    9.4
	* @return   integer
	* @param    string     $coupon_code             Coupon code
	*/
	public function get_coupon_id( $coupon_code ){
		global $wpdb;
		$table = $wpdb->prefix . 'posts';
		$coupon_id = false;

		$coupon = $wpdb->get_row(
			$wpdb->prepare(
				"SELECT id FROM {$table}
				WHERE post_title = %s AND
				post_type = %s",
				$coupon_code,
				'shop_coupon'
			)
		);

		if(isset($coupon->id)){
			$coupon_id = $coupon->id;
		}

		return $coupon_id;
	}

	/**
	* Get coupon code expiration date
	*
	* @since    9.4
	* @return   string
	* @param    string     $coupon_code             Coupon code
	*/
	public function get_coupon_expiration_date( $coupon_code ){
		
		if( !$coupon_code ) return;

		$date = '';
		$coupon = new WC_Coupon( $coupon_code );
		$date_expires = $coupon->get_date_expires();

		if( $date_expires ){ //If expiration date is set
			$date_expires->modify( '-1 day' ); //Subtract 1 day so that the expiration day ends on the end of the date that is displayed
			$date = $date_expires->date( apply_filters( 'cartbounty_pro_coupon_expiry_date_format', 'Y-m-d' ) );
		}
		
		return $date;
	}

	/**
	* Get coupon expiration time from milliseconds
	* This is ued to create expiration date in Preview
	*
	* @since    9.4
	* @return   string
	* @param    integer    $milliseconds             milliseconds
	*/
	public function get_preview_coupon_expiration_date( $milliseconds ){
		
		if( !$milliseconds ) return;

		$admin = $this->admin();
		$minutes = $admin->convert_milliseconds_to_minutes( $milliseconds );
		$coupon_expiry = date( apply_filters( 'cartbounty_pro_coupon_expiry_date_format', 'Y-m-d' ), strtotime( '+'. $minutes .' minutes' ) ); //Converting selected time interval to a date
		return $coupon_expiry;
	}

	/**
	* Check whether coupon code exists
	*
	* @since    9.4
	* @return   boolean
	* @param    string    $coupon_code       Coupon code that should be validated
	*/
	private function coupon_code_exists( $coupon_code = '' ){
		$exists = false;
		$coupon = new WC_Coupon( $coupon_code );
		if($coupon->is_valid()){
			$exists = true;
		}
		return $exists;
	}

	/**
	* Check if the cart is eligible for the coupon code and it can be applied
	*
	* @since    9.4
	* @return   boolean | array
	* @param    object    $cart              Cart data
	* @param    string    $recovery          Recovery type e.g. ActiveCampaign, WordPress, MailChimp
	* @param    string    $option            Option data field name for storing values
	* @param    integer   $step_nr           Automation step number
	* @param    string    $coupon_code       Coupon code that should be validated
	*/
	private function can_apply_coupon_code( $cart, $recovery, $option, $step_nr, $coupon_code = '' ){
		$result = array(
			'success' 	=> false,
			'message' 	=> ''
		);

		if( !$cart ){ //If cart does not exist - return true as this is request is coming from a preview or a test
			$result['success'] = true;
			return $result;
		}

		global $wpdb;
		$admin = $this->admin();
		$coupon = new WC_Coupon( $coupon_code );

		$cart_table = $wpdb->prefix . CARTBOUNTY_PRO_TABLE_NAME;
		$row = $wpdb->get_row( //Retrieve abandoned cart contents 
			$wpdb->prepare(
				"SELECT cart_contents
				FROM $cart_table
				WHERE id = %d AND
				(type = %d OR type = %d)",
				$cart->id,
				$admin->get_cart_type('abandoned'),
				$admin->get_cart_type('recovered_pending')
			)
		);

		wc_load_cart(); //Loading WooCommerce Cart object
		$admin->build_cart( $row, $ignore = true );
		$discounts = new WC_Discounts( WC()->cart );
		$response = $discounts->is_coupon_valid( $coupon );

		//Check if coupon is valid or not
		if ( !is_wp_error( $response ) ) { //If the coupon is valid
			$result['success'] = true;

		}else{

			//Check if the issue is with requirement to enter valid email address at checkout - considering coupon to be valid in this case
			if( isset( $response->errors['invalid_coupon'] ) 
			&& count( $response->errors['invalid_coupon'] ) === 1 
			&& strpos( $response->errors['invalid_coupon'][0], 'Please enter a valid email at checkout' ) === 0 ) {
				$result['success'] = true;
			
			}else{ //If other reason for invalid coupon
				if( !isset( $response->errors['invalid_coupon'] ) ){
					return $result;
				}
				$reason = implode( '', $response->errors['invalid_coupon'] );
				$result['message'] = $reason;
				$admin->log( 'notice', sprintf( 'Coupons: The cart ID = %d was not eligible for the coupon. Reason - %s', esc_html( $cart->id ), wp_strip_all_tags( $reason ) ) );
			}
		}

		//Check if repeat coupon usage passed
		if( $this->check_repeat_coupon( $cart, $recovery, $option, $step_nr ) ){
			$result['success'] = false;
			$result['message'] = esc_html__( 'You have already previously received a coupon.', 'woo-save-abandoned-carts' );
			$admin->log( 'notice', sprintf( 'Coupons: The cart ID = %d was not eligible for the coupon. Reason - user has already previously received a coupon.', esc_html( $cart->id ) ) );
		}

		//Check if email or phone is not in the exclusions list
		if( $admin->email_phone_excluded( $cart, $recovery, $option, $step_nr, $coupon = true ) ){
			$result['success'] = false;
			$result['message'] = esc_html__( 'Unfortunately, the coupon code cannot be applied to your current cart.', 'woo-save-abandoned-carts' );
			$admin->log( 'notice', sprintf( 'Coupons: The cart ID = %d was not eligible for the coupon. Reason - user email or phone number excluded from receiving coupons.', esc_html( $cart->id ) ) );
		}

		WC()->session->__unset('cartbounty_pro_ignore_cart'); //Unsetting cart ignore cookie. If this is not done registered users or administrators may be unable to save carts after a coupon creation function is run
		
		return $result;
	}

	/**
	* Update coupon code of the abandoned cart
	*
	* @since    9.4
	* @param    string     $coupon_code       	 Coupon code that should be validated
	* @param    string     $recovery             Recovery type e.g. ActiveCampaign, WordPress, MailChimp
	* @param    integer    $step_nr              Automation step number
	* @param    object / string     $id          Cart data or Session ID
	*/
	public function update_cart_coupon( $coupon_code, $recovery, $step_nr, $id ){
		if( !$id ) return; //If cart does not exist - exit and do not update as this is request is coming from email Preview

		global $wpdb;
		$admin = $this->admin();
		$automation = $this->automation();
		$cart_table = $wpdb->prefix . CARTBOUNTY_PRO_TABLE_NAME;
		$identifier_name = 'session_id';
		$identifier_value = $id;
		$identifier_type = '%s';

		if( is_object( $id ) ){ //If identifier is Object - coupon update request is coming from CartBounty coupon generation
			$identifier_name = 'id';
			$identifier_value = $id->id;
			$identifier_type = '%d';
		}

		$row = $wpdb->get_row(
			$wpdb->prepare(
				"SELECT coupons
				FROM $cart_table
				WHERE $identifier_name = $identifier_type",
				$identifier_value
			), ARRAY_A
		);

		$coupons = $row['coupons'];

		if( !empty( $coupons ) ){ //If the field already has data - unserialize it so we can use it as an array
			$coupons = maybe_unserialize( $coupons );
		
		}else{
			$coupons = array();
		}

		if( $automation->multi_step_automation( $recovery ) ){ //In the case of we have multiple step automation - we have additional key for the step
			
			if( !$coupon_code ){//If empty coupon code - remove element from array
				unset( $coupons[$recovery][$step_nr] );

			}else{
				$coupons[$recovery][$step_nr] = $coupon_code;
			}
			
		}else{

			if( !$coupon_code ){//If empty coupon code - remove element from array
				unset( $coupons[$recovery] );

			}else{
				$coupons[$recovery] = $coupon_code;
			}
		}

		$wpdb->query(
			$wpdb->prepare( "UPDATE $cart_table
				SET coupons = %s
				WHERE $identifier_name = $identifier_type AND
				(type = %d OR type = %d)",
				sanitize_text_field( maybe_serialize( $coupons ) ),
				$identifier_value,
				$admin->get_cart_type('abandoned'),
				$admin->get_cart_type('recovered_pending')
			)
		);
	}

	/**
	* Method displays available coupon discount types
	*
	* @since    9.4
	* @return   HTML
	* @param    string     $recovery             Recovery type e.g. ActiveCampaign, WordPress, MailChimp
	* @param    string     $option               Option data field name for storing values
	* @param    string     $step_nr              Automation step number
	* @param    string     $automation           Name for labeling
	* @param    string     $field_id             Field ID for distinguishing input fields
	*/
	public function display_coupon_types( $recovery, $option, $step_nr, $automation, $field_id ){
		$admin = $this->admin();
		$selected_discount = $this->get_coupon_settings( $recovery, $option, $step_nr, 'discount_type' );

		$discount_types = array( //Defining array of discount types
			'percent'		=> esc_html__('Percentage discount', 'woo-save-abandoned-carts'),
			'fixed_cart'	=> esc_html__('Fixed cart discount', 'woo-save-abandoned-carts'),
			'fixed_product'	=> esc_html__('Fixed product discount', 'woo-save-abandoned-carts')
		);

		echo '<select id="cartbounty-pro-'. esc_attr( $automation ) .'-coupon-type'. esc_attr( $field_id ) .'" class="cartbounty-pro-select" name="'. esc_attr( $option ) . esc_attr( $step_nr ) .'[discount_type]" autocomplete="off" '. $admin->disable_field() .'>';
		foreach( $discount_types as $key => $discount ){
			echo "<option value='". esc_attr( $key ) ."' ". selected( $selected_discount, $key, false ) .">". esc_html( $discount ) ."</option>";
		}
		echo '</select>';
	}

	/**
	* Method displays available coupon email restriction options
	*
	* @since    10.4
	* @return   HTML
	* @param    string     $recovery             Recovery type e.g. ActiveCampaign, WordPress, MailChimp
	* @param    string     $option               Option data field name for storing values
	* @param    string     $step_nr              Automation step number
	* @param    string     $automation           Name for labeling
	* @param    string     $field_id             Field ID for distinguishing input fields
	*/
	public function display_coupon_email_restrictions( $recovery, $option, $step_nr, $automation, $field_id ){
		$admin = $this->admin();
		$selected_restriction = $this->get_coupon_settings( $recovery, $option, $step_nr, 'email_restriction' );

		$restrictions = array( //Defining array of email options
			'any_email'			=> esc_html__( 'Any email', 'woo-save-abandoned-carts' ),
			'abandoned_email'	=> esc_html__( 'Abandoned cart email', 'woo-save-abandoned-carts' )
		);

		echo '<select id="cartbounty-pro-'. esc_attr( $automation ) .'-coupon-email-restriction'. esc_attr( $field_id ) .'" class="cartbounty-pro-select" name="'. esc_attr( $option ) . esc_attr( $step_nr ) .'[email_restriction]" autocomplete="off" '. $admin->disable_field() .'>';
		foreach( $restrictions as $key => $restriction ){
			echo "<option value='". esc_attr( $key ) ."' ". selected( $selected_restriction, $key, false ) .">". esc_attr( $restriction ) ."</option>";
		}
		echo '</select>';
	}


	/**
	* Returning HTML of coupon settings
	*
	* @since    9.4
	* @return   HTML
	* @param    string     $recovery             Recovery type e.g. ActiveCampaign, WordPress, MailChimp
	* @param    string     $option               Option data field name for storing values
	* @param    integer    $step_nr              Automation step number
	*/
	public function display_coupon_settings( $recovery, $option, $step_nr = false ){
		$admin = $this->admin();
		$automation = $this->automation();
		$automation_name = $recovery;
		$field_id = '';

		if( $automation->multi_step_automation( $recovery ) ){ //In case of of WordPress or BulkGate, must add additional items to output the form as we need to display coupons in all of the steps
			$automation_name = 'automation';
			$field_id = '-'.$step_nr;
			$step_nr = '['. $step_nr .']';
		}

		$title = esc_html__( 'Coupon', 'woo-save-abandoned-carts' );
		$description = esc_html__( 'Consider adding a coupon code to encourage customers to complete their purchase.', 'woo-save-abandoned-carts' );

		if( $recovery == 'exit_intent' || $recovery == 'early_capture' ){
			$page_slug = 'exit-intent-popup-technology';
			
			if( $recovery == 'early_capture' ){
				$page_slug = 'early-capture-add-to-cart-popup';
			}
			
			$title = esc_html__( 'Instant coupon', 'woo-save-abandoned-carts' );
			$description = sprintf(
				/* translators: %s - Link start, %s - Link end */
				esc_html__( 'Provide %sInstant coupon codes%s to motivate customers to complete their purchase. Be sure to mention this in your message title.', 'woo-save-abandoned-carts' ), '<a href="'. esc_url( $admin->get_trackable_link( CARTBOUNTY_PRO_LICENSE_SERVER_URL . $page_slug, 'instant_coupons', '#enable-instant-coupons' ) ) .'" target="_blank">', '</a>' );
		}

		$coupon_settings = $this->get_coupon_settings( $recovery, $option, $step_nr );
		$generate_coupon = $coupon_settings['generate_coupon'];
		$existing_coupon = $coupon_settings['existing_coupon'];
		$coupon_amount = $coupon_settings['coupon_amount'];
		$coupon_shipping = $coupon_settings['coupon_shipping'];
		$coupon_prefix = $coupon_settings['coupon_prefix'];
		$minimum_spend = $coupon_settings['minimum_spend'];
		$maximum_spend = $coupon_settings['maximum_spend'];
		$coupon_individual = $coupon_settings['coupon_individual'];
		$coupon_sale = $coupon_settings['coupon_sale'];
		$coupon_include_products = $coupon_settings['coupon_include_products'];
		$coupon_exclude_products = $coupon_settings['coupon_exclude_products'];
		$coupon_include_categories = $coupon_settings['coupon_include_categories'];
		$coupon_description = $coupon_settings['coupon_description'];
		$excluded_emails_phones = $coupon_settings['excluded_emails_phones'];
		$prevent_repeats = $coupon_settings['prevent_repeats'];

		$find_items_nonce = wp_create_nonce( 'find_items' ); ?>

		<div class="cartbounty-pro-titles-column cartbounty-col-sm-12 cartbounty-col-md-4 cartbounty-col-lg-3">
			<h4><?php echo $title; ?></h4>
			<p class="cartbounty-pro-titles-column-description">
				<?php echo $description; ?>
			</p>
		</div>
		<div class="cartbounty-pro-settings-column cartbounty-col-sm-12 cartbounty-col-md-8 cartbounty-col-lg-9<?php if($generate_coupon){ echo ' cartbounty-pro-checked-parent'; }?>">
			<div class="cartbounty-pro-settings-group cartbounty-pro-toggle">
				<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-generate-coupon<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-switch cartbounty-pro-control-visibility">
					<input id="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-generate-coupon<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-checkbox" type="checkbox" name="<?php echo esc_attr( $option ); ?><?php echo esc_attr( $step_nr ); ?>[generate_coupon]" value="1" <?php echo $admin->disable_field(); ?> <?php echo checked( 1, $generate_coupon, false ); ?> autocomplete="off" />
					<span class="cartbounty-pro-slider round"></span>
				</label>
				<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-generate-coupon<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-control-visibility"><?php esc_html_e('Generate coupon', 'woo-save-abandoned-carts'); ?></label>
			</div>
			<div class="cartbounty-pro-settings-group cartbounty-pro-hidden">
				<div class="cartbounty-pro-tabs">
					<ul class="cartbounty-pro-tabs-menu">
						<li>
							<button class="cartbounty-pro-tab-link active" id="cartbounty-pro-tab-general<?php echo esc_attr( $field_id ); ?>" data-cb-target="#cartbounty-pro-tab-general-content<?php echo esc_attr( $field_id ); ?>" type="button"><?php esc_html_e('General', 'woo-save-abandoned-carts'); ?></button>
						</li>
						<li>
							<button class="cartbounty-pro-tab-link" id="cartbounty-pro-tab-restrictions<?php echo esc_attr( $field_id ); ?>" data-cb-target="#cartbounty-pro-tab-restrictions-content<?php echo esc_attr( $field_id ); ?>" type="button"><?php esc_html_e('Usage restrictions', 'woo-save-abandoned-carts'); ?></button>
						</li>
					</ul>
					<div class="cartbounty-pro-tabs-contents">
						<div class="cartbounty-pro-tab active" id="cartbounty-pro-tab-general-content<?php echo esc_attr( $field_id ); ?>">
							<div class="cartbounty-pro-settings-group">
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-type<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e('Discount type', 'woo-save-abandoned-carts'); ?></label>
								<?php $this->display_coupon_types( $recovery, $option, $step_nr, $automation_name, $field_id ); ?>
							</div>
							<div class="cartbounty-pro-settings-group">
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-amount<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e('Coupon amount', 'woo-save-abandoned-carts'); ?></label>
								<input id="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-amount<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-text" type="number" name="<?php echo esc_attr( $option ); ?><?php echo esc_attr( $step_nr ); ?>[coupon_amount]" value="<?php echo esc_attr( $coupon_amount ); ?>" min="0" <?php echo $admin->disable_field(); ?> placeholder="<?php echo esc_attr( $this->get_defaults('coupon_amount') ); ?>" />
							</div>
							<div class="cartbounty-pro-settings-group cartbounty-pro-toggle">
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-shipping<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-switch">
									<input id="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-shipping<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-checkbox" type="checkbox" name="<?php echo esc_attr( $option ); ?><?php echo esc_attr( $step_nr ); ?>[coupon_shipping]" value="1" <?php echo $admin->disable_field(); ?> <?php echo checked( 1, $coupon_shipping, false ); ?> autocomplete="off" />
									<span class="cartbounty-pro-slider round"></span>
								</label>
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-shipping<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e('Allow free shipping', 'woo-save-abandoned-carts'); ?></label>
								<p class='cartbounty-pro-additional-information'>
									<?php echo sprintf( wp_kses_post( __( 'Check this box if the coupon grants free shipping. A <a href="%s" target="_blank">free shipping method</a> must be enabled in your shipping zone and be set to require "a valid free shipping coupon" (see the "Free Shipping Requires" setting).', 'woo-save-abandoned-carts' ) ), 'https://docs.woocommerce.com/document/free-shipping/' ); ?>
								</p>
							</div>
							<div class="cartbounty-pro-settings-group">
								<?php $admin->display_time_intervals( $option, str_replace( array( "[", "]"), "", $step_nr ), $automation_name, $recovery, $field_type = 'coupon_expiry' ); ?>
							</div>
							<div class="cartbounty-pro-settings-group">
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-prefix<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e('Coupon prefix', 'woo-save-abandoned-carts'); ?></label>
								<input id="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-prefix<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-text" type="text" name="<?php echo esc_attr( $option ); ?><?php echo esc_attr( $step_nr ); ?>[coupon_prefix]" value="<?php echo esc_attr( stripslashes( $coupon_prefix ) ); ?>" <?php echo $admin->disable_field(); ?> />
								<p class='cartbounty-pro-additional-information'>
									<?php esc_html_e( 'You can use this to easily distinguish between generated coupons and track recovery results.', 'woo-save-abandoned-carts' ); ?>
								</p>
							</div>
						</div>
						<div class="cartbounty-pro-tab" id="cartbounty-pro-tab-restrictions-content<?php echo esc_attr( $field_id ); ?>">
							<div class="cartbounty-pro-settings-group">
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-minimum-spend<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e('Minimum spend', 'woo-save-abandoned-carts'); ?></label>
								<input id="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-minimum-spend<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-text" type="number" name="<?php echo esc_attr( $option ); ?><?php echo esc_attr( $step_nr ); ?>[minimum_spend]" value="<?php echo esc_attr( $minimum_spend ); ?>" min="0" <?php echo $admin->disable_field(); ?> placeholder="<?php echo esc_attr( $this->get_defaults('minimum_spend_label') ); ?>" />
							</div>
							<div class="cartbounty-pro-settings-group">
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-maximum-spend<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e('Maximum spend', 'woo-save-abandoned-carts'); ?></label>
								<input id="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-maximum-spend<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-text" type="number" name="<?php echo esc_attr( $option ); ?><?php echo esc_attr( $step_nr ); ?>[maximum_spend]" value="<?php echo esc_attr( $maximum_spend ); ?>" min="0" <?php echo $admin->disable_field(); ?> placeholder="<?php echo esc_attr( $this->get_defaults('maximum_spend_label') ); ?>" />
							</div>
							<div class="cartbounty-pro-settings-group cartbounty-pro-toggle">
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-individual<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-switch">
									<input id="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-individual<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-checkbox" type="checkbox" name="<?php echo esc_attr( $option ); ?><?php echo esc_attr( $step_nr ); ?>[coupon_individual]" value="1" <?php echo $admin->disable_field(); ?> <?php echo checked( 1, $coupon_individual, false ); ?> autocomplete="off" />
									<span class="cartbounty-pro-slider round"></span>
								</label>
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-individual<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e('Individual use only', 'woo-save-abandoned-carts'); ?></label>
								<p class='cartbounty-pro-additional-information'>
									<?php esc_html_e( 'Check this box if the coupon cannot be used in conjunction with other coupons.', 'woo-save-abandoned-carts' ); ?>
								</p>
							</div>
							<div class="cartbounty-pro-settings-group cartbounty-pro-toggle">
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-sale<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-switch">
									<input id="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-sale<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-checkbox" type="checkbox" name="<?php echo esc_attr( $option ); ?><?php echo esc_attr( $step_nr ); ?>[coupon_sale]" value="1" <?php echo $admin->disable_field(); ?> <?php echo checked( 1, $coupon_sale, false ); ?> autocomplete="off" />
									<span class="cartbounty-pro-slider round"></span>
								</label>
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-sale<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e('Exclude sale items', 'woo-save-abandoned-carts'); ?></label>
								<p class='cartbounty-pro-additional-information'>
									<?php esc_html_e( 'Check this box if the coupon should not apply to items on sale. Per-item coupons will only work if the item is not on sale. Per-cart coupons will only work if there are items in the cart that are not on sale.', 'woo-save-abandoned-carts' ); ?>
								</p>
							</div>
							<div class="cartbounty-pro-settings-group">
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-include-products<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e('Products', 'woo-save-abandoned-carts'); ?></label>
								<select id="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-include-products<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-select cartbounty-pro-multiple cartbounty-pro-ajax-search" multiple name="<?php echo esc_attr( $option ); ?><?php echo esc_attr( $step_nr ); ?>[coupon_include_products][]" placeholder="<?php esc_attr_e('Search products...', 'woo-save-abandoned-carts'); ?>" autocomplete="off" data-search-type="product" data-action="find_items" data-nonce="<?php echo esc_attr( $find_items_nonce ); ?>">
									<?php foreach( $coupon_include_products as $product ){
										echo "<option value='". esc_attr( $product ) ."' selected>". esc_html( $admin->get_item_name_by_id( $product, 'product' ) ) ."</option>";
									}?>
								</select>
							</div>
							<div class="cartbounty-pro-settings-group">
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-exclude-products<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e('Exclude products', 'woo-save-abandoned-carts'); ?></label>
								<select id="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-exclude-products<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-select cartbounty-pro-multiple cartbounty-pro-ajax-search" multiple name="<?php echo esc_attr( $option ); ?><?php echo esc_attr( $step_nr ); ?>[coupon_exclude_products][]" placeholder="<?php esc_html_e('Search products...', 'woo-save-abandoned-carts'); ?>" autocomplete="off" data-search-type="product" data-action="find_items" data-nonce="<?php echo esc_attr( $find_items_nonce ); ?>">
									<?php foreach( $coupon_exclude_products as $product ){
										echo "<option value='". esc_attr( $product ) ."' selected>". esc_html( $admin->get_item_name_by_id( $product, 'product' ) ) ."</option>";
									}?>
								</select>
							</div>
							<div class="cartbounty-pro-settings-group">
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-include-product-categories<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e('Product categories', 'woo-save-abandoned-carts'); ?></label>
								<?php esc_html( $admin->display_product_categories( $recovery, $option, $step_nr, $automation_name, $field_id, 'include', $placement = 'coupons' ) ); ?>
							</div>
							<div class="cartbounty-pro-settings-group">
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-exclude-product-categories<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e('Exclude categories', 'woo-save-abandoned-carts'); ?></label>
								<?php esc_html( $admin->display_product_categories( $recovery, $option, $step_nr, $automation_name, $field_id, 'exclude', $placement = 'coupons' ) ); ?>
							</div>
							<?php if( !isset( $_GET['tab'] ) || $_GET['tab'] == 'recovery' ): ?>
							<div class="cartbounty-pro-settings-group">
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-email-restriction<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e('Coupon can be used by', 'woo-save-abandoned-carts'); ?></label>
								<?php esc_html( $this->display_coupon_email_restrictions( $recovery, $option, $step_nr, $automation_name, $field_id ) ); ?>
							</div>
							<?php endif; ?>
							<div class="cartbounty-pro-settings-group">
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-excluded-emails-phones<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e( 'Exclude these emails and phone numbers from receiving coupons', 'woo-save-abandoned-carts' ); ?></label>
								<input id="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-excluded-emails-phones<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-text cartbounty-pro-display-emails" type="text" name="<?php echo esc_attr( $option ); ?><?php echo esc_attr( $step_nr ); ?>[excluded_emails_phones]" value="<?php echo esc_attr( $excluded_emails_phones ); ?>" <?php echo $admin->disable_field(); ?> />
								<p class='cartbounty-pro-additional-information'>
									<?php esc_html_e( 'You can add multiple emails and phone numbers separated by a comma.', 'woo-save-abandoned-carts' ); ?> <?php esc_html_e( 'You can also use an asterisk (*) to match parts of an email. For example, "*@gmail.com" would match all Gmail addresses.', 'woo-save-abandoned-carts' ); ?>
								</p>
							</div>
							<div class="cartbounty-pro-settings-group cartbounty-pro-toggle">
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-prevent-repeats<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-switch">
									<input id="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-prevent-repeats<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-checkbox" type="checkbox" name="<?php echo esc_attr( $option ); ?><?php echo esc_attr( $step_nr ); ?>[prevent_repeats]" value="1" <?php echo $admin->disable_field(); ?> <?php echo checked( 1, $prevent_repeats, false ); ?> autocomplete="off" />
									<span class="cartbounty-pro-slider round"></span>
								</label>
								<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-prevent-repeats<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e( 'Prevent repeat coupons', 'woo-save-abandoned-carts' ); ?></label>
								<p class='cartbounty-pro-additional-information'>
									<?php esc_html_e( 'Stop providing coupons to users who have already received one.', 'woo-save-abandoned-carts' ); ?>
								</p>
							</div>
						</div>
					</div>
				</div>
			</div>
			<div class="cartbounty-pro-settings-group cartbounty-pro-hidden-enabled">
				<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-existing-coupon<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e('Include an existing coupon', 'woo-save-abandoned-carts'); ?></label>
				<select id="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-existing-coupon<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-select cartbounty-pro-ajax-search cartbounty-pro-hide-remove-button" name="<?php echo esc_attr( $option ); ?><?php echo esc_attr( $step_nr ); ?>[existing_coupon]" placeholder="<?php esc_attr_e('Search coupon...', 'woo-save-abandoned-carts'); ?>" autocomplete="off" data-search-type="shop_coupon" data-action="find_items" data-nonce="<?php echo esc_attr( $find_items_nonce ); ?>">
					<?php if($existing_coupon) echo "<option value=". esc_attr( $existing_coupon ) ." selected>". esc_html( $admin->get_item_name_by_id( $existing_coupon, 'shop_coupon' ) ) ."</option>"; ?>
				</select>
			</div>
			<?php if($recovery == 'wordpress'): ?>
				<div class="cartbounty-pro-settings-group">
					<label for="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-description<?php echo esc_attr( $field_id ); ?>"><?php esc_html_e('Description', 'woo-save-abandoned-carts'); ?></label>
					<div class="cartbounty-pro-content-creation cartbounty-pro-flex">
						<input id="cartbounty-pro-<?php echo esc_attr( $automation_name ); ?>-coupon-description<?php echo esc_attr( $field_id ); ?>" class="cartbounty-pro-text" type="text" name="<?php echo esc_attr( $option ); ?><?php echo esc_attr( $step_nr ); ?>[coupon_description]" value="<?php echo esc_attr( stripslashes( $coupon_description ) ); ?>" placeholder="<?php echo esc_attr( $this->get_defaults('coupon_description') ); ?>" /><?php $admin->add_emojis(); ?><?php $admin->add_tags(); ?>
					</div>
				</div>
			<?php endif; ?>
		</div>
	<?php }

	/**
	* Delete expired coupons that have not been used and have been previously created by CartBounty
	* Coupons are erased in batches of 50 to avoid timeouts
	*
	* @since    9.4
	*/
	public function delete_unused_expired_coupons(){
		$args = array( //Selecting coupons that have expired, have been created by CartBounty and have not been used
			'posts_per_page'	=> 500,
			'post_type'			=> 'shop_coupon',
			'post_status'		=> 'publish',
			'meta_query'		=> array(
				'relation'		=> 'AND',
				array(
					'key'		=> 'date_expires',
					'value'		=> current_time( 'timestamp', true ),
					'compare'	=> '<='
				),
				array(
					'key'		=> 'date_expires',
					'value'		=> '',
					'compare'	=> '!='
				),		
				array(
					'key'		=> 'cartbounty_pro_coupon',
					'value'		=> 1,
					'compare'	=> '='
				),
				array(
					'key'		=> 'usage_count',
					'value'		=> 0,
					'compare'	=> '='
				)
			),
			'orderby' => array( 
				'date_expires' => 'ASC'
			),
		);
		$coupons = get_posts( $args );

		if ( !empty($coupons) ) {
			foreach ($coupons as $coupon) {
				wp_delete_post( $coupon->ID, true );
			}
		}
	}

	/**
	* Checking if repeat coupons are allowed or not
	* Then check if a users email, phone number or push notification has previously received a coupon code or not
	* It does not matter if previously user has received coupon code via email, phone or push notification,
	* CartBounty is looking for any contact information that can be linked with the same customer and if it finds any shopping cart linked with
	* any of the contact information, it will return true.
	*
	* @since    9.11
	* @return   boolean
	* @param    object    $cart              Cart data
	* @param    string    $recovery          Recovery type e.g. ActiveCampaign, WordPress, MailChimp
	* @param    string    $option            Option data field name for storing values
	* @param    integer   $step_nr           Automation step number
	*/
	private function check_repeat_coupon( $cart, $recovery, $option, $step_nr ){
		$result = false;
		$settings = (object)$this->get_coupon_settings( $recovery, $option, $step_nr );

		if( !empty( $settings->prevent_repeats ) ){ //If option to check repeat coupons is enabled
			global $wpdb;
			$cart_table = $wpdb->prefix . CARTBOUNTY_PRO_TABLE_NAME;
			$fields = array();
			$values = array();

			if( !empty( $cart->email ) ){
				$fields[] = 'email = %s';
				$values[] = $cart->email;
			}

			if( !empty( $cart->phone ) ){
				$fields[] = 'phone = %s';
				$values[] = $cart->phone;
			}

			if( !empty( $cart->pn_subscription ) ){
				$fields[] = 'pn_subscription = %s';
				$values[] = $cart->pn_subscription;
			}

			if( !empty( $fields ) ){

				$fields = implode( ' OR ', $fields ); //Linking multiple values with OR (in case there are multiple)

				//Try to find previous user's shopping cart that match email, phone or push notification subscription data (depending on the recovery type) and has a coupon applied
				//Make sure we exclude carts with the same cart ID (because if store administrator has enabled coupons in all steps, we want all of these coupons to be delivered). Also exclude carts without coupons
				$row = $wpdb->get_row(
					$wpdb->prepare(
						"SELECT id, coupons
						FROM $cart_table
						WHERE id != %d AND
						coupons != '' AND
						coupons != 'a:0:{}' AND
						($fields)",
						array_merge( array($cart->id), $values)
					)
				);

				if( $row ){ //If we have found an older cart with a coupon code applied to it
					$result = true;
				}
			}
		}

		return $result;
	}

	/**
	 * Count coupons in Coupon table
	 *
	 * @since    4.0
	 * @return   Number
	 */
	public function coupon_count(){
		global $wpdb;
		$admin = $this->admin();

		if( $admin->table_exists( 'coupon_table_exists' ) ){
			$coupon_table = $wpdb->prefix . CARTBOUNTY_PRO_TABLE_NAME_COUPONS;
			$total_items = $wpdb->get_var("SELECT COUNT(coupon_id) FROM $coupon_table");
			return $total_items;
		}else{
			return false;
		}
	}
}