<?php
/**
 * Reward Setting module
 *
 * @package Vite_Reward_Lite\Modules
 */

namespace Vite_Reward_Lite\Modules;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use Appsbd_Lite\V5\libs\AppInput;
use Appsbd_Lite\V5\libs\Ajax_Confirm_Response;
use Vite_Reward_Lite\Core\Vite_Reward_Module_Lite;
use Vite_Reward_Lite\Models\Database\Mapbd_Reward_Badge;
use Vite_Reward_Lite\Models\Database\Mapbd_Reward_Email_Template;
use Vite_Reward_Lite\Models\Database\Mapbd_Reward_Log;

/**
 * Class Reward_Rules
 *
 * @package Vite_Reward_Lite\Modules
 */
class Vite_Reward_Settings extends Vite_Reward_Module_Lite {
	/**
	 * Its property is_ser_global_var
	 *
	 * @var bool
	 */
	public static $is_ser_global_var = false;
	/**
	 * Its property reg_form_id
	 *
	 * @var int
	 */
	public static $reg_form_id = 1;
	/**
	 * Its property user_account_id
	 *
	 * @var int
	 */
	public static $user_account_id = 1;

	/**
	 * The on initialize is generated by appsbd
	 */
	public function initialize() {
	}

	/**
	 * The on init is generated by appsbd
	 */
	public function on_init() {
		parent::on_init();
		$this->add_admin_ajax_action( 'option', 'ajax_request_callback' );
		$this->add_admin_ajax_action( 'get-option', 'get_admin_options' );
		$this->add_ajax_both_action( 'user-reward-data', array( $this, 'user_reward_data' ) );
		$this->add_ajax_both_action( 'user-point-redemption', array( $this, 'user_point_redemption' ) );
		add_action( 'appsbd/reward/action/apply-order-reward', array( $this, 'apply_reward_in_cart' ) );

		add_action( 'wp_ajax_remove_coupon', array( $this, 'remove_coupon' ) );
		add_action( 'wp_ajax_nopriv_remove_coupon', array( $this, 'remove_coupon' ) );

		add_action( 'appsbd/vite-reward/action/send-email', array( $this, 'send_email' ), 9, 2 );

		add_action( 'woocommerce_order_status_completed', array( $this, 'send_email_on_order_complete' ), 999, 2 );
		add_action( 'user_register', array( $this, 'send_email_on_user_reg' ), 999, 1 );
		add_filter( 'woocommerce_account_menu_items', array( $this, 'custom_account_menu_item' ) );

		add_action( 'woocommerce_account_reward-tab_endpoint', array( $this, 'custom_tab_content' ) );

		add_action( 'woocommerce_flush_rewrite_rules', array( $this, 'custom_tab_flush_rewrite_rules' ) );
		add_shortcode( 'VRD_USER_ACCOUNT', array( $this, 'user_account' ) );
		add_shortcode( 'VRD_APPLY_REWARD', array( $this, 'reward_apply' ) );
		add_filter(
			'the_content',
			function ( $content ) {
				if ( ( function_exists( 'is_cart' ) ) || ( function_exists( 'is_checkout' ) ) ) {
					ob_start();
					$this->reddem_reward_notice();
					$custom_text = ob_get_clean();
					if ( ! empty( $this->options['cart_page_type'] ) && 'B' == $this->options['cart_page_type'] && is_cart() && 'N' != $this->options['cart_page_position'] ) {
						if ( ! empty( $this->options['cart_page_position'] ) && 'woocommerce_before_cart' == $this->options['cart_page_position'] ) {
							return $custom_text . $content;
						}
						if ( ! empty( $this->options['cart_page_position'] ) && 'woocommerce_after_cart' == $this->options['cart_page_position'] ) {
							return $content . $custom_text;
						}
					}
					if ( ! empty( $this->options['checkout_page_type'] ) && 'B' == $this->options['checkout_page_type'] && is_checkout() && 'N' != $this->options['checkout_page_position'] ) {
						if ( ! empty( $this->options['checkout_page_position'] ) && 'woocommerce_before_checkout_form' == $this->options['checkout_page_position'] ) {
							return $custom_text . $content;
						}
						if ( ! empty( $this->options['checkout_page_position'] ) && 'woocommerce_after_checkout_form' == $this->options['checkout_page_position'] ) {
							return $content . $custom_text;
						}
					}
				}

				return $content;
			}
		);
		if ( ! empty( $this->options['cart_page_type'] ) && 'L' == $this->options['cart_page_type'] ) {
			if ( ! empty( $this->options['cart_page_position'] ) ) {
				add_action(
					$this->options['cart_page_position'],
					array( $this, 'reddem_reward_notice' )
				);
			} else {
				add_action(
					'woocommerce_cart_actions',
					array( $this, 'reddem_reward_notice' )
				);
			}
		}

		if ( ! empty( $this->options['checkout_page_type'] ) && 'L' == $this->options['checkout_page_type'] ) {
			if ( ! empty( $this->options['checkout_page_position'] ) ) {
				add_action(
					$this->options['checkout_page_position'],
					array( $this, 'reddem_reward_notice' )
				);
			} else {
				add_action(
					'woocommerce_before_checkout_form',
					array( $this, 'reddem_reward_notice' )
				);
			}
		}

		add_filter( 'woocommerce_get_shop_coupon_data', array( $this, 'reward_create_virtual_coupon' ), 9999, 2 );
		add_action( 'woocommerce_applied_coupon', array( $this, 'action_applied_coupon' ) );
		add_filter(
			'woocommerce_cart_totals_coupon_label',
			array( $this, 'reward_filter_woocommerce_coupon_label' ),
			10,
			2
		);
		add_filter( 'woocommerce_cart_totals_coupon_html', array( $this, 'reward_virtual_coupon_remove' ), 30, 3 );

		add_action( 'woocommerce_checkout_order_processed', array( $this, 'on_new_order' ), 20, 3 );
		add_action( 'woocommerce_store_api_checkout_order_processed', array( $this, 'update_order_meta' ) );
		add_action( 'appsbd/vite-reward/action/conditional-hook', array( $this, 'conditional_hook' ), 10 );
	}

	/**
	 * The conditional hook is generated by appsbd
	 *
	 * @param mixed $status It is status param.
	 */
	public function conditional_hook( $status ) {
		if ( $status ) {
			add_filter( 'woocommerce_get_shop_coupon_data', array( $this, 'reward_create_virtual_coupon' ), 9999, 2 );
		} else {
			remove_filter(
				'woocommerce_get_shop_coupon_data',
				array( $this, 'reward_create_virtual_coupon' ),
				9999,
				2
			);
		}
	}

	/**
	 * The reddem reward notice is generated by appsbd
	 */
	public function reddem_reward_notice() {
		if ( is_wc_endpoint_url( 'order-received' ) ) {
			return;
		}
		if ( ! empty( wp_get_current_user()->ID ) ) {
			?>
			<div id="custom_rwd" class="" style="text-align: left;">
				<?php
				echo do_shortcode( '[VRD_APPLY_REWARD]' );
				?>
			</div>
			<?php
		}
	}

	/**
	 * The remove coupon is generated by appsbd
	 *
	 * @return Ajax_Confirm_Response
	 */
	public function remove_coupon() {
		$response = new Ajax_Confirm_Response();
		$coupon   = AppInput::post_value( 'coupon_code' );
		WC()->cart->remove_coupon( $coupon );
		$this->unset_wc_session();
		$response->display_with_response( true );

		return $response;
	}

	/**
	 * The unset wc session is generated by appsbd
	 */
	public function unset_wc_session() {
		if ( ! empty( WC()->session ) && ! empty( WC()->session->get( '_rwd_redeem_amount', '' ) ) ) {
			WC()->session->__unset( '_rwd_redeem_amount' );
			WC()->session->__unset( '_rwd_redeem_rate' );
			WC()->session->__unset( '_rwd_redeem_points' );
		}
	}

	/**
	 * This function is used to rename discount type in cart page
	 *
	 * @param string $sprintf sprintf.
	 * @param object $coupon coupon.
	 *
	 * @return string
	 */
	public function reward_filter_woocommerce_coupon_label( $sprintf, $coupon ) {
		$points = WC()->session->get( '_rwd_redeem_points' );

		/* translators: %s is the number of reward points */
		$cart_discount = $this->__( 'Reward(%s)', $points );
		$coupon_data   = $coupon->get_data();
		if ( ! empty( $coupon_data ) ) {
			if ( strtolower( $coupon_data['code'] ) === strtolower( $cart_discount ) ) {
				$sprintf = $cart_discount;
			}
		}

		return $sprintf;
	}

	/**
	 * This function is used to remove coupon.
	 *
	 * @param string $coupon_html coupon html.
	 * @param object $coupon coupon.
	 * @param string $discount_amount_html discount amount html.
	 *
	 * @return string
	 */
	public function reward_virtual_coupon_remove( $coupon_html, $coupon, $discount_amount_html ) {
		$points = WC()->session->get( '_rwd_redeem_points' );

		/* translators: %s is the number of reward points */
		$cart_discount = $this->__( 'Reward(%s)', $points );
		$coupon_data   = $coupon->get_data();
		if ( ! empty( $coupon_data ) ) {
			if ( strtolower( $coupon_data['code'] ) === strtolower( $cart_discount ) ) {
				$coupon_html = $discount_amount_html . ' <a href="#" class="remove-coupon-btn" data-coupon="' . esc_attr( $coupon->get_code() ) . '">' . $this->__(
					'[Remove]'
				) . '</a>';
			}
		}

		return $coupon_html;
	}

	/**
	 * The action applied coupon is generated by appsbd
	 *
	 * @param mixed $coupon It is coupon param.
	 */
	public function action_applied_coupon( $coupon ) {
		if ( $this->reward_is_coupon_code_valid( $coupon ) ) {
			wc_add_notice( $this->__( "Coupon '%s' has been applied. Mark as used.", $coupon ), 'error' );
		}
	}

	/**
	 * The on new order is generated by appsbd
	 *
	 * @param mixed $order_id It is order_id param.
	 * @param mixed $data It is data param.
	 * @param mixed $order It is order param.
	 */
	public function on_new_order( $order_id, $data, $order ) {
		$this->update_order_meta( $order );
	}

	/**
	 * The update order meta is generated by appsbd
	 *
	 * @param \WC_Order $order It is order param.
	 */
	public function update_order_meta( $order ) {
		if ( ! $order->meta_exists( '_is_vitepos' ) && ! $order->meta_exists( '_rwd_redeem_points' ) ) {
			if ( WC()->session->get( '_rwd_redeem_points' ) ) {
				$order->add_meta_data( '_rwd_redeem_points', WC()->session->get( '_rwd_redeem_points' ) );
				$order->add_meta_data( '_rwd_redeem_amount', WC()->session->get( '_rwd_redeem_amount' ) );
				$order->add_meta_data( '_rwd_redeem_rate', WC()->session->get( '_rwd_redeem_rate' ) );
				if ( $order->save() ) {
					if ( self::update_user_points(
						$order->get_customer_id(),
						'O',
						$order->get_id(),
						WC()->session->get( '_rwd_redeem_points' ),
						'Redeemed points on order',
						'O',
						'ORP'
					) ) {
						$order->add_meta_data( '_rwd_is_redeemed', 'Y' );
						$order->save_meta_data();
						$log = Mapbd_Reward_Log::find_by(
							'type',
							'O',
							array(
								'ref_val'  => $order->get_id(),
								'ref_type' => 'O',
							)
						);
						if ( self::get_module_option( 'is_redeem_notification', 'N' ) == 'Y' ) {
							/**
							 * Its for check is there any change before process
							 *
							 * @since 1.0
							 */
							do_action( 'appsbd/vite-reward/action/send-email', $log, 'ORP' );
						}
					}
				}
				WC()->session->destroy_session();
			}
		}
	}

	/**
	 * The reward create virtual coupon is generated by appsbd
	 *
	 * @param mixed $false It is false param.
	 * @param mixed $data It is data param.
	 *
	 * @return array
	 */
	public function reward_create_virtual_coupon( $false, $data ) {
		$coupon_code_valid = false;
		$coupon_settings   = null;
		/**
		 * Its for check is there any change before process
		 *
		 * @since 1.0
		 */
		$settings = apply_filters( 'appsbd/rwd/filters/get-admin-options', array() );
		if ( $this->reward_is_coupon_code_valid( $data ) ) {
			$coupon_code_valid = true;
		}
		if ( $coupon_code_valid ) {
			$points = WC()->session->get( '_rwd_redeem_points', '' );
			if ( empty( $points ) ) {
				return $false;
			}
			$amount        = WC()->session->get( '_rwd_redeem_amount' );
			$rate          = WC()->session->get( '_rwd_redeem_rate' );
			$redeem_amount = $rate * WC()->session->get( '_rwd_redeem_points' );
			if ( $amount != $redeem_amount ) {
				if ( $redeem_amount > WC()->cart->get_subtotal() ) {
					$redeem_amount = WC()->cart->get_subtotal();
				}
				if ( ! empty( $settings['is_reward_points_only'] ) && 'Y' == $settings['is_reward_points_only'] ) {
					$max_redeem_percentage = $settings['max_amount_percentage'];
					if ( ! empty( $max_redeem_percentage ) ) {
						$max_rate          = $max_redeem_percentage / 100;
						$max_redeem_amount = $max_rate * WC()->cart->get_subtotal();
						if ( $max_redeem_amount <= $redeem_amount ) {
							$redeem_amount = $max_redeem_amount;
						}
					}
				}
				WC()->session->set( '_rwd_redeem_amount', $redeem_amount );
			}

			$coupon_settings = array(
				'discount_type'              => 'fixed_cart',
				'amount'                     => $redeem_amount,
				'expiry_date'                => '',

				'individual_use'             => true,
				'product_ids'                => array(),
				'exclude_product_ids'        => array(),
				'usage_limit'                => '1',
				'usage_limit_per_user'       => '',
				'limit_usage_to_x_items'     => '',
				'usage_count'                => '',
				'virtual'                    => 'yes',
				'free_shipping'              => false,
				'product_categories'         => array(),
				'exclude_product_categories' => array(),
				'exclude_sale_items'         => false,
				'minimum_amount'             => '',
				'maximum_amount'             => '',
				'customer_email'             => array(),
			);

			return $coupon_settings;
		}

		return $false;
	}

	/**
	 * The reward is coupon code valid is generated by appsbd
	 *
	 * @param mixed $coupon_code It is coupon_code param.
	 *
	 * @return bool
	 */
	public function reward_is_coupon_code_valid( $coupon_code ) {
		if ( 0 === stripos( $coupon_code, 'reward' ) ) {
			return true;
		} else {
			$this->unset_wc_session();
		}

		return false;
	}

	/**
	 * The apply reward in cart is generated by appsbd
	 *
	 * @param mixed $coupon_code It is coupon_code param.
	 * @param mixed $amount It is amount param.
	 *
	 * @return bool
	 */
	public function apply_reward_in_cart( $coupon_code, $amount ) {

		return WC()->cart->add_discount( $coupon_code );
	}

	/**
	 * The apply reward in cart bk is generated by appsbd
	 *
	 * @param mixed $amount It is amount param.
	 *
	 * @return true|void
	 */
	public function apply_reward_in_cart_bk( $amount ) {
		$coupon_code = 'reward';
		if ( ! empty( $coupon_code ) ) {
			WC()->cart->apply_coupon( $coupon_code );

			return true;
		} else {
			$this->add_error( 'Reward discount add failed' );
		}
	}

	/**
	 * The reward apply is generated by appsbd
	 *
	 * @param mixed $atts It is atts param.
	 *
	 * @return false|string
	 */
	public function reward_apply( $atts ) {
		$this->set_global_shortcode_var();
		$atts = shortcode_atts(
			array(
				'redeem_text'     => $this->__( 'You can redeem your points' ),
				'redeem_btn_text' => $this->__( 'Redeem Now' ),
				'is_modal'        => $this->get_option( 'is_modal', 'N' ),
			),
			$atts
		);
		/**
		 * Its for check is there any change before process
		 *
		 * @since 1.0
		 */
		$color = apply_filters( 'appsbd/rwd/filters/get-theme-color', array() );

		$jv_client                                       = new \stdClass();
		$jv_client->settings                             = (object) $atts;
		$var_name                                        = 'apbd_rep_' . self::$reg_form_id++;

		ob_start();
		?>
		<script type='text/javascript'>
			/* <![CDATA[ */
			try {
				var <?php echo esc_html( $var_name ); ?>=<?php echo wp_json_encode( $jv_client ); ?>;
			} catch (e) {
			}
			/* ]]> */
		</script>
		<div id="<?php echo esc_html( $var_name ); ?>"
			class="appsbd-main apbd-reward-redeem
			<?php
			echo esc_html(
				'rwd-' . ( $color ? $color : $this->get_option(
					'client_theme_color',
					'gray'
				) )
			);
			?>
													"
			data-val='<?php echo esc_html( $var_name ); ?>'></div>
		<?php
		return ob_get_clean();
	}

	/**
	 * The custom account menu item is generated by appsbd
	 *
	 * @param mixed $items It is items param.
	 *
	 * @return array
	 */
	public function custom_account_menu_item( $items ) {
		/**
		 * Its for check is there any change before process
		 *
		 * @since 1.0
		 */
		$settings                = apply_filters( 'appsbd/rwd/filters/get-admin-options', array() );
		$new_items               = array_slice(
			$items,
			0,
			array_search( 'orders', array_keys( $items ), true ) + 1,
			true
		);
		$title                   = isset( $settings['user_menu_title'] ) && $settings['user_menu_title']
			? $settings['user_menu_title']
			: $this->get_option( 'user_menu_title', 'Vite Rewards' );
		$new_items['reward-tab'] = $this->__( $title );
		$new_items              += array_slice(
			$items,
			array_search( 'orders', array_keys( $items ), true ) + 1,
			null,
			true
		);

		return $new_items;
	}


	/**
	 * The custom tab flush rewrite rules is generated by appsbd
	 */
	public function custom_tab_flush_rewrite_rules() {
		flush_rewrite_rules();
	}

	/**
	 * The custom tab content is generated by appsbd
	 */
	public function custom_tab_content() {
		if ( is_user_logged_in() ) {
			echo do_shortcode( '[VRD_USER_ACCOUNT]' );
		} else {
			$login_url = wp_login_url();
			echo '<a href="' . esc_url( $login_url ) . '" class="button login-button">Login to View</a>';
		}
	}

	/**
	 * The user account is generated by appsbd
	 *
	 * @param mixed $atts It is atts param.
	 *
	 * @return false|string
	 */
	public function user_account( $atts ) {
		/**
		 * Its for check is there any change before process
		 *
		 * @since 1.0
		 */
		$badge_settings = apply_filters( 'appsbd/rwd/filters/get-badge-settings', array() );
		$this->set_global_shortcode_var();
		$atts = shortcode_atts(
			array(
				'is_user_badge' => $badge_settings['is_user_badge'] ?? 'N',
			),
			$atts
		);
		/**
		 * Its for check is there any change before process
		 *
		 * @since 1.0
		 */
		$color                      = apply_filters(
			'appsbd/rwd/filters/get-theme-color',
			array()
		);
		$jv_client                  = new \stdClass();
		$jv_client->settings        = (object) $atts;
		$var_name                                        = 'apbd_rwd_user_' . self::$user_account_id++;

		ob_start();
		?>
		<script type='text/javascript'>
			/* <![CDATA[ */
			try {
				var <?php echo esc_html( $var_name ); ?>=<?php echo wp_json_encode( $jv_client ); ?>;
			} catch (e) {
			}
			/* ]]> */
		</script>
		<div id="<?php echo esc_html( $var_name ); ?>"
			class="appsbd-main apbd-reward-user
			<?php
			echo esc_html(
				'rwd-' . ( $color ? $color : $this->get_option(
					'client_theme_color',
					'gray'
				) )
			);
			?>
													"
			data-val='<?php echo esc_html( $var_name ); ?>'></div>
		<?php
		return ob_get_clean();
	}

	/**
	 * The set global shortcode var is generated by appsbd
	 */
	public function set_global_shortcode_var() {
		if ( self::$is_ser_global_var ) {
			return;
		}
		self::$is_ser_global_var = true;
	}

	/**
	 * The user reward data is generated by appsbd
	 *
	 * @return Ajax_Confirm_Response
	 */
	public function user_reward_data() {
		$response       = new Ajax_Confirm_Response();
		$user           = wp_get_current_user();
		$client         = new \stdClass();
		$client->id     = $user->ID;
		$client->points = Mapbd_Reward_Log::get_current_points( $client->id );
		/**
		 * Its for check is there any change before process
		 *
		 * @since 2.0
		 */
		do_action( 'appsbd/reward/action/get-customer-data', $client );
		$response->display_with_response( true, $client );

		return $response;
	}

	/**
	 * The user point redemption is generated by appsbd
	 *
	 * @return Ajax_Confirm_Response
	 */
	public function user_point_redemption() {
		$response = new Ajax_Confirm_Response();
		$user_id  = get_current_user_id();
		$user     = get_current_user();

		$redeems    = AppInput::post_value( 'redeems' );
		$is_applied = false;
		/**
		 * Its for check is there any change before process
		 *
		 * @since 1.0
		 */
		$settings  = apply_filters( 'appsbd/rwd/filters/get-admin-options', array() );
		$uc_points = Mapbd_Reward_Log::get_current_points( $user_id );
		$max_usage = $settings['max_redemption'];
		if ( empty( $max_usage ) ) {
			$max_usage = $uc_points;
		}
		if ( ! empty( $user_id ) && ! WC()->cart->is_empty() ) {
			if ( $uc_points >= $redeems ) {
				if ( $max_usage > 0 && $max_usage < $redeems ) {

					$response->display_with_response( $is_applied );

					return $response;
				}
				$per_point_amount = $this->get_option( 'currency_amount' );
				$per_point        = $this->get_option( 'currency_points' );
				$rate             = appsbd_wc_amount( $per_point_amount ) / appsbd_wc_amount( $per_point );
				$amount           = $rate * $redeems;
				if ( $amount > WC()->cart->get_subtotal() ) {
					$amount = WC()->cart->get_subtotal();
				}
				if ( ! empty( $settings['is_reward_points_only'] ) && 'Y' == $settings['is_reward_points_only'] ) {
					$max_redeem_percentage = $settings['max_amount_percentage'];
					if ( ! empty( $max_redeem_percentage ) ) {
						$max_rate          = $max_redeem_percentage / 100;
						$max_redeem_amount = $max_rate * WC()->cart->get_subtotal();
						if ( $max_redeem_amount <= $amount ) {
							$amount = $max_redeem_amount;
						}
					}
				}
				WC()->session->set( '_rwd_redeem_points', $redeems );
				WC()->session->set( '_rwd_redeem_amount', $amount );
				WC()->session->set( '_rwd_redeem_rate', $rate );

				$code       = sprintf( 'Reward(%s)', $redeems );
				$is_applied = $this->apply_reward_in_cart( $code, $amount );
				if ( ! $is_applied ) {
					$this->unset_wc_session();
				}
			}
		}

		$response->display_with_response( $is_applied );

		return $response;
	}

	/**
	 * The send email on order complete is generated by appsbd
	 *
	 * @param mixed     $order_id Order Id.
	 * @param \WC_Order $order Order.
	 */
	public function send_email_on_order_complete( $order_id, $order ) {
		if ( ! $order->meta_exists( '_is_vitepos' ) && 'Y' == $this->get_option( 'is_reward_notification', 'N' ) ) {
			$this->on_order_rewards( $order_id );
		}
	}

	/**
	 * The on order rewards is generated by appsbd
	 *
	 * @param mixed $order_id It is order_id param.
	 */
	public function on_order_rewards( $order_id ) {
		$new_log = new Mapbd_Reward_Log();
		$logs    = Mapbd_Reward_Log::find_all_by( 'ref_val', $order_id, array( 'ref_type' => 'O' ) );
		if ( ! empty( $logs ) ) {
			foreach ( $logs as $log ) {
				if ( 'O' != $log->type ) {
					$new_log->point_val += $log->point_val;
					$new_log->msg        = 'On order';
					$new_log->user_id    = $log->user_id;
					$new_log->type       = 'I';
					$new_log->ref_val    = $log->ref_val;
					$new_log->ref_type   = 'O';
					if ( empty( $new_log->prev_point ) ) {
						$new_log->prev_point = $log->prev_point;
					}
				}
			}
		}
		if ( ! empty( $new_log ) ) {
			$this->send_email( $new_log, 'POP' );
		}
	}

	/**
	 * The send email on user reg is generated by appsbd
	 *
	 * @param mixed $user_id New user Id.
	 */
	public function send_email_on_user_reg( $user_id ) {
		$user = get_userdata( $user_id );
		$log  = Mapbd_Reward_Log::find_by( 'user_id', $user_id, array( 'ref_type' => 'U' ) );
		if ( ! empty( $log ) && ! empty( $user->user_email ) ) {
			$this->send_email( $log, 'SUP' );
		}
	}

	/**
	 * The send email is generated by appsbd
	 *
	 * @param Mapbd_Reward_Log $reward_log Get reward log.
	 * @param string           $key Get email key.
	 */
	public function send_email( $reward_log, $key = '' ) {
		self::send_reward_email( $reward_log, $key );
	}

	/**
	 * The send reward email is generated by appsbd
	 *
	 * @param mixed $log_obj Get log obj.
	 * @param mixed $key Get email key.
	 */
	public static function send_reward_email( $log_obj, $key ) {
		$user             = get_user_by( 'id', $log_obj->user_id );
		$params           = array();
		$params['points'] = $log_obj->point_val;
		$points           = $log_obj->prev_point;
		if ( 'O' == $log_obj->type ) {
			$points = $points - $log_obj->point_val;
		} else {
			$points = $points + $log_obj->point_val;
		}
		$params['total_points']  = $points;
		$params['customer_name'] = apbd_get_user_title_by_user( $user );
		if ( 'O' == $log_obj->ref_type ) {
			$params['order_no'] = $log_obj->ref_val;
			$order              = wc_get_order( $log_obj->ref_val );

			$params['sub_total']   = $order->get_subtotal();
			$params['order_total'] = $order->get_total();
		}
		if ( 'R' == $log_obj->ref_type ) {
			$params['order_no']    = $log_obj->ex1_param;
			$params['refund_id']   = $log_obj->ref_val;
			$order                 = new \WC_Order( $log_obj->ex1_param );
			$params['sub_total']   = $order->get_subtotal();
			$params['order_total'] = $order->get_total();
		}
		if ( 'B' == $log_obj->ref_type ) {
			$wc_badge             = Mapbd_Reward_Badge::find_by( 'id', $log_obj->ref_val );
			$params['new_badge']  = $wc_badge->name;
			$params['prev_badge'] = 'Default';
			$prev_badge           = null;
			if ( ! empty( $log_obj->ex1_param ) ) {
				$prev_badge = Mapbd_Reward_Badge::find_by( 'id', $log_obj->ex1_param );
			}
			if ( ! empty( $prev_badge ) ) {
				$params['prev_badge'] = $prev_badge->name;
			}
		}
		$params['profile_link']        = self::get_profile_link( $log_obj->user_id );
		$params['view_profile_anchor'] = '<a href="' . $params['profile_link'] . '">' . $log_obj->__( 'View Profile' ) . '</a>';
		$params['msg']                 = $log_obj->msg;
		Mapbd_Reward_Email_Template::send_email_templates( $key, $user->user_email, $params, '' );
	}

	/**
	 * The get profile link is generated by appsbd
	 *
	 * @param mixed $user_id User Id.
	 *
	 * @return false|string
	 */
	public static function get_profile_link( $user_id ) {
		$a = get_permalink( wc_get_page_id( 'myaccount' ) );

		return $a;
	}

	/**
	 * The ajax request callback is generated by appsbd
	 */
	public function ajax_request_callback() {
		$response = new Ajax_Confirm_Response();
		if ( $this->update_request_option() ) {
			$this->get_admin_options();
		}

		$response->display_with_response( false, $this->get_admin_options() );
	}

	/**
	 * The update request option is generated by appsbd
	 */
	public function update_request_option() {
		$before_save = $this->options;
		$app_posts   = AppInput::get_posted_data();
		if ( ! empty( $app_posts['action'] ) ) {
			unset( $app_posts['action'] );
		}
		$is_updated = false;
		$skiped_key = array(
			'max_redemption',
			'is_refund_order',
			'is_refund_redeem',
			'user_menu_title',
			'is_reward_points_only',
			'max_amount_percentage',
			'client_theme_color',
			'is_badge',
			'is_user_badge',
		);
		foreach ( $app_posts as $key => $post ) {
			if ( in_array( $key, $skiped_key ) ) {
				continue;
			} else {
				$this->options[ $key ] = $post;
			}
		}
		/**
		 * Its for check is there any change before process
		 *
		 * @since 1.0
		 */
		$external_update = apply_filters( 'appsbd/rwd/filters/is-admin-settings-update', false, $app_posts );
		if ( ! $external_update && $before_save === $this->options ) {
			$this->add_error( 'No change for update' );
		} elseif ( $this->update_option() || $external_update ) {

			$is_updated = true;
			$this->add_info( 'Saved Successfully' );
		} else {
			$this->add_error( 'No change for update' );
		}

		return $is_updated;
	}

	/**
	 * The get admin settings is generated by appsbd
	 */
	public function get_admin_options() {
		$response = new Ajax_Confirm_Response();
		if ( empty( $this->options ) ) {
			$this->set_default_options();
		}
		$options['currency_amount']               = $this->get_option( 'currency_amount', 1 );
		$options['currency_points']               = $this->get_option( 'currency_points', 1 );
		$options['is_refund_order']               = $this->get_option( 'is_refund_order', 'N' );
		$options['is_refund_redeem']              = $this->get_option( 'is_refund_redeem', 'N' );
		$options['is_modal']                      = $this->get_option( 'is_modal', 'N' );
		$options['is_redeem_notification']        = $this->get_option( 'is_redeem_notification', 'N' );
		$options['is_reward_notification']        = $this->get_option( 'is_reward_notification', 'N' );
		$options['is_display_point_notification'] = $this->get_option( 'is_display_point_notification', 'N' );
		$options['max_redemption']                = $this->get_option( 'max_redemption', 0 );
		$options['user_menu_title']               = $this->get_option( 'user_menu_title', 'Vite Rewards' );
		$options['is_reward_points_only']         = $this->get_option( 'is_reward_points_only', 'N' );
		$options['max_amount_percentage']         = $this->get_option( 'max_amount_percentage', 0 );
		$options['client_theme_color']            = $this->get_option( 'client_theme_color', 'gray' );
		$options['is_badge']                      = $this->get_option( 'is_badge', 'N' );
		$options['is_user_badge']                 = $this->get_option( 'is_user_badge', 'N' );
		$options['is_total_earning_points']       = $this->get_option( 'is_total_earning_points', 'N' );
		$options['cart_page_type']                = $this->get_option( 'cart_page_type', 'L' );
		$options['cart_page_position']            = $this->get_option(
			'cart_page_position',
			'woocommerce_before_cart_table'
		);
		$options['checkout_page_type']            = $this->get_option( 'checkout_page_type', 'L' );
		$options['checkout_page_position']        = $this->get_option(
			'checkout_page_position',
			'woocommerce_before_checkout_form'
		);

		/**
		 * Its for check is there any change before process
		 *
		 * @since 1.0
		 */
		$options = apply_filters( 'appsbd/rwd/filters/get-admin-options', $options );
		$response->display_with_response( true, $options );
	}

	/**
	 * The set default options is generated by appsbd
	 */
	private function set_default_options() {
		$this->options['currency_amount']               = 1;
		$this->options['currency_points']               = 1;
		$this->options['is_modal']                      = 'N';
		$this->options['is_refund_order']               = 'N';
		$this->options['is_refund_redeem']              = 'N';
		$this->options['is_redeem_notification']        = 'N';
		$this->options['is_reward_notification']        = 'N';
		$this->options['is_display_point_notification'] = 'N';
		$this->options['max_redemption']                = 0;
		$this->options['user_menu_title']               = 'Vite Rewards';
		$this->options['is_reward_points_only']         = 'N';
		$this->options['max_amount_percentage']         = 0;
		$this->options['client_theme_color']            = 'gray';
		$this->options['is_badge']                      = 'N';
		$this->options['is_user_badge']                 = 'N';
		$this->options['is_total_earning_points']       = 'N';
		$this->options['cart_page_type']                = 'L';
		$this->options['cart_page_position']            = 'woocommerce_before_cart_table';
		$this->options['checkout_page_type']            = 'L';
		$this->options['checkout_page_position']        = 'woocommerce_before_checkout_form';
		$this->update_option();
	}

	/**
	 * The update user points is generated by appsbd
	 *
	 * @param mixed $user_id It is user_id param.
	 * @param mixed $ref_type It is ref_type param.
	 * @param mixed $ref_val It is ref_val param.
	 * @param mixed $rule_points It is rule_points param.
	 * @param mixed $msg It is msg param.
	 * @param mixed $opr It is opr param.
	 * @param mixed $key It is key param.
	 * @param mixed $ex_param1 It is ex_param1 param.
	 *
	 * @return bool|void
	 */
	public static function update_user_points(
		$user_id,
		$ref_type,
		$ref_val,
		$rule_points,
		$msg,
		$opr = 'I',
		$key = '',
		$ex_param1 = ''
	) {
		$prev_points = 0.0;
		$points      = 0.0;

		$prev_points = self::user_prev_reward_points( $user_id, $opr );
		if ( 'O' == $opr && $prev_points < $rule_points ) {
			return false;
		}
		$points = $prev_points + $rule_points;
		$points = appsbd_wc_amount( $points );
		if ( $points > 0 ) {
			if ( 'O' == $opr ) {
				$i_points = 0.0;
				if ( metadata_exists( 'user', $user_id, 'apbd_reward_out' ) ) {
					$i_points = floatval( get_user_meta( $user_id, 'apbd_reward_out', true ) );
				}
				$i_points = $i_points + $rule_points;
				if ( update_user_meta( $user_id, 'apbd_reward_out', $i_points ) ) {
					if ( ! empty( $ex_param1 ) ) {
						$log = Mapbd_Reward_Log::AddLog(
							$opr,
							$user_id,
							$prev_points,
							$rule_points,
							$msg,
							$ref_val,
							$ref_type,
							'Y',
							$ex_param1
						);
					} else {
						$log = Mapbd_Reward_Log::AddLog(
							$opr,
							$user_id,
							$prev_points,
							$rule_points,
							$msg,
							$ref_val,
							$ref_type
						);
					}

					return ! empty( $log );
				}
			} else {
				$i_points = 0.0;
				if ( metadata_exists( 'user', $user_id, 'apbd_reward_in' ) ) {
					$i_points = floatval( get_user_meta( $user_id, 'apbd_reward_in', true ) );
				}
				$i_points = $i_points + $rule_points;
				$i_points = appsbd_wc_amount( $i_points );
				if ( update_user_meta( $user_id, 'apbd_reward_in', $i_points ) ) {
					$log            = Mapbd_Reward_Log::AddLog(
						$opr,
						$user_id,
						$prev_points,
						$rule_points,
						$msg,
						$ref_val,
						$ref_type
					);
					$current_points = get_user_meta( $user_id, 'apbd_reward_in', true );
					if ( empty( $current_points ) ) {
						$current_points = 0;
					}
					/**
					 * Its for check is there any change before process
					 *
					 * @since 1.0
					 */
					$badge_settings = apply_filters( 'appsbd/rwd/filters/get-badge-settings', array() );
					if ( ! empty( $badge_settings ) && 'Y' == $badge_settings['is_badge'] ) {
						$current_badge = get_user_meta( $user_id, 'apbd_reward_crnt_bg', true );
						/**
						 * Its for check is there any change before process
						 *
						 * @since 1.0
						 */
						$next_badge = apply_filters(
							'appsbd/reward/filters/get-next-badge-points',
							$current_badge,
							$current_points
						);
						if ( ! empty( $next_badge->id ) && $next_badge != $current_badge ) {
							if ( $next_badge->threshold_points <= $current_points ) {
								if ( update_user_meta( $user_id, 'apbd_reward_crnt_bg', $next_badge->id ) ) {
									if ( $next_badge->welcome_points > 0 ) {
										$new_prev_points    = self::user_prev_reward_points( $user_id );
										$current_points     = get_user_meta( $user_id, 'apbd_reward_in', true );
										$new_current_points = $current_points + $next_badge->welcome_points;
										if ( update_user_meta( $user_id, 'apbd_reward_in', $new_current_points ) ) {
											$new_log = Mapbd_Reward_Log::AddLog(
												$opr,
												$user_id,
												$new_prev_points,
												$next_badge->welcome_points,
												'By badge update',
												$next_badge->id,
												'B',
												'Y',
												$current_badge
											);
											if ( ! empty( $new_log ) ) {
												self::send_reward_email( $new_log, 'BUP' );
											}
										}
									}
								}
							}
						}
					}

					return ! empty( $log );
				}
			}
		}
	}

	/**
	 * The user reward point is generated by appsbd
	 *
	 * @param mixed $user_id Wp User Id.
	 *
	 * @return float
	 */
	public static function user_reward_point( $user_id ) {
		$points = 0.0;
		if ( metadata_exists( 'user', $user_id, 'apbd_reward_in' ) ) {
			$points = floatval( get_user_meta( $user_id, 'apbd_reward_in', true ) );
			if ( metadata_exists( 'user', $user_id, 'apbd_reward_out' ) ) {
				$points = $points - floatval( get_user_meta( $user_id, 'apbd_reward_out', true ) );
			}
		}

		return $points;
	}

	/**
	 * The user reward point is generated by appsbd
	 *
	 * @param mixed  $user_id Wp User Id.
	 *
	 * @param string $type Reward type.
	 *
	 * @return float
	 */
	public static function user_prev_reward_points( $user_id, $type = 'I' ) {
		$prev_points = 0.0;
		if ( metadata_exists( 'user', $user_id, 'apbd_reward_in' ) ) {
			$prev_points = floatval( get_user_meta( $user_id, 'apbd_reward_in', true ) );
		}
		if ( metadata_exists( 'user', $user_id, 'apbd_reward_out' ) ) {
			$prev_points = $prev_points - floatval( get_user_meta( $user_id, 'apbd_reward_out', true ) );
		}

		return appsbd_wc_amount( $prev_points );
	}
}
