<?php

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

class Startbutton_WC_Payment_Gateway extends WC_Payment_Gateway {
	/**
	 * API public key
	 *
	 * @var string
	 */
	private $public_key;

	/**
	 * API secret key
	 *
	 * @var string
	 */
	private $secret_key;

	/**
	 * Gateway disabled message
	 *
	 * @var string
	 */
	private $msg;

	/**
	 * Environment
	 *
	 * @var string
	 */
	private $environment;



	public function __construct() {
		$this->id                 = 'startbutton';
		$this->method_title       = 'Startbutton Payment';
		$this->has_fields         = true;

		$this->supports = array(
			'products',
		);

		// Load the form fields
		$this->init_form_fields();

		// Load the settings
		$this->init_settings();

		// Get setting values
		$this->title              = $this->get_option( 'title', 'Startbutton' );
		$this->description        = $this->get_option( 'description', 'Pay securely using Startbutton Payment Gateway' );
		$this->enabled            = $this->get_option( 'enabled', 'no' );
    $this->environment        = $this->get_option('environment', 'test');
    $this->secret_key 		    = $this->get_option('secret_key', '');
    $this->public_key 		    = $this->get_option('public_key', '');

		$this->method_description = sprintf(
			'Go boundaryless with Startbutton Payment Gateway, access local and international customers with diverse payment methods. %s for an account, and get your API key.' 
      , '<a href="'. STARTBUTTON_WC_SITE_URL .'" target="_blank">Sign up</a>',
    );

		// Hooks
		add_action( 'wp_enqueue_scripts', array( $this, 'payment_scripts' ) );

		add_action( 'admin_notices', array( $this, 'admin_notices' ) );

    // Save admin options when updated.
    add_action(
        'woocommerce_update_options_payment_gateways_' . $this->id, 
        array($this, 'process_admin_options')
    );

		add_action( 'woocommerce_receipt_' . $this->id, array( $this, 'receipt_page' ) );

		// Payment listener/API hook.
		add_action( 'woocommerce_api_wc_gateway_startbutton', array( $this, 'update_startbutton_transaction' ) );

		// Webhook listener/API hook.
		add_action( 'woocommerce_api_wc_startbutton_webhook', array( $this, 'process_webhooks' ) );

		// Currency switcher AJAX handlers
		add_action( 'wp_ajax_startbutton_refresh_exchange_rates', array( $this, 'ajax_refresh_exchange_rates' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );

		// Frontend currency switcher hooks
		add_action( 'wp_footer', array( $this, 'render_currency_switcher' ) );
		add_action( 'wp_ajax_startbutton_switch_currency', array( $this, 'ajax_switch_currency' ) );
		add_action( 'wp_ajax_nopriv_startbutton_switch_currency', array( $this, 'ajax_switch_currency' ) );
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_scripts' ) );
		
		// Force cart fragment refresh when currency changes
		add_action( 'startbutton_currency_changed', array( $this, 'force_cart_fragment_refresh' ) );
		
		// Price conversion hooks (using current WooCommerce hooks)
		add_filter( 'woocommerce_product_get_price', array( $this, 'convert_product_price' ), 10, 2 );
		add_filter( 'woocommerce_product_get_regular_price', array( $this, 'convert_product_price' ), 10, 2 );
		add_filter( 'woocommerce_product_get_sale_price', array( $this, 'convert_product_price' ), 10, 2 );

		add_filter( 'woocommerce_get_price_html', array( $this, 'convert_price_html' ), 10, 2 );

		add_filter( 'woocommerce_cart_item_price', array( $this, 'convert_cart_item_price' ), 10, 3 );
		add_filter( 'woocommerce_cart_subtotal', array( $this, 'convert_cart_subtotal' ), 10, 3 );
		add_filter( 'woocommerce_cart_total', array( $this, 'convert_cart_total' ), 10, 1 );
		add_filter( 'woocommerce_cart_item_subtotal', array( $this, 'convert_cart_item_subtotal' ), 10, 3 );
		
		// WooCommerce Store API price range conversion - hook into the REST API response
		add_filter( 'rest_post_dispatch', array( $this, 'convert_store_api_response' ), 10, 3 );

		// Check if the gateway can be used.
		if ( ! $this->is_valid_for_use() ) {
			$this->enabled = false;
		}
	}


	/**
	 * Check if this gateway is enabled and available in the user's country.
	 */
	public function is_valid_for_use() {

		if ( ! in_array( get_woocommerce_currency(), apply_filters( 'startbutton_wc_supported_currencies', array( 'NGN', 'GHS', 'KES', 'ZAR', 'USD', 'TZS', 'RWF', 'UGX', 'XOF', 'XAF', 'ZMW' ) ) ) ) {

			$this->msg = sprintf( 
                'Startbutton does not support your store currency. Kindly set it to either NGN (&#8358), GHS (&#x20b5;), USD (&#36;), KES (KSh), RWF (R₣), ZAR (R), XOF (FCFA), XAF (CM), UGX (USh), ZMW (ZK), or TZS (TSh) %s', 
                '<a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=general' )) . '">here</a>'
			);
			return false;
		}

		return true;
	}

	/**
	 * Display startbutton payment icon.
	 */
	public function get_icon() {
		$icon_url = plugins_url( 'assets/images/logo.png', STARTBUTTON_WC_FILE );
    $icon_element = '<img src="' . esc_url($icon_url) . '" alt="Startbutton Payment" style="width:34px; height:auto; margin-right:8px; margin-left: 0; vertical-align:middle;">';
		return apply_filters( 'woocommerce_gateway_icon', $icon_element, $this->id );
	}

	/**
	 * Check if Startbutton merchant details is filled.
	 */
	public function admin_notices() {

		if ( $this->enabled == 'no' ) {
			return;
		}

		// Check required fields.
		if ( $this->public_key == '' || $this->secret_key == '' ) {
        echo '<div class="error"><p>' . sprintf(
            'Please enter your Startbutton api details <a href="%s">here</a> to be able to use the Startbutton WooCommerce plugin.', 
            esc_url(admin_url( 'admin.php?page=wc-settings&tab=checkout&section=startbutton' ))
            ) . '</p></div>';
        return;
		}

	}

	/**
	 * Check if Startbutton gateway is enabled.
	 *
	 * @return bool
	 */
	public function is_available() {

		if ( 'yes' == $this->enabled ) {

			if ( ! ( $this->public_key && $this->secret_key ) ) {

				return false;

			}

			return true;

		}

		return false;

	}

	/**
	 * Admin Panel Options.
	 */
	public function admin_options() {

		?>

		<h2><?php echo 'Startbutton'; ?>
		<?php
		if ( function_exists( 'wc_back_link' ) ) {
			wc_back_link( 'Return to payments', esc_url(admin_url( 'admin.php?page=wc-settings&tab=checkout' ) ));
		}
		?>
		</h2>

		<?php

		if ( $this->is_valid_for_use() ) {

			echo '<table class="form-table">';
			$this->generate_settings_html();
			echo '</table>';

		} else {
			?>
			<div class="inline error"><p><strong>Startbutton Payment Gateway Disabled</strong>: <?php echo esc_html($this->msg); ?></p></div>

			<?php
		}

	}

    // Define the admin form fields.
	public function init_form_fields() {

		$form_fields = array(
			'enabled'         => array(
				'title'       => 'Enable/Disable',
				'label'       =>  'Enable Startbutton',
				'type'        => 'checkbox',
				'description' =>  'Enable Startbutton as a payment option on the checkout page.' ,
				'default'     => 'no',
				'desc_tip'    => true,
			),
			'title'           => array(
				'title'       => 'Title',
				'type'        => 'text',
				'description' =>  'This controls the payment method title which the user sees during checkout.' ,
				'default'     =>  'Startbutton Payment',
				'desc_tip'    => true,
			),
      'environment' => array(
				'title'       => 'Environment',
				'type'        => 'select',
				'description' =>  'Set the development environment. Default is `Sandbox`',
				'default'     => 'test',
				'desc_tip'    => false,
				'options'     => array(
					'test'  =>  'Sandbox' ,
					'prod' =>  'Production' ,
				),
      ),
      'secret_key' => array(
          'title' => 'Secret Key',
          'type' => 'password',
          'description' => 'Enter the secret key provided by Startbutton.',
          'default' => '',
      ),
      'public_key' => array(
          'title' => 'Public Key',
          'type' => 'text',
          'description' => 'Enter the public key provided by Startbutton.',
          'default' => '',
      ),
      // Currency Switcher Settings Section
      'currency_switcher_section' => array(
          'title' => 'Currency Switcher Settings',
          'type' => 'title',
          'description' => 'Configure multi-currency support for your store.',
      ),
      'enable_currency_switcher' => array(
          'title' => 'Enable Currency Switcher',
          'type' => 'checkbox',
          'label' => 'Allow customers to switch currencies',
          'description' => 'Enable multi-currency support for your store.',
          'default' => 'no',
          'desc_tip' => true,
      ),
      'exchange_rates_section' => array(
          'title' => 'Exchange Rates',
          'type' => 'title',
          'description' => 'Current exchange rates from Startbutton FX API. Click "Refresh Rates" to update.',
          'class' => 'currency-switcher-field',
      ),
      'refresh_exchange_rates' => array(
          'title' => 'Refresh Exchange Rates',
          'type' => 'button',
          'description' => 'Fetch latest exchange rates from Startbutton FX API.',
          'default' => 'Refresh Rates',
          'class' => 'currency-switcher-field',
      ),
      'exchange_rates_display' => array(
          'title' => 'Current Exchange Rates',
          'type' => 'exchange_rates_table',
          'description' => 'Display of current exchange rates.',
          'class' => 'currency-switcher-field',
      )
		);

		$this->form_fields = $form_fields;

	}


	/**
	 * Generate button field HTML
	 */
	public function generate_button_html($key, $data) {
		$field_key = $this->get_field_key($key);
		$default = isset($data['default']) ? $data['default'] : 'Button';
		
		ob_start();
		?>
		<tr valign="top">
			<th scope="row" class="titledesc">
				<label for="<?php echo esc_attr($field_key); ?>"><?php echo esc_html($data['title']); ?></label>
			</th>
			<td class="forminp">
				<button type="button" id="<?php echo esc_attr($field_key); ?>" class="button button-secondary">
					<?php echo esc_html($default); ?>
				</button>
				<p class="description"><?php echo esc_html($data['description']); ?></p>
			</td>
		</tr>
		<?php
		return ob_get_clean();
	}

	/**
	 * Generate exchange rates table HTML
	 */
	public function generate_exchange_rates_table_html($key, $data) {
		$field_key = $this->get_field_key($key);
		$rates_data = $this->get_exchange_rates();
    $rates = $rates_data['rates'];
		
		ob_start();
		?>
		<tr valign="top">
			<th scope="row" class="titledesc">
				<label for="<?php echo esc_attr($field_key); ?>"><?php echo esc_html($data['title']); ?></label>
			</th>
			<td class="forminp">
				<?php if (!empty($rates)): ?>
					<table class="widefat">
						<thead>
							<tr>
								<th>Currency</th>
								<th>Rate</th>
								<th>Last Updated</th>
							</tr>
						</thead>
						<tbody>
							<?php foreach ($rates as $currency => $rate_data): ?>
							<tr>
								<td><?php echo esc_html($currency); ?></td>
								<td><?php echo esc_html($rate_data['rate']); ?></td>
								<td><?php echo esc_html($rate_data['updated']); ?></td>
							</tr>
							<?php endforeach; ?>
						</tbody>
					</table>
				<?php else: ?>
					<p>No exchange rates available. Click "Refresh Rates" to fetch from Startbutton FX API.</p>
				<?php endif; ?>
				<p class="description"><?php echo esc_html($data['description']); ?></p>
			</td>
		</tr>
		<?php
		return ob_get_clean();
	}

	/**
	 * Get exchange rates from Startbutton FX API
	 */
	private function get_exchange_rates() {
		$rates = get_option('startbutton_exchange_rates', array());
    $error_message = '';
		$base_currency = $this->get_option('base_currency', get_woocommerce_currency());
		// If no rates exist, fetch from API
    // if last update is more than 5min ago, fetch from API
		if (empty($rates) || !isset($rates['last_updated']) || time() - $rates['last_updated'] > 300) {
			$api_rates = $this->fetch_exchange_rates_from_api($base_currency);
			if (!empty($api_rates) && !isset($api_rates['error'])) {
        $rates = $api_rates;
				// error_log('api_rates: ' . print_r($api_rates, true));
			}else{
        $error_message = $api_rates['error'];
				error_log('error_message: ' . $error_message);
      }
      // update rate with current time
      if (count($rates) > 0) {
        $rates['last_updated'] = time();
      }
      update_option('startbutton_exchange_rates', $rates);
		}
		
    // delete last_updated from rates
    unset($rates['last_updated']);
		return [ 'rates' => $rates, 'error' => $error_message ];
	}

	/**
	 * Fetch exchange rates from Startbutton FX API
	 */
	private function fetch_exchange_rates_from_api($base_currency) {
    // Return error if api key is not set
    if (empty($this->public_key)){
      $error_message = 'Public key is not set';
      error_log($error_message);
      return array('error' => $error_message);
    }
		$api_url = STARTBUTTON_WC_API_URL[$this->environment] . '/transaction/exchange-rate/list?base=' . strtoupper($base_currency);
		error_log('connecting.... to ' . $api_url);
		$response = wp_remote_get($api_url, array(
			'timeout' => 30,
			'headers' => array(
				'Authorization' => 'Bearer ' . $this->public_key
			)
		));

		if (is_wp_error($response)) {
      $error_message = 'API request failed: ' . $response->get_error_message();
      error_log($error_message);
      return array('error' => $error_message);
		}

    if (wp_remote_retrieve_response_code($response) != 200) {
      $error_message = 'API request failed: ' . wp_remote_retrieve_response_message($response);
      error_log($error_message);
      return array('error' => $error_message);
    }
		
		$body = wp_remote_retrieve_body($response);
		$rates_data = json_decode($body, true);

    // Check if response is valid and has success status
    if (!is_array($rates_data) || !isset($rates_data['success']) || !$rates_data['success']) {
        error_log('rates_data: ' . print_r($rates_data, true));
        error_log('Invalid API response or unsuccessful request');
        return array('error' => 'Invalid API response or unsuccessful request');
    }
        
    // Access the data array from the response
    $rates_array = isset($rates_data['data']) ? $rates_data['data'] : array();

    if (!is_array($rates_array)) {
        error_log('No data array in API response');
        return array('error' => 'No data array in API response');
    }

		$rates = array();
		foreach ($rates_array as $rate_item) {
			if (isset($rate_item['currency']) && isset($rate_item['rate'])) {
        // skip rate with value 0
        if ($rate_item['rate'] == 0) {
          continue;
        }
				$rates[$rate_item['currency']] = array(
					'rate' => $rate_item['rate'],
          'updated' => current_time('Y-m-d H:i:s')
				);
			}
		}

    $rates['last_updated'] = time();
		return $rates;
	}

	/**
	 * Payment form on checkout page
	 */
	public function payment_fields() {
		if ( $this->description ) {
			echo esc_html( $this->description );
		}
	}

	/**
	 * Outputs scripts used for startbutton payment.
	 */
	public function payment_scripts() {

		if ( isset( $_GET['pay_for_order'] ) || ! is_checkout_pay_page() ) {
			return;
		}

		if ( $this->enabled === 'no' ) {
			return;
		}

		$order_key = isset($_GET['key']) ? urldecode(sanitize_text_field(wp_unslash($_GET['key']))) : '';
		
		$order_id  = absint( get_query_var( 'order-pay' ) );

    if (!$order_id) {
        return;
    }

		$order = wc_get_order( $order_id );

		if ( $this->id !== $order->get_payment_method() ) {
			return;
		}
		wp_enqueue_script( 'startbutton', plugins_url( 'assets/js/sb-web-sdk.min.js', STARTBUTTON_WC_FILE ), array( 'jquery' ), STARTBUTTON_WC_VERSION, false );
		// https://checkout.startbutton.tech/dev/sb-web-sdk.min.js
		// wp_enqueue_script( 'startbutton', 'https://checkout.startbutton.tech/version/latest/sb-web-sdk.min.js', array( 'jquery' ), STARTBUTTON_WC_VERSION, false );
		wp_enqueue_script( 'wc_startbutton', plugins_url( 'assets/js/startbutton.js', STARTBUTTON_WC_FILE ), array( 'jquery', 'startbutton' ), STARTBUTTON_WC_VERSION, false );
		

		$startbutton_params = [
			'key' => $this->public_key,
      'env' => $this->environment,
			'nonce' => wp_create_nonce( 'startbutton_payment' ),
    ];

    $email         = $order->get_billing_email();
    $current_currency = $this->get_current_currency();
    $base_currency = get_woocommerce_currency();
    $amount = $order->get_total() * 100;
    $currency = $order->get_currency();
    
    // Use converted amount and currency if different from base currency and currency switcher is enabled
    if ($current_currency !== $base_currency && $this->get_option( 'enable_currency_switcher' ) === 'yes') {
        $order->set_currency($current_currency);
        $order->save();
        $currency = $current_currency;
        
    }
    $the_order_id  = $order->get_id();
    $the_order_key = $order->get_order_key();
    $currency_symbol = get_woocommerce_currency_symbol($currency);

    if ( $the_order_id == $order_id && $the_order_key == $order_key ) {
        $startbutton_params['email']    = $email;
        $startbutton_params['amount']   = $amount;
        $startbutton_params['currency'] = $currency;
        $startbutton_params['symbol'] = $currency_symbol;
    }

    $startbutton_params['order_id'] = $the_order_id;
    $startbutton_params['name'] = $order->get_billing_first_name() . ' ' . $order->get_billing_last_name();
    $startbutton_params['email'] = $email;
    $startbutton_params['phone'] = $order->get_billing_phone();

    $billing_address = $order->get_formatted_billing_address();
    $billing_address = esc_html( preg_replace( '#<br\s*/?>#i', ', ', $billing_address ) );
    $startbutton_params['billing_address'] = $billing_address;

    $shipping_address = $order->get_formatted_shipping_address();
    $shipping_address = esc_html( preg_replace( '#<br\s*/?>#i', ', ', $shipping_address ) );
    if ( empty( $shipping_address ) ) {
        $shipping_address = $billing_address;
    }
    $startbutton_params['shipping_address'] = $shipping_address;
    $startbutton_params['api_url'] = WC()->api_request_url( 'WC_Gateway_Startbutton' );

		wp_localize_script( 'wc_startbutton', 'wc_startbutton_params', $startbutton_params );
	}

	/**
	 * Process the payment.
	 *
	 * @param int $order_id
	 *
	 * @return array|void
	 */
	public function process_payment( $order_id ) {
		$order = wc_get_order( $order_id );

		return array(
			'result'   => 'success',
			'redirect' => $order->get_checkout_payment_url( true ),
		);
	}

	/**
	 * Displays the payment page.
	 *
	 * @param $order_id
	 */
	public function receipt_page( $order_id ) {

		$order = wc_get_order( $order_id );

		echo '<div id="wc-startbutton-form">';
		echo '<div id="startbutton_form"><form id="order_review" method="post" action="' . esc_url( WC()->api_request_url( 'WC_Gateway_Startbutton' ) ) . '"></form><button class="button disabled" id="startbutton-payment-button">' . 'Pay Now' . '</button>';
    echo '&nbsp;<a class="button disabled cancel" id="startbutton-cancel-payment-button" href="' . esc_url( $order->get_cancel_order_url() ) . '">Cancel</a></div>';
		echo '</div>';

	}

	/**
	 * Get Startbutton payment icon URL.
	 */
	public function get_logo_url() {
		$icon_url = plugins_url( 'assets/images/logo.png', STARTBUTTON_WC_FILE ); // Replace with your icon URL.
		$url = WC_HTTPS::force_https_url( $icon_url );
		return apply_filters( 'startbutton_wc_gateway_icon_url', $url, $this->id );
	}

	/**
	 * Process Webhook.
	 */
	public function process_webhooks() {

		$request_method = isset($_SERVER['REQUEST_METHOD']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_METHOD'])) : '';

		if ( ! array_key_exists( 'HTTP_X_STARTBUTTON_SIGNATURE', $_SERVER ) || ( strtoupper( $request_method ) !== 'POST' ) ) {

      wp_send_json_error("Error Authentication", 401);
      return;
		}

		$json = file_get_contents( 'php://input' );
		if ( $_SERVER['HTTP_X_STARTBUTTON_SIGNATURE'] !== hash_hmac( 'sha512', $json, $this->secret_key ) ) {

      wp_send_json_error("Error Authentication", 401);
			return;
		}

		$event = json_decode( $json );
    $status = $event->data->transaction->status;
    if ($status != 'verified' && $status != 'successful' && $status != 'failed'){
        wp_send_json_success("Webhook still processing", 200);
        return;
    }

    $reference = $event->data->transaction->transactionReference;

    if (empty($reference)) {
        wp_send_json_error("Invalid Request", 400);
        return;
    }

    $amount = $event->data->transaction->amount;
    $currency = $event->data->transaction->currency;

    $orders = wc_get_orders( 
        array(
            'meta_key'      => '_startbutton_tx_ref', 
            'meta_value'    => $reference, 
            'meta_compare'  => '=', 
            'return'        => 'ids' 
        )
    );

    $order_id = $orders[0];

    if (!$order_id) {
        wp_send_json_error('no id found');
        wp_send_json_error("Invalid Request. Order not found", 400);
        return;
    }

		$order = wc_get_order( $order_id );

		if ( ! $order ) {
			return;
		}
        
    // Aready processed
		if ( in_array( strtolower( $order->get_status() ), array( 'completed', 'on-hold', 'failed' ), true ) ) {
            
      wp_send_json_success("Order already processed", 200);
			return;
		}

		$order_currency = $order->get_currency();
		$currency_symbol = get_woocommerce_currency_symbol( $order_currency );

		$order_total = $order->get_total();
		$amount_paid = $amount / 100;
		
		// Log payment details for debugging
		error_log( "Webhook payment details - Order ID: {$order_id}, Order Currency: {$order_currency}, Order Total: {$order_total}, Payment Amount: {$amount_paid}, Payment Currency: {$currency}" );

		$payment_currency = strtoupper( $currency );
		$gateway_symbol = get_woocommerce_currency_symbol( $payment_currency );

    if ($status == 'failed' || $status == 'abandoned') {
        $order->update_status( 'failed', 'Payment verification failed.' );
        $notice = sprintf( 
            'Thank you for shopping with us.%1$sYour payment transaction %2s could not be verified.', 
            '<br />',
            $reference,
        );
        $notice_type = 'notice';

        // Add Customer Order Note.
        $order->add_order_note( $notice, 1 );

        // Add Admin Order Note.
        $admin_order_note = sprintf( 
            '<strong>Order Failure</strong>%1$sThis order has failed.%2$sStartbutton Transaction Reference:</strong> %3$s',
            '<br />', '<br />', $reference 
        );

        $order->add_order_note( $admin_order_note );
        $order->save();
        wp_send_json_success("Order processed successfully", 200);
        return;
    }
    
    // check if the amount paid is less than order amount
    if ( $amount_paid < $order_total ) {

        $order->update_status( 'on-hold', 'Payment amount doesn\'t tally. Investigation needed.' );
        $notice      = sprintf( 'Thank you for shopping with us.%1$sYour payment transaction was successful, but the amount paid doesn\'t match the total order amount.%2$sYour order is currently on hold.%3$sKindly contact us for more information regarding your order and payment status.', '<br />', '<br />', '<br />' );
        $notice_type = 'notice';

        // Add Customer Order Note.
        $order->add_order_note( $notice, 1 );

        // Add Admin Order Note.
        $admin_order_note = sprintf( 
            '<strong>Look into this order</strong>%1$sThis order is currently on hold.%2$sReason: Amount paid doesn\'t match the total order amount.%3$sAmount Paid was <strong>%4$s (%5$s)</strong> while the total order amount is <strong>%6$s (%7$s)</strong>%8$s<strong>Startbutton Transaction Reference:</strong> %9$s', 
            '<br />', '<br />', '<br />', 
            $currency_symbol, 
            $amount_paid, 
            $currency_symbol, 
            $order_total, '<br />',
            $reference 
        );

        $order->add_order_note( $admin_order_note );

        function_exists( 'wc_reduce_stock_levels' ) ? wc_reduce_stock_levels( $order_id ) : $order->reduce_order_stock();

        wc_add_notice( $notice, $notice_type );
        $order->save();
        
        wp_send_json_success("Order processed successfully with amount mismatch.", 200);
        return;

    }        

    if ( $payment_currency !== $order_currency ) {

        $order->update_status( 'on-hold', '' );
        $notice      = sprintf( 'Thank you for shopping with us.%1$sYour payment was successful, but the payment currency is different from the order currency.%2$sYour order is currently on-hold.%3$sKindly contact us for more information regarding your order and payment status.', 
        '<br />', '<br />', '<br />' );
        $notice_type = 'notice';

        // Add Customer Order Note.
        $order->add_order_note( $notice, 1 );

        // Add Admin Order Note.
        $admin_order_note = sprintf( 
            '<strong>Look into this order</strong>%1$sThis order is currently on hold.%2$sReason: Order currency is different from the payment currency.%3$sOrder Currency is <strong>%4$s (%5$s)</strong> while the payment currency is <strong>%6$s (%7$s)</strong>%8$s<strong>Startbutton Transaction Reference:</strong> %9$s', 
            '<br />', '<br />', '<br />', 
            $order_currency, 
            $currency_symbol, 
            $payment_currency, 
            $gateway_symbol, 
            '<br />', 
            $reference 
        );
        $order->add_order_note( $admin_order_note );

        function_exists( 'wc_reduce_stock_levels' ) ? wc_reduce_stock_levels( $order_id ) : $order->reduce_order_stock();

        wc_add_notice( $notice, $notice_type );
        $order->save();
        
        wp_send_json_success("Order processed successfully with currency mismatch.", 200);
        return;

    } 

    $order->set_transaction_id( $reference );
    $order->payment_complete( $reference );
    $order->add_order_note( sprintf( 
        'Payment via Startbutton successful (Transaction Reference: %s)',
        $reference
    ) );
    
    $order->update_status( 'completed' );
    $order->save();

    wp_send_json_success("Order processed successfully", 200);
    return;
	}

	/**
	 * Update Startbutton payment.
	 */
	public function update_startbutton_transaction() {
    error_log('=== STARTBUTTON TRANSACTION UPDATE STARTED ===');
    
    // Update request parameters - support both POST and GET requests
    $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : (isset( $_GET['order_id'] ) ? absint( $_GET['order_id'] ) : 0);
    $tx_ref   = isset( $_POST['startbutton_tx_ref'] ) ? sanitize_text_field( wp_unslash($_POST['startbutton_tx_ref'] )) : (isset( $_GET['startbutton_tx_ref'] ) ? sanitize_text_field( wp_unslash($_GET['startbutton_tx_ref'] )) : '');
    $tx_id    = isset( $_POST['startbutton_tx_id'] ) ? sanitize_text_field( wp_unslash($_POST['startbutton_tx_id'] )) : (isset( $_GET['startbutton_tx_id'] ) ? sanitize_text_field( wp_unslash($_GET['startbutton_tx_id'] )) : '');
    $nonce    = isset( $_POST['startbutton_nonce'] ) ? sanitize_text_field( wp_unslash($_POST['startbutton_nonce'] )) : (isset( $_GET['startbutton_nonce'] ) ? sanitize_text_field( wp_unslash($_GET['startbutton_nonce'] )) : '');

    error_log('Order ID: ' . $order_id);
    error_log('Transaction Ref: ' . $tx_ref);
    error_log('Transaction ID: ' . $tx_id);
    error_log('Request method: ' . $_SERVER['REQUEST_METHOD']);

    if ( ! $order_id || empty( $tx_ref ) || empty ( $tx_id ) || empty( $nonce )) {
        error_log('ERROR: Missing required parameters');
        wp_safe_redirect( wc_get_page_permalink( 'cart' ) );
        exit;
    }

    // Verify nonce before proceeding
    if ( ! wp_verify_nonce( $nonce, 'startbutton_payment' ) ) {
      wp_die( 'Security check failed.', 'woocommerce', 'Authorization Error', array( 'response' => 403 ) );
    }

    // Get the order object
    $order = wc_get_order( $order_id );
    if ( ! $order ) {
      wp_safe_redirect( wc_get_page_permalink( 'cart' ) );
      exit;
    }

    // Save the txRef to order metadata
    $order->update_meta_data( '_startbutton_tx_ref', $tx_ref );
    $order->update_meta_data( '_startbutton_tx_id', $tx_id );
    $order->update_status( 'processing', 'Payment is undergoing verification in the background' );
    WC()->cart->empty_cart();
    $order->save();

    wp_safe_redirect( $this->get_return_url( $order ) );
    exit;
	}

	/**
	 * AJAX handler for refreshing exchange rates
	 */
	public function ajax_refresh_exchange_rates() {
    // error_log('ajax_refresh_exchange_rates...??');
		check_ajax_referer( 'startbutton_admin_nonce', 'nonce' );
    // error_log('ajax_refresh_exchange_rates...2');
		if ( ! current_user_can( 'manage_woocommerce' ) ) {
			wp_die();
		}

    $rates_data = $this->get_exchange_rates();
    $rates = $rates_data['rates'];
    $error_message = $rates_data['error'];

		if ( ! empty( $rates ) && empty( $error_message ) ) {
			wp_send_json_success( array(
				'message' => 'Exchange rates updated successfully',
				'rates' => $rates
			) );
		} else {
			wp_send_json_error( $error_message );
		}
	}

	/**
	 * Enqueue admin scripts for currency switcher
	 */
	public function enqueue_admin_scripts( $hook ) {
		// Only load on WooCommerce settings pages
		if ( strpos( $hook, 'wc-settings' ) === false ) {
			return;
		}
		
		// Only load for Startbutton gateway settings
		if ( isset( $_GET['section'] ) && $_GET['section'] !== 'startbutton' ) {
			return;
		}
		
		wp_enqueue_script( 'startbutton-admin', STARTBUTTON_WC_URL . '/assets/js/admin.js', array( 'jquery' ), STARTBUTTON_WC_VERSION, true );
		wp_localize_script( 'startbutton-admin', 'startbutton_admin', array(
			'ajax_url' => admin_url( 'admin-ajax.php' ),
			'nonce' => wp_create_nonce( 'startbutton_admin_nonce' )
		) );
	}

	/**
	 * Enqueue frontend scripts for currency switcher
	 */
	public function enqueue_frontend_scripts() {
		// Only load if currency switcher is enabled
		if ( $this->get_option( 'enable_currency_switcher' ) !== 'yes' ) {
			return;
		}
    // error_log('FrontendCurrency switcher is enabled......-x-');

    // rates list exists in get_option('startbutton_exchange_rates')
    $rates = get_option('startbutton_exchange_rates');
    if (empty($rates)) {
      return;
    }

    // disable switcher when order init and set in session
		$order_id  = absint( get_query_var( 'order-pay' ) );
    if ($order_id) {
        return;
    }

    wp_enqueue_style( 'startbutton_currency_switcher', STARTBUTTON_WC_URL . '/assets/css/currency-switcher.css', array(), STARTBUTTON_WC_VERSION, false );
    wp_enqueue_script( 'startbutton_currency_switcher', STARTBUTTON_WC_URL . '/assets/js/currency-switcher.js', array( 'jquery' ), STARTBUTTON_WC_VERSION, false );
		wp_localize_script( 'startbutton_currency_switcher', 'startbutton_currency', array(
			'ajax_url' => admin_url( 'admin-ajax.php' ),
			'nonce' => wp_create_nonce( 'startbutton_currency_nonce' )
		) );
	}

	/**
	 * Render currency switcher in footer
	 */
	public function render_currency_switcher() {
		// Only render if currency switcher is enabled and
		if ( $this->get_option( 'enable_currency_switcher' ) !== 'yes' ) {
			return;
		}
    // disable switcher when order init and set in session
		$order_id  = absint( get_query_var( 'order-pay' ) );
    if ($order_id) {
        return;
    }
		// Include the template
		include_once plugin_dir_path( STARTBUTTON_WC_FILE ) . 'templates/currency-switcher.php';
	}

	/**
	 * Get available currencies for the switcher (dynamic from FX API)
	 */
	public function get_available_currencies() {
		$base_currency = get_woocommerce_currency();
		$rates_data = $this->get_exchange_rates();
    $rates = $rates_data['rates'];
		
		// Start with base currency
		$currencies = array(
			$base_currency => $this->get_currency_display_name($base_currency)
		);
		
		// Add currencies from FX rates
		if (!empty($rates)) {
			foreach ($rates as $currency_code => $rate_data) {
				if ($currency_code !== $base_currency) {
					$currencies[$currency_code] = $this->get_currency_display_name($currency_code);
				}
			}
		}
		
		// Fallback to static list if no FX rates available
		if (count($currencies) <= 1) {
			$currencies = apply_filters( 'startbutton_wc_supported_currencies', array(
				'USD' => 'US Dollar',
				'EUR' => 'Euro',
				'GBP' => 'British Pound',
				'NGN' => 'Nigerian Naira',
				'GHS' => 'Ghanaian Cedi',
				'KES' => 'Kenyan Shilling',
				'ZAR' => 'South African Rand',
				'TZS' => 'Tanzanian Shilling',
				'RWF' => 'Rwandan Franc',
				'UGX' => 'Ugandan Shilling',
				'XOF' => 'West African CFA Franc',
				'XAF' => 'Central African CFA Franc',
				'ZMW' => 'Zambian Kwacha',
			) );
		}
		
		return $currencies;
	}

	/**
	 * Get currency display name (static version to avoid recursion)
	 */
	private function get_currency_display_name_static( $currency_code ) {
		$currency_names = array(
			'USD' => 'US Dollar',
			'EUR' => 'Euro',
			'GBP' => 'British Pound',
			'NGN' => 'Nigerian Naira',
			'GHS' => 'Ghanaian Cedi',
			'KES' => 'Kenyan Shilling',
			'ZAR' => 'South African Rand',
			'TZS' => 'Tanzanian Shilling',
			'RWF' => 'Rwandan Franc',
			'UGX' => 'Ugandan Shilling',
			'XOF' => 'West African CFA Franc',
			'XAF' => 'Central African CFA Franc',
			'ZMW' => 'Zambian Kwacha',
		);
		
		return isset( $currency_names[ $currency_code ] ) ? $currency_names[ $currency_code ] : $currency_code;
	}

	/**
	 * Get currency display name (public method that uses available currencies)
	 */
	public function get_currency_display_name( $currency_code ) {
		$rates_data = $this->get_exchange_rates();
    $rates = $rates_data['rates'];
		if ( isset( $rates[ $currency_code ] ) && empty( $error_message ) ) {
      $currency_name = $this->get_currency_display_name_static( $currency_code );
      return $currency_name;
		}
		return [];
	}

	/**
	 * Get currency symbol
	 */
	public function get_currency_symbol( $currency_code ) {
		return get_woocommerce_currency_symbol( $currency_code );
	}

	/**
	 * Get last FX update time
	 */
	public function get_last_fx_update_time() {
		$rates_data = $this->get_exchange_rates();
    $rates = $rates_data['rates'];

		if ( ! empty( $rates ) && empty( $error_message ) ) {
			$first_rate = reset( $rates );
			return isset( $first_rate['updated'] ) ? $first_rate['updated'] : '';
		}
		return '';
	}

	/**
	 * Get switch currency post data
	 */
	public function get_switch_currency_post_data( $currency_code ) {
		return array(
			'currency' => $currency_code,
			'nonce' => wp_create_nonce( 'startbutton_switch_currency_' . $currency_code ),
			'return_url' => wc_get_page_permalink( 'shop' )
		);
	}

	/**
	 * AJAX handler for switching currency (session-based)
	 */
	public function ajax_switch_currency() {
		check_ajax_referer( 'startbutton_currency_nonce', 'nonce' );
		
		$currency = sanitize_text_field( $_POST['currency'] ?? '' );
		
		if ( empty( $currency ) ) {
			wp_send_json_error( 'Invalid currency code' );
		}

		// Verify currency is supported
		$supported_currencies = array_keys( $this->get_available_currencies() );
		if ( ! in_array( $currency, $supported_currencies ) ) {
			wp_send_json_error( 'Currency not supported' );
		}

		// Store selected currency in session
		if ( ! session_id() ) {
			@session_start();
		}
		$_SESSION['startbutton_selected_currency'] = $currency;
		
		// Clear any cached cart fragments to force refresh
		if ( class_exists( 'WC_Cache_Helper' ) ) {
			$cart_version = WC_Cache_Helper::get_transient_version( 'cart' );
			if ( $cart_version ) {
				wp_cache_set( 'cart_version', $cart_version + 1, 'woocommerce' );
			}
		}
		
		// Trigger cart fragment refresh
		do_action( 'woocommerce_cart_updated' );
		
		// Return success with currency data
		wp_send_json_success( array(
			'symbol' => $this->get_currency_symbol( $currency ),
			'code' => $currency,
			'name' => $this->get_currency_display_name( $currency )
		) );
	}

	/**
	 * Force cart fragment refresh when currency changes
	 */
	public function force_cart_fragment_refresh() {
		// Clear cart fragments cache
		if ( class_exists( 'WC_Cache_Helper' ) ) {
			$cart_version = WC_Cache_Helper::get_transient_version( 'cart' );
			if ( $cart_version ) {
				wp_cache_set( 'cart_version', $cart_version + 1, 'woocommerce' );
			}
		}
		
		// Trigger cart update
		if ( WC()->cart ) {
			WC()->cart->calculate_totals();
		}
		
		// Trigger fragment refresh
		do_action( 'woocommerce_cart_updated' );
	}

	/**
	 * Get current session currency or fallback to base currency
	 */
	public function get_current_currency() {
    // error_log('get_current_currency...');
		if ( ! session_id() ) {
			@session_start();
		}
		
		$session_currency = $_SESSION['startbutton_selected_currency'] ?? null;
		$base_currency = get_woocommerce_currency();
		
		// Verify session currency is still supported
		if ( $session_currency ) {
			$supported_currencies = array_keys( $this->get_available_currencies() );
			if ( in_array( $session_currency, $supported_currencies ) ) {
				return $session_currency;
			}
		}
		
		return $base_currency;
	}

	/**
	 * Convert price using exchange rates
	 */
	public function convert_price( $price, $from_currency = null, $to_currency = null ) {
		
		// Validate price is numeric and not empty
		if ( ! is_numeric( $price ) || $price === '' || $price === null ) {
			return $price;
		}
		
		if ( $from_currency === null ) {
			$from_currency = get_woocommerce_currency();
		}
		if ( $to_currency === null ) {
			$to_currency = $this->get_current_currency();
		}
		
		// If same currency, no conversion needed
		if ( $from_currency === $to_currency ) {
			return $price;
		}
		
		$rates_data = $this->get_exchange_rates();
    $rates = $rates_data['rates'];
		
		// Check if we have the required rate
		if ( isset( $rates[$to_currency] ) ) {
			// error_log('rates[$to_currency]: ' . print_r($rates[$to_currency], true));
      // rate from API is typically the base currency to 1 unit of the target currency
			$rate = isset( $rates[$to_currency]['rate'] ) ? 1/$rates[$to_currency]['rate'] : 0;
			// The new rate is how much of the target currency you get for 1 unit of base currency
			// So we multiply the price by the rate directly
			$converted_price = $price * $rate;
			 error_log('Converted...');
			// error_log('Converted price calculation: ' . $price . ' * ' . $rate . ' = ' . $converted_price);
      // merchant protection, round up to the nearest decimal point
      $converted_price = ceil($converted_price * 100) / 100;
			return $converted_price;
		}
		
		// Fallback: return original price if no rate available
		return $price;
	}

	/**
	 * Convert product price
	 */
	public function convert_product_price( $price, $product ) {
		if ( ! $price || $price === '' ) {
			return $price;
		}
		
		$current_currency = $this->get_current_currency();
		$base_currency = get_woocommerce_currency();
		
		if ( $current_currency === $base_currency ) {
			return $price;
		}
		
		$converted_price = $this->convert_price( $price );
    // error_log('converted_price...' . $converted_price);
		return $converted_price;
	}

	/**
	 * Convert price HTML - Updated to handle discounts properly
	 */
	public function convert_price_html( $price_html, $product ) {
		$current_currency = $this->get_current_currency();
		$base_currency = get_woocommerce_currency();
		
		if ( $current_currency === $base_currency ) {
			return $price_html;
		}
		
		$regular_price = $product->get_regular_price();
		$sale_price = $product->get_sale_price();
		$current_price = $product->get_price();
		
		// Validate prices before conversion
		if ( ! is_numeric( $regular_price ) || $regular_price === '' || $regular_price === null ) {
			$regular_price = 0;
		}
		if ( ! is_numeric( $sale_price ) || $sale_price === '' || $sale_price === null ) {
			$sale_price = 0;
		}
		if ( ! is_numeric( $current_price ) || $current_price === '' || $current_price === null ) {
			$current_price = 0;
		}
		
		// Format prices with new currency
		$formatted_regular_price = wc_price( $regular_price, array( 'currency' => $current_currency ) );
		$formatted_sale_price = wc_price( $sale_price, array( 'currency' => $current_currency ) );
		$formatted_current_price = wc_price( $current_price, array( 'currency' => $current_currency ) );
		
		// Replace original prices in HTML
		if ( $sale_price && $sale_price !== $regular_price ) {
			// Product is on sale - replace both regular and sale prices
			$price_html = str_replace( wc_price( $regular_price ), $formatted_regular_price, $price_html );
			$price_html = str_replace( wc_price( $sale_price ), $formatted_sale_price, $price_html );
		} else {
			// Product is not on sale - replace current price only
			$price_html = str_replace( wc_price( $current_price ), $formatted_current_price, $price_html );
		}
		
		return $price_html;
	}

	/**
	 * Convert cart item price
	 */
	public function convert_cart_item_price( $price, $cart_item, $cart_item_key ) {
    $price = wc_price( $this->extract_price_from_html($price), array( 'currency' => $this->get_current_currency() ) );
    return $price;
	}

	/**
	 * Convert cart item subtotal
	 */
	public function convert_cart_item_subtotal( $subtotal, $cart_item, $cart_item_key ) {
    $current_currency = $this->get_current_currency();
    $base_currency = get_woocommerce_currency();
		if ( $current_currency === $base_currency ) {
			return $subtotal;
		}

    $subtotal = wc_price( $this->extract_price_from_html($subtotal), array( 'currency' => $this->get_current_currency() ) );
    return $subtotal;
	}

	/**
	 * Convert cart subtotal
	 */
	public function convert_cart_subtotal( $subtotal, $compound, $cart ) {
    // error_log('convert_cart_subtotal...' . $subtotal);
		$current_currency = $this->get_current_currency();

    // error_log('..$subtotal: ' . $subtotal);
    // sum up the converted prices
    $converted_subtotal = 0;
		foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
			$product = $cart_item['data'];
			$product_price = $product->get_price();
			$quantity = $cart_item['quantity'];
      $converted_subtotal += $product_price * $quantity;
		}
		// Extract numeric value from subtotal string
    $numeric_subtotal = $converted_subtotal;
		return wc_price( $numeric_subtotal, array( 'currency' => $current_currency ) );
	}

	/**
	 * Convert cart total
	 */
	public function convert_cart_total( $total ) {
    // error_log('...convert_cart_total: ' . $total);
		$current_currency = $this->get_current_currency();
		$base_currency = get_woocommerce_currency();
		if ( $current_currency === $base_currency ) {
			return $total;
    }

    // use global cart object to estimate total
    $converted_total = 0;
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
      $product = $cart_item['data'];
      $product_price = $product->get_price();
      $quantity = $cart_item['quantity'];
      $converted_total += $product_price * $quantity;
    }
		
    return wc_price( $converted_total, array( 'currency' => $current_currency ) );
	}

  /**
   * Extract price from HTML
   */
  public function extract_price_from_html($price_html) {
      // Handle empty or null input
      if ( empty( $price_html ) || $price_html === null ) {
          return 0;
      }
      
      // Convert HTML entities first
      $decoded_html = html_entity_decode($price_html, ENT_QUOTES, 'UTF-8');
      
      // Extract only numbers, decimal points, and commas
      $numeric_price = preg_replace('/[^0-9.,]/', '', $decoded_html);
      
      // Handle case where no numeric value was found
      if ( empty( $numeric_price ) ) {
          return 0;
      }
      
      // Remove commas and convert to float
      $price = (float) str_replace(',', '', $numeric_price);
      
      // Ensure we return a valid number
      return is_numeric( $price ) ? $price : 0;
  }

	/**
	 * Convert price filter widget amounts (min/max prices)
	 */
	public function convert_price_filter_amount( $amount ) {
    // error_log('...convert_price_filter_amount: ' . $amount);
		$current_currency = $this->get_current_currency();
		$base_currency = get_woocommerce_currency();
		
		if ( $current_currency === $base_currency ) {
			return $amount;
		}
		
		// Validate amount before conversion
		if ( ! is_numeric( $amount ) || $amount === '' || $amount === null ) {
			return $amount;
		}
		
		$converted_amount = $this->convert_price( $amount );
		
		// Round to nearest whole number for better UX in price filters
		return round( $converted_amount );
	}

	/**
	 * Intercept WooCommerce Store API response to convert price range data.
	 */
	public function convert_store_api_response( $response, $server, $request ) {
		// Check if this is the WooCommerce Store API collection-data endpoint
		$route = $request->get_route();
		if ( $route && strpos( $route, '/wc/store/v1/products/collection-data' ) !== false ) {
			$data = $response->get_data();
			error_log('convert_store_api_response: ' . json_encode($data));
			// Convert price range data if it exists
			if ( isset( $data['price_range'] ) && is_object( $data['price_range'] ) ) {
				if ( isset( $data['price_range']->min_price ) ) {
					$data['price_range']->min_price = $this->convert_price_filter_amount( $data['price_range']->min_price );
				}
				if ( isset( $data['price_range']->max_price ) ) {
					$data['price_range']->max_price = $this->convert_price_filter_amount( $data['price_range']->max_price );
				}
			}
			
			$response->set_data( $data );
		}
		
		return $response;
	}

}
