<?php
/**
 * Store Credit Balance Display
 *
 * @author      StoreApps
 * @since       9.55.0
 * @version     1.2.0
 *
 * @package     woocommerce-smart-coupons/includes/
 */

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

if ( ! class_exists( 'WC_SC_Store_Credit_Balance' ) ) {

	/**
	 * Class for handling Store Credit balance display functionality
	 */
	class WC_SC_Store_Credit_Balance {

		/**
		 * Variable to hold instance of WC_SC_Store_Credit_Balance
		 *
		 * @var $instance
		 */
		private static $instance = null;

		/**
		 * Get single instance of WC_SC_Store_Credit_Balance
		 *
		 * @return WC_SC_Store_Credit_Balance Singleton object of WC_SC_Store_Credit_Balance
		 */
		public static function get_instance() {

			// Check if instance is already exists.
			if ( is_null( self::$instance ) ) {

				self::$instance = new self();
			}

			return self::$instance;
		}

		/**
		 * Constructor
		 */
		private function __construct() {
			add_action( 'init', array( $this, 'initialize' ) );
		}

		/**
		 * Handle call to functions which is not available in this class
		 *
		 * @param string $function_name The function name.
		 * @param array  $arguments Array of arguments passed while calling $function_name.
		 *
		 * @return mixed Result of function call.
		 */
		public function __call( $function_name, $arguments = array() ) {

			global $woocommerce_smart_coupon;

			if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
				return null;
			}

			if ( ! empty( $arguments ) ) {
				return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
			} else {
				return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
			}
		}

		/**
		 * Initialize the class.
		 */
		public function initialize() {
			// Clear cache when Store Credit changes.
			add_action( 'woocommerce_order_status_completed', array( $this, 'clear_user_balance_cache_on_order_complete' ) );
			add_action( 'woocommerce_order_status_processing', array( $this, 'clear_user_balance_cache_on_order_complete' ) );
			add_action( 'wc_sc_new_coupon_generated', array( $this, 'clear_user_balance_cache_on_coupon_generated' ) );
			add_action( 'woocommerce_coupon_used', array( $this, 'clear_user_balance_cache_on_coupon_used' ) );
			add_action( 'save_post', array( $this, 'clear_cache_on_coupon_save' ), 10, 2 );

			// Shortcodes.
			add_shortcode( 'wc_sc_balance', array( $this, 'store_credit_balance_shortcode' ) ); // Alternative shortcode.
			add_shortcode( 'smart_coupons_balance', array( $this, 'store_credit_balance_shortcode' ) ); // Alternative shortcode.

			// Classic Cart & Checkout: append Store Credit balance next to coupon.
			add_filter( 'woocommerce_cart_totals_coupon_html', array( $this, 'add_store_credit_balance_to_coupon_html' ), 110, 3 );

			// Block-based Cart & Checkout (Store API): register endpoint data extension.
			$this->register_store_api_extension();

			// Block-based Cart & Checkout: enqueue JS to display balance.
			add_action( 'enqueue_block_assets', array( $this, 'enqueue_block_balance_script' ) );
		}

		/**
		 * Check if Store Credit balance feature is enabled.
		 *
		 * @return bool
		 */
		protected function is_coupon_show_store_credit_balance_enabled() {
			/**
			 * Filter to enable/disable show Store Credit balance display.
			 *
			 * @since 9.66.0
			 *
			 * @param bool $show_balance Whether to show the balance feature.
			 */
			return (bool) apply_filters( 'wc_sc_coupon_show_store_credit_balance', true );
		}

		/**
		 * Get Store Credit balance data for a coupon.
		 *
		 * Returns an associative array with numeric values for:
		 * - used      => amount of Store Credit used from this coupon.
		 * - remaining => remaining Store Credit on this coupon.
		 * - total     => total Store Credit amount on this coupon.
		 *
		 * @param WC_Coupon $coupon Coupon object.
		 * @param bool      $convert Whether to convert currency (default: true for multi-currency support).
		 *
		 * @return array|false Balance data or false if balance cannot be determined.
		 */
		protected function get_store_credit_balance_for_coupon( $coupon, $convert = true ) {
			try {
				if ( ! $coupon instanceof WC_Coupon ) {
					return false;
				}

				// Only applicable for smart_coupon (Store Credit) type.
				if ( ! $coupon->is_type( 'smart_coupon' ) ) {
					return false;
				}

				if ( ! function_exists( 'WC' ) || ! isset( WC()->cart ) || ! WC()->cart instanceof WC_Cart ) {
					return false;
				}

				$smart_coupon_credit_used = WC()->cart->smart_coupon_credit_used ?? array();
				$coupon_code              = $coupon->get_code();

				if ( empty( $coupon_code ) || empty( $smart_coupon_credit_used[ $coupon_code ] ) ) {
					return false;
				}

				$used_amount_raw = (float) $smart_coupon_credit_used[ $coupon_code ];

				if ( $used_amount_raw <= 0 ) {
					return false;
				}

				// Get coupon amount with multi-currency support.
				global $woocommerce_smart_coupon;
				$coupon_amount_raw = 0;
				if ( isset( $woocommerce_smart_coupon ) && is_a( $woocommerce_smart_coupon, 'WC_Smart_Coupons' ) ) {
					// Get base amount first.
					$coupon_amount_raw = (float) $woocommerce_smart_coupon->get_amount( $coupon, false );
					// Convert to current currency if needed.
					if ( true === $convert ) {
						$coupon_amount_raw = (float) $woocommerce_smart_coupon->read_price( $coupon_amount_raw, true, null );
						// Also convert used amount to current currency.
						$used_amount_raw = (float) $woocommerce_smart_coupon->read_price( $used_amount_raw, true, null );
					}
				} else {
					// Fallback to standard method if Smart Coupons class not available.
					$coupon_amount_raw = (float) $coupon->get_amount();
				}

				if ( $coupon_amount_raw <= 0 ) {
					return false;
				}

				// Prevent negative balance due to rounding.
				$remaining = max( 0, $coupon_amount_raw - $used_amount_raw );

				$used_amount   = (float) wc_format_decimal( $used_amount_raw, wc_get_price_decimals() );
				$coupon_amount = (float) wc_format_decimal( $coupon_amount_raw, wc_get_price_decimals() );
				$remaining     = (float) wc_format_decimal( $remaining, wc_get_price_decimals() );

				return array(
					'used'      => $used_amount,
					'remaining' => $remaining,
					'total'     => $coupon_amount,
				);
			} catch ( \Throwable $e ) {
				$this->sc_block_catch_error( $e );
				return false;
			}
		}

		/**
		 * Get Store Credit balance label format.
		 *
		 * @since 9.66.0
		 *
		 * @return string Label format string.
		 */
		public function get_store_credit_balance_label() {

			/* translators: 1: remaining balance, 2: total coupon amount */
			$default_label = esc_html_x( 'Balance: %1$s/%2$s', 'store credit balance label', 'woocommerce-smart-coupons' );
			/**
			 * Filter to customize Store Credit balance label.
			 *
			 * Expected format string with two placeholders, e.g. 'Balance: %1$s/%2$s'.
			 *
			 * @since 9.66.0
			 *
			 * @param string $label_format Label format string.
			 */
			$label_format = apply_filters(
				'wc_sc_store_credit_balance_label',
				/* translators: 1: remaining balance, 2: total coupon amount */
				$default_label
			);

			return is_string( $label_format ) && '' !== $label_format ? $label_format : $default_label;
		}

		/**
		 * Append Store Credit balance information to coupon HTML on Classic Cart & Checkout.
		 *
		 * Hooked into `woocommerce_cart_totals_coupon_html`.
		 *
		 * @param string    $coupon_html          Existing coupon HTML.
		 * @param WC_Coupon $coupon               Coupon object.
		 * @param string    $discount_amount_html Discount amount HTML.
		 *
		 * @return string Modified coupon HTML.
		 */
		public function add_store_credit_balance_to_coupon_html( $coupon_html, $coupon, $discount_amount_html ) {
			try {
				if ( ! $coupon instanceof WC_Coupon || ! $coupon->is_type( 'smart_coupon' ) ) {
					return $coupon_html;
				}

				if ( ! $this->is_coupon_show_store_credit_balance_enabled() ) {
					return $coupon_html;
				}

				// Get balance with multi-currency conversion enabled.
				$balance = $this->get_store_credit_balance_for_coupon( $coupon, true );

				if ( ! $balance ) {
					return $coupon_html;
				}

				$label_format = $this->get_store_credit_balance_label();

				$balance_label = sprintf(
					/* translators: 1: remaining balance, 2: total coupon amount */
					is_string( $label_format ) && '' !== $label_format ? $label_format : esc_html_x( 'Balance: %1$s/%2$s', 'store credit balance label', 'woocommerce-smart-coupons' ),
					wc_price( $balance['remaining'] ),
					wc_price( $balance['total'] )
				);

				$balance_html = sprintf(
					'<br><span class="wc-sc-store-credit-balance">%s</span>',
					wp_kses_post( $balance_label )
				);

				return $coupon_html . $balance_html;
			} catch ( \Throwable $e ) {
				$this->sc_block_catch_error( $e );
			}

			return $coupon_html;
		}

		/**
		 * Register Store API extension to expose Store Credit balance data.
		 *
		 * @since 9.66.0
		 */
		public function register_store_api_extension() {
			if ( ! function_exists( 'woocommerce_store_api_register_endpoint_data' ) ) {
				return;
			}

			// Use CartSchema to extend cart endpoint with coupon balance data.
			if ( ! class_exists( 'Automattic\WooCommerce\StoreApi\Schemas\V1\CartSchema' ) ) {
				return;
			}

			woocommerce_store_api_register_endpoint_data(
				array(
					'endpoint'        => \Automattic\WooCommerce\StoreApi\Schemas\V1\CartSchema::IDENTIFIER,
					'namespace'       => 'wc-sc-block-store-credit-balance',
					'data_callback'   => array( $this, 'get_store_credit_balance_data' ),
					'schema_callback' => array( $this, 'get_store_credit_balance_schema' ),
					'schema_type'     => ARRAY_N,
				)
			);
		}

		/**
		 * Get Store Credit balance data for all applied coupons.
		 *
		 * @since 9.66.0
		 *
		 * @return array Balance data keyed by coupon code.
		 */
		public function get_store_credit_balance_data() {
			$data = array();

			try {
				if ( ! function_exists( 'WC' ) || ! isset( WC()->cart ) || ! WC()->cart instanceof WC_Cart || ! $this->is_coupon_show_store_credit_balance_enabled() ) {
					return $data;
				}

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

				if ( empty( $applied_coupons ) ) {
					return $data;
				}

				// Ensure cart totals are calculated to get accurate credit used data.
				// Only calculate if smart_coupon_credit_used is not already set.
				if ( ! isset( WC()->cart->smart_coupon_credit_used ) || empty( WC()->cart->smart_coupon_credit_used ) ) {
					WC()->cart->calculate_totals();
				}

				foreach ( $applied_coupons as $coupon_code ) {
					$coupon_code = sanitize_text_field( $coupon_code );

					if ( empty( $coupon_code ) ) {
						continue;
					}

					$coupon = new WC_Coupon( $coupon_code );

					if ( ! $coupon instanceof WC_Coupon || ! $coupon->is_type( 'smart_coupon' ) ) {
						continue;
					}

					// Get balance with multi-currency conversion enabled.
					$balance = $this->get_store_credit_balance_for_coupon( $coupon, true );

					if ( $balance ) {
						$formatted_used      = wc_price( $balance['used'] );
						$formatted_remaining = wc_price( $balance['remaining'] );
						$formatted_total     = wc_price( $balance['total'] );

						// Provide plain-text prices for React (no HTML).
						$plain_used      = html_entity_decode( wp_strip_all_tags( $formatted_used ), ENT_QUOTES, get_bloginfo( 'charset' ) );
						$plain_remaining = html_entity_decode( wp_strip_all_tags( $formatted_remaining ), ENT_QUOTES, get_bloginfo( 'charset' ) );
						$plain_total     = html_entity_decode( wp_strip_all_tags( $formatted_total ), ENT_QUOTES, get_bloginfo( 'charset' ) );

						$data[] = array(
							'coupon_code' => $coupon_code,
							'used'        => $balance['used'],
							'remaining'   => $balance['remaining'],
							'total'       => $balance['total'],
							'plain'       => array(
								'used'      => $plain_used,
								'remaining' => $plain_remaining,
								'total'     => $plain_total,
							),
						);
					}
				}
			} catch ( \Throwable $e ) {
				$this->sc_block_catch_error( $e );
			}

			return $data;
		}

		/**
		 * Get schema definition for Store Credit balance data.
		 *
		 * @since 9.66.0
		 *
		 * @return array Schema definition.
		 */
		public function get_store_credit_balance_schema() {
			return array(
				'type'     => 'array',
				'readonly' => true,
				'items'    => array(
					'type'       => 'object',
					'readonly'   => true,
					'properties' => array(
						'coupon_code' => array(
							'type'     => 'string',
							'readonly' => true,
						),
						'used'        => array(
							'type'     => 'number',
							'readonly' => true,
						),
						'remaining'   => array(
							'type'     => 'number',
							'readonly' => true,
						),
						'total'       => array(
							'type'     => 'number',
							'readonly' => true,
						),
						'plain'       => array(
							'type'       => 'object',
							'readonly'   => true,
							'properties' => array(
								'used'      => array( 'type' => 'string' ),
								'remaining' => array( 'type' => 'string' ),
								'total'     => array( 'type' => 'string' ),
							),
						),
					),
				),
			);
		}

		/**
		 * Enqueue JavaScript for block-based Cart & Checkout to display Store Credit balance.
		 *
		 * @since 9.66.0
		 */
		public function enqueue_block_balance_script() {
			if ( is_admin() ) {
				return;
			}

			if ( ! $this->is_coupon_show_store_credit_balance_enabled() ) {
				return;
			}

			if ( ! has_block( 'woocommerce/cart' ) && ! has_block( 'woocommerce/checkout' ) ) {
				return;
			}

			$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';

			wp_enqueue_script(
				'wc-sc-block-store-credit-balance',
				WC_SC_PLUGIN_URL . 'assets/js/blocks/store-credit-balance' . $suffix . '.js',
				array( 'wc-blocks-checkout' ),
				$this->get_version(),
				true
			);

			$label_format = $this->get_store_credit_balance_label();

			wp_localize_script(
				'wc-sc-block-store-credit-balance',
				'WC_SC_Store_Credit_Balance',
				array(
					'i18n' => array(
						'balance_label' => $label_format,
					),
				)
			);
		}

		/**
		 * Store Credit Balance Shortcode
		 *
		 * Usage: [store_credit_balance] or [sc_balance]
		 * Parameters:
		 * - format: 'amount' (default) or 'raw'
		 * - label: Custom text before balance (default: 'Store Credit: ')
		 * - class: Custom CSS class
		 * - user_id: Specific user ID (admin only)
		 * - show_label: true/false (default: true) - Whether to show the text label
		 *
		 * @param array $atts Shortcode attributes.
		 *
		 * @return string HTML output
		 */
		public function store_credit_balance_shortcode( $atts ) {
			if ( ! is_user_logged_in() ) {
				return '';
			}

			$atts = shortcode_atts(
				array(
					'format'        => 'amount',
					'label'         => __( 'Store Credit: ', 'woocommerce-smart-coupons' ),
					'class'         => 'wc-sc-balance',
					'user_id'       => null,
					'force_refresh' => false,
					'show_label'    => true,
				),
				$atts,
				'store_credit_balance'
			);

			$user_id = $atts['user_id'];

			// Security check: only admins can view other users' balances.
			if ( $user_id && get_current_user_id() !== $user_id && ! current_user_can( 'manage_woocommerce' ) ) {
				$user_id = null;
			}

			$force_refresh = wc_string_to_bool( $atts['force_refresh'] );
			$balance       = $this->get_customer_store_credit_balance( $user_id, $force_refresh );

			if ( 'raw' === $atts['format'] ) {
				return wp_kses_post( $balance );
			}

			$formatted_balance = $this->format_balance( $balance );
			$css_class         = esc_attr( $atts['class'] );
			$show_label        = wc_string_to_bool( $atts['show_label'] );
			$text              = $show_label ? esc_html( $atts['label'] ) : '';

			return wp_kses_post(
				sprintf(
					'<span class="%s">%s%s</span>',
					$css_class,
					$show_label ? '<span class="wc-sc-balance-label" style="padding-right: 5px;">' . esc_html( $atts['label'] ) . '</span>' : '',
					$formatted_balance
				)
			);
		}

		/**
		 * Get customer's total Store Credit balance using sc_endpoint_content logic
		 *
		 * @param int  $user_id User ID (optional, defaults to current user).
		 * @param bool $force_refresh Force refresh without cache.
		 *
		 * @return float Total Store Credit balance
		 */
		public function get_customer_store_credit_balance( $user_id = null, $force_refresh = false ) {
			if ( ! $user_id ) {
				$user_id = get_current_user_id();
			}

			if ( ! $user_id ) {
				return 0;
			}

			global $woocommerce_smart_coupon;

			if ( ! isset( $woocommerce_smart_coupon ) || ! is_a( $woocommerce_smart_coupon, 'WC_Smart_Coupons' ) ) {
				return 0;
			}

			try {
				$user = get_userdata( $user_id );
				if ( ! $user ) {
					return 0;
				}

				// Check cache first (unless force refresh is requested).
				$cache_key = 'wc_sc_balance_' . $user_id;
				if ( ! $force_refresh ) {
					$cached_balance = wp_cache_get( $cache_key, 'woocommerce_smart_coupons' );
					if ( false !== $cached_balance ) {
						return floatval( $cached_balance );
					}
				}

				$total_store_credit = 0;

				// Use the same logic as sc_endpoint_content function.
				$total_store_credit = $this->get_balance_using_sc_endpoint_logic( $user_id );

				// Cache the result for 30 seconds to avoid excessive queries.
				wp_cache_set( $cache_key, $total_store_credit, 'woocommerce_smart_coupons', 30 );

				return $total_store_credit;

			} catch ( \Throwable $e ) {
				$this->sc_block_catch_error( $e );
			}
		}

		/**
		 * Get customer's Store Credit balance using the same logic as sc_endpoint_content
		 *
		 * @param int $user_id User ID.
		 *
		 * @return float Total Store Credit balance
		 */
		public function get_balance_using_sc_endpoint_logic( $user_id ) {
			global $woocommerce_smart_coupon;

			if ( ! class_exists( 'WC_SC_Display_Coupons' ) ) {
				include_once WC_SC_PLUGIN_DIRPATH . 'includes/class-wc-sc-display-coupons.php';
			}
			$wc_sc_display_coupons = WC_SC_Display_Coupons::get_instance();

			if ( ! is_object( $wc_sc_display_coupons ) ) {
				return 0;
			}

			try {
				$max_coupon_to_show = absint( get_option( 'wc_sc_setting_max_coupon_to_show', 5 ) );
				$max_coupon_to_show = get_option( 'wc_sc_setting_max_coupon_to_show_on_myaccount', ( $max_coupon_to_show * 10 ) );
				$max_coupon_to_show = apply_filters( 'wc_sc_max_coupon_to_show_on_myaccount', $max_coupon_to_show, array( 'source' => $wc_sc_display_coupons ) );
				$max_coupon_to_show = absint( $max_coupon_to_show );

				$coupons = array();
				if ( $max_coupon_to_show > 0 ) {
					$coupons = ( ! in_array( $wc_sc_display_coupons->get_db_status_for( '9.8.0' ), array( 'completed', 'done' ), true ) ) ? $wc_sc_display_coupons->sc_get_available_coupons_list_old( array() ) : $wc_sc_display_coupons->sc_get_available_coupons_list( array() );
				}

				$total_store_credit = 0;
				$coupons_applied    = ( is_object( WC()->cart ) && is_callable( array( WC()->cart, 'get_applied_coupons' ) ) ) ? WC()->cart->get_applied_coupons() : array();

				foreach ( $coupons as $code ) {
					$coupon_id = ( isset( $code->id ) && ! empty( $code->id ) ) ? absint( $code->id ) : 0;

					if ( empty( $coupon_id ) ) {
						continue;
					}

					$coupon = new WC_Coupon( $coupon_id );

					if ( ! $coupon instanceof WC_Coupon || ! $wc_sc_display_coupons->is_callable( $coupon, 'get_code' ) ) {
						continue;
					}

					if ( $wc_sc_display_coupons->sc_coupon_code_exists( $coupon->get_code(), $coupons_applied ) ) {
						continue;
					}

					if ( $wc_sc_display_coupons->is_wc_gte_30() ) {
						$discount_type = $coupon->get_discount_type();
					} else {
						$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
					}

					if ( empty( $discount_type ) ) {
						continue;
					}

					$coupon_amount = $wc_sc_display_coupons->get_amount( $coupon, true );

					// Only count smart_coupon (Store Credit) types - same logic as sc_endpoint_content line 1351.
					if ( 'smart_coupon' === $discount_type ) {
						$show_as_valid = apply_filters( 'wc_sc_show_as_valid', $wc_sc_display_coupons->is_valid( $coupon ), array( 'coupon_obj' => $coupon ) );

						if ( true === $show_as_valid ) {
							$total_store_credit += $coupon_amount;
						}
					}
				}

				return $total_store_credit;

			} catch ( \Throwable $e ) {
				$this->sc_block_catch_error( $e );
			}
		}

		/**
		 * Format Store Credit balance for display
		 *
		 * @param float $balance The balance amount.
		 * @param bool  $include_currency Whether to include currency symbol.
		 *
		 * @return string Formatted balance
		 */
		public function format_balance( $balance, $include_currency = true ) {
			if ( $include_currency ) {
				return wc_price( $balance );
			}

			return wc_format_decimal( $balance, wc_get_price_decimals() );
		}

		/**
		 * Clear cache when coupon is saved/updated
		 *
		 * @param int     $post_id Post ID.
		 * @param WP_Post $post Post object.
		 */
		public function clear_cache_on_coupon_save( $post_id, $post ) {
			try {
				if ( 'shop_coupon' !== $post->post_type ) {
					return;
				}

				$coupon = new WC_Coupon( $post_id );
				if ( 'smart_coupon' !== $coupon->get_discount_type() ) {
					return;
				}

				// Clear cache for all users associated with this coupon.
				$customer_emails = $coupon->get_meta( 'customer_email' );
				if ( ! empty( $customer_emails ) ) {
					if ( is_string( $customer_emails ) ) {
						$customer_emails = maybe_unserialize( $customer_emails );
					}

					if ( is_array( $customer_emails ) ) {
						foreach ( $customer_emails as $email ) {
							$user = get_user_by( 'email', $email );
							if ( $user ) {
								$this->clear_user_balance_cache( $user->ID );
							}
						}
					}
				}
			} catch ( \Throwable $e ) {
				$this->sc_block_catch_error( $e );
			}
		}

		/**
		 * Clear balance cache for specific user
		 *
		 * @param int $user_id User ID.
		 */
		public function clear_user_balance_cache( $user_id ) {
			$cache_key = 'wc_sc_balance_' . $user_id;
			wp_cache_delete( $cache_key, 'woocommerce_smart_coupons' );
		}

		/**
		 * Clear user balance cache when order is completed (Store Credit purchased)
		 *
		 * @param int $order_id Order ID.
		 */
		public function clear_user_balance_cache_on_order_complete( $order_id ) {
			try {
				$order = wc_get_order( $order_id );
				if ( ! $order ) {
					return;
				}

				$user_id = $order->get_user_id();
				if ( $user_id ) {
					$this->clear_user_balance_cache( $user_id );
				}
			} catch ( \Throwable $e ) {
				$this->sc_block_catch_error( $e );
			}
		}

		/**
		 * Clear user balance cache when new coupon is generated
		 *
		 * @param array $args Coupon generation arguments.
		 */
		public function clear_user_balance_cache_on_coupon_generated( $args ) {
			try {
				if ( ! empty( $args['receiver_email'] ) ) {
					$user = get_user_by( 'email', $args['receiver_email'] );
					if ( $user ) {
						$this->clear_user_balance_cache( $user->ID );
					}
				}

				if ( ! empty( $args['order_id'] ) ) {
					$order = wc_get_order( $args['order_id'] );
					if ( $order && $order->get_user_id() ) {
						$this->clear_user_balance_cache( $order->get_user_id() );
					}
				}
			} catch ( \Throwable $e ) {
				$this->sc_block_catch_error( $e );
			}
		}

		/**
		 * Clear user balance cache when coupon is used.
		 *
		 * @param WC_Coupon $coupon Coupon object.
		 */
		public function clear_user_balance_cache_on_coupon_used( $coupon ) {
			try {
				if ( ! $coupon || 'smart_coupon' !== $coupon->get_discount_type() ) {
					return;
				}

				// Clear cache for current user.
				$user_id = get_current_user_id();
				if ( $user_id ) {
					$this->clear_user_balance_cache( $user_id );
				}

				// Also clear for any users associated with this coupon.
				$customer_emails = $coupon->get_meta( 'customer_email' );
				if ( ! empty( $customer_emails ) && is_array( $customer_emails ) ) {
					foreach ( $customer_emails as $email ) {
						$user = get_user_by( 'email', $email );
						if ( $user ) {
							$this->clear_user_balance_cache( $user->ID );
						}
					}
				}
			} catch ( \Throwable $e ) {
				$this->sc_block_catch_error( $e );
			}
		}
	}
}

WC_SC_Store_Credit_Balance::get_instance();
