<?php
/**
 * Plugin Name: Bankful
 * Plugin URI: https://bankful.com/integrations-woocommerce/
 * Description: Accept credit card payments, bankful hosted payments page and supports WooCommerce subscriptions on your store.
 * Version: 3.0.4
 * Author: Bankful
 * Author URI: https://bankful.com/
 * Developer: Bankful
 * Developer URI: https://bankful.com/
 * Requires Plugins: woocommerce
 * Text Domain: bankful
 *
 * WC requires at least: 7.0
 * WC tested up to: 9.1.4
 *
 * License: GNU General Public License v3.0
 * License URI: http://www.gnu.org/licenses/gpl-3.0.html
 */

if (!defined('ABSPATH')) { // To check absolute path
	exit;
}

// Define constants for plugin version and dependencies
define('BANKFUL_VERSION', '3.0.4');
define('WC_MIN_REQUIRED_VERSION', '1.0.0');

/**
 * Verify hash signature from request parameters.
 *
 * @param array|mixed $params Request parameters containing SIGNATURE key.
 * @return bool True if signature is valid, false otherwise.
 */
function verifyHashSignatureFromRequest( $params ) {
	// Bail early if params is not an array or missing the required SIGNATURE key.
	if ( ! is_array( $params ) || ! isset( $params['SIGNATURE'] ) ) {
		return false;
	}

	// Retrieve the stored hash salt used for HMAC verification.
	$bf_hash_salt = get_option('bankful_options_hash_salt');
	if ( empty( $bf_hash_salt ) ) {
		return false;
	}

	// Generate a hash from the incoming params and compare against the provided signature.
	$signatureGenerated = generateSignatureHash($params, $bf_hash_salt);

	return hash_equals( $signatureGenerated, $params['SIGNATURE'] );
}

/**
 * Generate signature hash from data array.
 *
 * @param array|mixed $data Data array to hash.
 * @param string      $salt Salt for hashing.
 * @return string Hash signature, empty string on failure.
 */
function generateSignatureHash( $data, $salt ) {
	// Validate inputs: data must be an array, salt must be a non-empty string.
	if ( ! is_array( $data ) || empty( $salt ) || ! is_string( $salt ) ) {
		return '';
	}

	// Keys excluded from signature computation.
	$notInclude = array( 'SIGNATURE', 'RECURRING_SCHEDULE_ID' );

	$strField = '';

	// Filter out excluded keys and sort remaining keys alphabetically for deterministic hashing.
	$paramData = array_filter(array_keys($data), function ( $key ) use ( $notInclude ) {
		return !in_array($key, $notInclude);
	});

	sort($paramData);

	// Build a concatenated string of key-value pairs for hashing.
	foreach ($paramData as $paramName) {
		$paramValue = $data[$paramName];
		if (is_array($paramValue) || is_object($paramValue)) {
			$strField .= $paramName . wp_json_encode($paramValue);
		} elseif (is_string($paramValue) || is_numeric($paramValue) || is_bool($paramValue)) {
			if (is_string($paramValue) && '' !== $paramValue) {
				$strField .= $paramName . $paramValue;
			} elseif (!is_string($paramValue)) {
				$strField .= $paramName . $paramValue;
			}
		} elseif ('' !== $paramValue) {
			$strField .= $paramName . $paramValue;
		}
	}

	// Compute HMAC-SHA256 hash of the concatenated fields using the provided salt.
	$generatedSignature = hash_hmac('sha256', $strField, $salt);

	return $generatedSignature;
}

/**
 * Check if the current connection is secure.
 *
 * Relies on WordPress is_ssl() which uses server variables set by the web server
 * and cannot be spoofed by client-injected headers.
 *
 * If running behind a reverse proxy (AWS ALB, nginx, Cloudflare, etc.), add the
 * following to wp-config.php so that is_ssl() returns true:
 *
 *   if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
 *       $_SERVER['HTTPS'] = 'on';
 *   }
 *
 * @return bool True if the connection is secure.
 */
function bankful_is_secure_connection() {
	return is_ssl();
}

// Load shared security checks trait for gateway classes.
require_once dirname( __FILE__ ) . '/includes/trait-bankful-security-checks.php';

// Load all Classes and actions / filters.
add_action('plugins_loaded', 'Bf_Init_Gateway_classes');
add_action('plugins_loaded', 'init_subscription_core_for_bankful', 0);

// Global Variables
$WP_SITE_URL = get_site_url();
$BF_PLUGIN_SOURCE = 'woo_market';
$LIVE_API_SRV = 'https://api.paybybankful.com/';
$SANDBOX_API_SRV = $LIVE_API_SRV;

/**
 * The class itself, please note that it is inside plugins_loaded action hook
 *
 */
function Bf_Init_Gateway_classes() {

	// Load the dependency manager class
	require_once __DIR__ . '/includes/class-wc-bankful-dependency-manager.php';

	// Initialize the dependency manager
	$dependency_manager = new WC_Bankful_Dependency_Manager( WC_MIN_REQUIRED_VERSION );

	// If dependencies are not valid, prevent plugin from loading further
	if ( ! $dependency_manager->are_dependencies_valid() ) {
		// Show admin notice
		add_action( 'admin_notices', array( $dependency_manager, 'show_dependency_admin_notice' ) );
		
		// Deactivate the plugin to prevent it from being activated
		deactivate_plugins( plugin_basename( __FILE__ ) );
		
		// Prevent further execution of this file
		return;
	}

	// Check class WP_Payment_Gateway exist or not
	if (!class_exists('WC_Payment_Gateway')) {
		return;
	}

	if (class_exists('WC_Bankful_WS_Gateway') || class_exists('WC_Gateway_Bankful')) {
		add_action('admin_notices', 'bankful_gateway_exists_error');
		return;
	}

	// Credit Card Gateway with Woo Subscriptions
	require_once plugin_dir_path(__FILE__) . 'includes/class-wc-bankful-ws-gateway.php';

	// Hosted Page Bankful Gateway
	require_once plugin_dir_path(__FILE__) . '/includes/bankful-webhook-controller.php';
	require_once plugin_dir_path(__FILE__) . '/includes/class-wc-bankful-hosted-gateway.php';
	require_once plugin_dir_path(__FILE__) . '/includes/blocks/class-wc-bankful-payments-blocks.php';
	require_once plugin_dir_path(__FILE__) . '/includes/blocks/class-wc-bankful-ws-payments-blocks.php';
	// Actions and Filters
	add_action('admin_menu', 'add_bankful_menus', 1000);

	add_action('admin_enqueue_scripts', 'enqueue_styles_scripts_bankful');
	add_action('wp_enqueue_scripts', 'front_enqueue_styles_bankful');
	add_action('wp_ajax_sync_subscription_products', 'sync_subscription_products');

	add_action('wp_ajax_migrate_subscription_products', 'migrate_subscription_products');

	add_filter('woocommerce_payment_gateways', 'Bf_Add_Gateway_classes');

	add_action('woocommerce_blocks_loaded', 'woocommerce_gateway_bankful_woocommerce_block_support');
	add_filter('http_request_timeout', 'wp_timeout_extend_fb_one');
	add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'plugin_action_links_bankful');
	add_filter('plugin_row_meta', 'bankful_add_plugin_meta_links', 10, 2);
	
	add_action( 'woocommerce_scheduled_subscription_payment', 'gateway_scheduled_subscription_payment', 10, 1 );
}


/**
 * Display a non-dismissible admin error notice on WooCommerce-related pages.
 */
function bankful_add_admin_error_notice() {
	// Only show on WooCommerce and Bankful admin pages.
	$screen = get_current_screen();
	if ( $screen && strpos( $screen->id, 'woocommerce' ) === false && strpos( $screen->id, 'bankful' ) === false ) {
		return;
	}

	$options = get_option('bankful_options');
	$available_gateways = WC()->payment_gateways()->get_available_payment_gateways();
	$allowed = array(
		'strong' => array(),
		'a'      => array(
			'href'   => array(),
		),
	);

	// Check if the site is running on an insecure (non-HTTPS) connection.
	if ( ! bankful_is_secure_connection() ) {
		$message = sprintf(
			// translators: $1: opening <strong> tag, $2: closing </strong> tag, $3: opening <a> tag , $4: closing </a> tag
			esc_html__( '%1$sBankful requires a secure (HTTPS) connection.%2$s Your site is currently using an insecure HTTP connection. Payment processing has been disabled to protect your customers. Please install an SSL certificate and update your site URL to use HTTPS. %3$sLearn more about SSL setup.%4$s', 'bankful' ),
			'<strong>', '</strong>',
			'<a href="https://bankful.com/integrations-woocommerce/">', '</a>'
		);

		?>
		<div class="notice notice-error">
			<p><?php echo wp_kses( $message, $allowed ); ?></p>
		</div>
		<?php
		return;
	}

	if (!isset($available_gateways['bankful_hosted_gateway']) && !isset($available_gateways['bankful_credit_card'])) {
		$message = sprintf(
			// translators: $1: opening <strong> tag, $2: closing </strong> tag, $3: opening <a> tag , $4: closing </a> tag, $5: opening <a> tag , $6: closing </a> tag
			esc_html__( '%1$sBankful is not connected/configured.%2$s The %3$sMerchant API Credentials%4$s are required for Bankful to function. Please add API keys to create %5$sconnection with Bankful here.%6$s', 'bankful' ),
			'<strong>', '</strong>',
			'<a href="https://bankful.com/integrations-woocommerce/">', '</a>',
			'<a href="' . admin_url('admin.php?page=bankful_settings') . '">', '</a>'
		);
		
		?>
		<div class="notice notice-error">
			<p><?php echo ( wp_kses($message, $allowed) ); ?></p>
		</div>
		<?php

	} else if (isset($options['bankful_field_environment']) && 'Test' == $options['bankful_field_environment']) {
		$message = sprintf(
			// translators: $1: opening <strong> tag, $2: closing </strong> tag, $3: opening <a> tag , $4: closing </a> tag, $5: opening <a> tag , $6: closing </a> tag, $8: opening <a> tag , $9: closing </a> tag
			esc_html__( '%1$sBankful is in %5$sTEST mode%6$s.%2$s Current %3$sEnvironment%4$s is set to test transactions flow, Customers will not be charged in this TEST/Sandbox Environment. Please set LIVE Environment to charge customers %5$swith Bankful here.%6$s %7$sYou can contact %8$sBankful Support anytime for help.%9$s', 'bankful' ),
			'<strong>', '</strong>',
			'<a href="https://bankful.com/integrations-woocommerce/">', '</a>',
			'<a href="' . admin_url('admin.php?page=bankful_settings') . '">', '</a>',
			'<br>',
			'<a href="https://bankful.com/contact-us/">', '</a>'
		);
		?>
		<div class="notice notice-info" style="border-left-color: #695AE3;">
			<p><?php echo ( wp_kses($message, $allowed) ); ?></p>
		</div>
		<?php
	}
}

if (!function_exists('init_subscription_core_for_bankful')) {
	function init_subscription_core_for_bankful() {
		$options = get_option( 'bankful_options' );
		if ( isset($options['bankful_field_enable_subscription']) && 'enable' === strtolower($options['bankful_field_enable_subscription']) && !class_exists( 'WC_Subscriptions' )) {
			require plugin_dir_path( __FILE__ ) . 'includes/vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-core-plugin.php';
			new WC_Subscriptions_Core_Plugin();
		}
	}
}

function bankful_add_plugin_meta_links( $links, $file ) {
	// Make sure this is only applied to the Bankful plugin
	if (plugin_basename(__FILE__) === $file) {
		if (isset($links[2])) {
			unset($links[2]);
		}
		$settings_link = '<a href="' . admin_url('admin.php?page=bankful_settings') . '">' . __('Settings', 'bankful') . '</a>';
		$bankful_link = '<a target="_blank" href="https://bankful.com/integrations-woocommerce/">' . __('View Details', 'bankful') . '</a>';
		// Add the settings link
		$links[] = $settings_link;
		$links[] = $bankful_link;
	}

	return $links;
}

/**
 * Fire a gateway specific hook for when a subscription payment is due.
 *
 * @since 1.0
 */
function gateway_scheduled_subscription_payment( $subscription_id ) {
	if ( ! is_object( $subscription_id ) ) {
		$subscription = wcs_get_subscription( $subscription_id );
	} else {
		$subscription = $subscription_id;
	}
	if ( false === $subscription ) {
		// translators: %d: subscription ID.
		throw new InvalidArgumentException( sprintf( esc_html( 'Subscription doesn\'t exist in scheduled action: %d', 'woocommerce-subscriptions' ), esc_html($subscription_id) ) );
	}

	if ( ! $subscription->is_manual() && ! $subscription->has_status( wcs_get_subscription_ended_statuses() ) ) {
		trigger_bankful_gateway_renewal_payment_hook( $subscription->get_last_order( 'all', 'renewal' ) );
	}
}

/**
 * Fire a gateway specific hook for when a subscription renewal payment is due.
 *
 * @param WC_Order $renewal_order The renewal order to trigger the payment gateway hook for.
 * @since 2.1.0
 */
function trigger_bankful_gateway_renewal_payment_hook( $renewal_order ) {
	if ( ! empty( $renewal_order ) && $renewal_order->get_total() > 0 && $renewal_order->get_payment_method() === 'bankful_credit_card' ) {

		// Make sure gateways are setup
		WC()->payment_gateways();

		/**
		 * Do Bankful Specific Scheduled Payment Action Hook
		 * 
		 * @since 3.0.0
		 * @param string Order total amount 
		 * @param WC_Order $renewal_order  The renewal order to trigger the payment gateway hook for.
		 */
		do_action( 'woocommerce_scheduled_subscription_payment_bankful_credit_card', $renewal_order->get_total(), $renewal_order );
	} else if ( ! empty( $renewal_order ) && $renewal_order->get_total() > 0 && $renewal_order->get_payment_method() === 'bankful_hosted_gateway' ) {

		// Make sure gateways are setup
		WC()->payment_gateways();

		/**
		 * Do Bankful Specific Scheduled Payment Action Hook
		 * 
		 * @since 3.0.0
		 * @param string Order total amount 
		 * @param WC_Order $renewal_order  The renewal order to trigger the payment gateway hook for.
		 */
		do_action( 'woocommerce_scheduled_subscription_payment_bankful_hosted_gateway', $renewal_order->get_total(), $renewal_order );
	}
}

/**
 * Plugin url.
 *
 * @return string
 */
function plugin_url() {
	return untrailingslashit(plugins_url('/', __FILE__));
}

/**
 * Plugin url.
 *
 * @return string
 */
function plugin_abspath() {
	return trailingslashit(plugin_dir_path(__FILE__));
}

/**
 * Registers WooCommerce Blocks integration.
 *
 */
function woocommerce_gateway_bankful_woocommerce_block_support() {
	$options = get_option('bankful_options');
	if (isset($options['bankful_field_live_validated_account_cc']) && 'yes' == $options['bankful_field_live_validated_account_cc']) {
		if (class_exists('Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType')) {
			add_action(
				'woocommerce_blocks_payment_method_type_registration',
				function ( Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry ) {
					$payment_method_registry->register(new WC_Bankful_WS_Gateway_Blocks_Support());
				}
			);
		}
	}
	if (isset($options['bankful_field_live_validated_account_hg']) && 'yes' == $options['bankful_field_live_validated_account_hg']) {
		if (class_exists('Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType')) {
			add_action(
				'woocommerce_blocks_payment_method_type_registration',
				function ( Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry ) {
					$payment_method_registry->register(new WC_Gateway_Bankful_Blocks_Support());
				}
			);
		}
	}
}

/**
 * Enqueue custom CSS and scripts for Bankful Gateway Frontend
 *
 */
function front_enqueue_styles_bankful() {
	wp_register_style('bankful_front_screens', plugin_dir_url(__FILE__) . 'assets/css/bf-style.css', false, '3.0.4');
	wp_enqueue_style('bankful_front_screens');
}


/**
 * Add links to plugins page for checkout settings
 *
 * @param  array $links
 * @return array
 */
function plugin_action_links_bankful( $links = array() ) {

	$options = get_option('bankful_options');
	$plugin_links = array( '<a href="' . admin_url('admin.php?page=bankful_settings') . '">' . __('Settings', 'bankful') . '</a>' );

	( isset($options['bankful_field_live_validated_account_cc']) && 'yes' == $options['bankful_field_live_validated_account_cc'] ) ?
		$plugin_links[] = '<a href="' . admin_url('admin.php?page=wc-settings&tab=checkout&section=bankful_credit_card') . '">' . __('Credit Card', 'bankful') . '</a>' : '';
	( isset($options['bankful_field_live_validated_account_hg']) && 'yes' == $options['bankful_field_live_validated_account_hg'] ) ?
		$plugin_links[] = '<a href="' . admin_url('admin.php?page=wc-settings&tab=checkout&section=bankful_hosted_gateway') . '">' . __('Bankful Hosted', 'bankful') . '</a>' : '';

	return array_merge($plugin_links, $links);
}

/**
 * This function is used to log on globally for bankful plugin
 *
 * @param string $message message to log
 *
 * @param string $level log level like info/debug
 */
function write_logs_bf( $message = '', $level = 'info' ) {
	$logger = wc_get_logger();

	$logger->log($level, wc_print_r($message, true), array( 'source' => 'bankful_payment_gateway' ));
}

/**
 * This action hook registers notice that bankful gateway plugin already active
 *
 * @param string $gateways SDK/API method name
 *
 * @return string error message
 */
function bankful_gateway_exists_error() {
	$return_error = '<div class="notice error is-dismissible" >';
	$return_error .= '<p>' . esc_html_e('Another Bankful Gateway already activated, please deactivate other Bankful or Bankful Hosted Gateway. Thanks.', 'bankful') . '</p>';
	$return_error .= '</div>';
	return $return_error;
}

/**
 * This action hook registers our PHP class as a WooCommerce payment gateway
 *
 * @param string $gateways SDK/API method name
 *
 * @return object  $this
 */
function Bf_Add_Gateway_classes( $gateways ) {
	$options = get_option('bankful_options');

	( isset($options['bankful_field_live_validated_account_cc']) && 'yes' == $options['bankful_field_live_validated_account_cc'] ) ?
		$gateways[] = 'WC_Bankful_WS_Gateway' : '';
	( isset($options['bankful_field_live_validated_account_hg']) && 'yes' == $options['bankful_field_live_validated_account_hg'] ) ?
		$gateways[] = 'WC_Gateway_Bankful' : '';

	add_action('admin_notices', 'bankful_add_admin_error_notice');
	return $gateways;
}

/**
 * Process the payment and return the result.
 *
 * @param datetime $time Order ID.
 *
 * @return array
 */
function wp_timeout_extend_fb_one( $time ) {
	// Default timeout is 5
	return 30;
}

/**
 * Add Bankful Menus to Admin Menus
 *
 */
function add_bankful_menus() {
	add_submenu_page(
		'woocommerce',
		'Bankful',
		'Bankful',
		'manage_woocommerce',
		'bankful_settings',
		'bankful_options_page_html'
	);
}

/**
 * Top level menu callback function for bankful_options_page_html
 */
function bankful_options_page_html() {
	global $LIVE_API_SRV;

	if (!current_user_can('manage_woocommerce')) {
		return;
	}

	// check if the user have submitted the settings
	// WordPress will add the "settings-updated" $_GET parameter to the url
	if (isset($_GET['settings-updated'])) {
		// add settings saved message with the class of "updated"
		add_settings_error('bankful_messages', 'bankful_message', __('Settings Saved', 'bankful'), 'updated');
	}

	$options = get_option('bankful_options');

	// show error/update messages
	settings_errors('bankful_messages');
	?>
	<div class="wrap">
		<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
		<form action="options.php" method="post" name="bankful_settings">
			<?php
			// output security fields for the registered setting "bankful"
			settings_fields('bankful');
			// output setting sections and their fields
			// (sections are registered for "bankful", each field is registered to a specific section)
			do_settings_sections('bankful');
			wp_nonce_field( 'bf-creds-nonce', '_bfcrednonce' );
			?>
			<input type="button" name="submitValidate" id="submitValidate" class="button" value="Save Settings">
			<p>
			<?php
				echo( ( isset($options['bankful_field_live_validated_account_cc']) && 'yes' == $options['bankful_field_live_validated_account_cc'] ) ?
				'<a style="margin-right: 10px;" type="button" name="redirectToCC" id="redirectToCC" class="button" href="' . esc_url(admin_url('admin.php?page=wc-settings&tab=checkout&section=bankful_credit_card')) . '">Credit Card Settings</a>' : '' );
				echo( ( isset($options['bankful_field_live_validated_account_hg']) && 'yes' == $options['bankful_field_live_validated_account_hg'] ) ?
				'<a type="button" name="redirectToHP" id="redirectToHP" class="button" href="' . esc_url(admin_url('admin.php?page=wc-settings&tab=checkout&section=bankful_hosted_gateway')) . '">Hosted Page Settings</a>' : '' );
				echo '</p><p><input type="button" name="syncSubsProducts" id="syncSubsProducts" class="button" value="Sync Subscription Products"/></p><p>';
				echo '</p><p><input type="button" name="migrateSubsProducts" id="migrateSubsProducts" class="button" value="Migrate Recurring Products"/></p><p>';
				// output save settings button
				submit_button( 'Save Settings', 'hidden' );
			?>
			</p>
		</form>
	</div>
	<script>
		jQuery('#syncSubsProducts').on('click', function(event) {
			jQuery.ajax({
				type: 'post',
				url: ajaxurl,
				data : {action: "sync_subscription_products"},
				success: function(response) {
					// console.log(response);
					const data = response['data'];
					if(data){
						alert("Products Updated: " + data['updatedProducts'] + '. New Created Products: ' + data['createdProducts']);
					}else{
						alert("Request Failed");
					}
				}
			});
		});

		jQuery('#migrateSubsProducts').on('click', function(event) {
			jQuery.ajax({
				type: 'post',
				url: ajaxurl,
				data : {action: "migrate_subscription_products"},
				success: function(response) {
					// console.log(response);
					const data = response['updatedCount'];
					alert("Products Updated: " + data + '.');
				}
			});
		});

		jQuery('#submitValidate').on('click', async function(event) {
		
			const live_username = jQuery("#bankful_field_live_username").val();
			const live_password = jQuery("#bankful_field_live_password").val();

			const validated_live_username = `${live_username.substr(0, 2)}*****${live_username.substr(live_username.length - 8)}`;

			const environment = jQuery("#bankful_field_environment").val();

			const current_site_url = '<?php echo esc_url(get_site_url()); ?>';

			const request_url_live = '<?php echo esc_url($LIVE_API_SRV); ?>';
			const _bfcrednonce = jQuery("#_bfcrednonce").val();

			var jsonObj =  { "req_username" : live_username, "req_password" : live_password , "site_url" : current_site_url, '_bfcrednonce' : _bfcrednonce };

			let live_saved = false;
			if (live_username && live_password) {
				await jQuery.ajax({
					url: ajaxurl,
					type: "post",
					dataType: "json",
					data: {
						action: 'validate_bankful_merchant',
						postdata: jsonObj
					},
					success: function(response) {
						if ('success' === response.status) {
							const data = response.data;
							// console.log('data ====> ', data);
							jQuery("#bankful_field_live_validate").val(validated_live_username);
							jQuery("#bankful_field_live_validated_account_hg").val(data.isHostedPageEnabled === "Y" ? 'yes' : "no");
							jQuery("#bankful_field_live_validated_account_cc").val(data.isNativeEnabled === "Y" ? 'yes' : "no");
							jQuery("#bankful_field_live_subscription_status").val(data.isSubscriptionEnabled === "Y" ? 'yes' : "no");
							jQuery("#bankful_field_enable_subscription").val((jQuery("#bankful_field_enable_subscription").val() === "Enable" && data.isSubscriptionEnabled === "Y") ? "Enable" : "Disable");
							jQuery(".description.bankful_field_live_password").html('<span style="color:green;">Validation Success.</span>');

							jQuery('#submit').trigger("click");
							
						} else {
							jQuery(".description.bankful_field_live_password").html('<span style="color:red;">Validation Failed.</span>');
							jQuery("#bankful_field_live_validate").val("");
							jQuery("#bankful_field_live_validated_account_hg").val("no");
							jQuery("#bankful_field_live_validated_account_cc").val("no");
							jQuery("#bankful_field_live_subscription_status").val("no");
							jQuery("#bankful_field_enable_subscription").val("Disable");
							alert(response.errorMessage);
							jQuery('#submit').trigger("click");
						}
					},
					error: function (jqXHR, exception) {
						// console.log('error', jqXHR.status);
						// console.log('error', jqXHR.responseText);
						var msg = '';
						if (jqXHR.status === 0) {
							msg = 'Not connect.\n Verify Network.';
						} else if (jqXHR.status == 404) {
							msg = 'Requested page not found. [404]';
						} else if (jqXHR.status == 500) {
							msg = 'Internal Server Error [500].';
						} else if (exception === 'parsererror') {
							msg = 'Requested JSON parse failed.';
						} else if (exception === 'timeout') {
							msg = 'Time out error.';
						} else if (exception === 'abort') {
							msg = 'Ajax request aborted.';
						} else {
							responseJSON = JSON.parse(jqXHR.responseText);
							msg = 'Validation Error.\n' + responseJSON.errorMessage;
						}
						jQuery(".description.bankful_field_live_password").html('<span style="color:red;">Validation Failed.</span>');
						jQuery("#bankful_field_live_validate").val("");
						jQuery("#bankful_field_live_validated_account_hg").val("no");
						jQuery("#bankful_field_live_validated_account_cc").val("no");
						jQuery("#bankful_field_live_subscription_status").val("no");
						jQuery("#bankful_field_enable_subscription").val("Disable");
						alert(msg);
						jQuery('#submit').trigger("click");
					}
				});

			} else {
				jQuery(".description.bankful_field_live_password").html('<span style="color:red;">Please enter Username and Password to use.</span>');
			}

		});

		jQuery('#LIVE_edit').on('click', function(event) {
			event.preventDefault();
			jQuery("#bankful_field_live_validate").val("");
			jQuery("#bankful_field_live_validated_account_hg").val("no");
			jQuery("#bankful_field_live_validated_account_cc").val("no");
			jQuery("#bankful_field_live_subscription_status").val("no");
			jQuery("#bankful_field_enable_subscription").val("Disable");
			jQuery('#submit').trigger("click");
		});
	</script>
<?php
}

/**
 * Redirect to WooCommerce Payment Gateway Settings Page
 *
 */
function redirect_to_gateway_bankful_cc() {
	wp_safe_redirect(admin_url('admin.php?page=wc-settings&tab=checkout&section=bankful_credit_card'));
	exit;
}

/**
 * Redirect to WooCommerce Payment Gateway Settings Page
 *
 */
function redirect_to_gateway_bankful_hg() {
	wp_safe_redirect(admin_url('admin.php?page=wc-settings&tab=checkout&section=bankful_hosted_gateway'));
	exit;
}

/**
 * Enqueue custom CSS and scripts for Bankful Gateeway admin
 *
 */
function enqueue_styles_scripts_bankful() {
	wp_register_style('bankful_admin_screens', plugin_dir_url(__FILE__) . 'assets/css/admin-bf.css', false, '3.0.4');
	wp_enqueue_style('bankful_admin_screens');
}

/**
 * Register our bankful_settings_init to the admin_init action hook.
 */
add_action('admin_init', 'bankful_settings_init');

/**
 * Bankful option and settings
 */
function bankful_settings_init() {
	// Register a new setting for "bankful" page.
	register_setting('bankful', 'bankful_options');

	$options = get_option('bankful_options');
	
	$hidden_validated_live = ( isset($options['bankful_field_live_validate']) && !empty($options['bankful_field_live_validate']) ) ? 'hidden' : '';
	$hidden_not_validated_live = ( !isset($options['bankful_field_live_validate']) || empty($options['bankful_field_live_validate']) ) ? 'hidden' : '';

	$hidden_subscription = ( isset($options['bankful_field_live_subscription_status']) && 'yes' === $options['bankful_field_live_subscription_status'] ) ? '' : 'hidden';

	// Register a new section in the "bankful" page.
	add_settings_section(
		'bankful_section_settings',
		__('API Credentials', 'bankful'),
		'bankful_section_settings_callback',
		'bankful'
	);

	// Register a new field in the "bankful_field_test_cb" section, inside the "bankful" page.
	add_settings_field(
		'bankful_field_environment',
		__('Current Environment:', 'bankful'),
		'bankful_field_dropdown',
		'bankful',
		'bankful_section_settings',
		array(
			'label_for'         => 'bankful_field_environment',
			'class'             => 'bankful_row',
			'type'              => 'text',
			'desc'              => '',
			'default'           => 'Live',
		)
	);

	// Register a new field in the "bankful_field_test_cb" section, inside the "bankful" page.
	add_settings_field(
		'bankful_field_live_validate',
		__('API Status:', 'bankful'),
		'bankful_field_test_cb',
		'bankful',
		'bankful_section_settings',
		array(
			'label_for'         => 'bankful_field_live_validate',
			'class'             => 'bankful_row disabled ' . $hidden_not_validated_live,
			'type'              => 'text',
			'desc'              => '',
			'default'           => '',
			'info'              => 'LIVE',
		)
	);

	// Register a new field in the "bankful_field_test_cb" section, inside the "bankful" page.
	add_settings_field(
		'bankful_field_live_validated_account_cc',
		__('Live API Connected Account Credit Card:', 'bankful'),
		'bankful_field_test_cb',
		'bankful',
		'bankful_section_settings',
		array(
			'label_for'         => 'bankful_field_live_validated_account_cc',
			'class'             => 'bankful_row hidden ',
			'type'              => 'text',
			'desc'              => '',
			'default'           => 'no',
		)
	);

	// Register a new field in the "bankful_field_test_cb" section, inside the "bankful" page.
	add_settings_field(
		'bankful_field_live_validated_account_hg',
		__('Live API Connected Account Hosted Gateway:', 'bankful'),
		'bankful_field_test_cb',
		'bankful',
		'bankful_section_settings',
		array(
			'label_for'         => 'bankful_field_live_validated_account_hg',
			'class'             => 'bankful_row hidden ',
			'type'              => 'text',
			'desc'              => '',
			'default'           => 'no',
		)
	);

	// Register a new field in the "bankful_field_test_cb" section, inside the "bankful" page.
	add_settings_field(
		'bankful_field_live_username',
		__('API Key', 'bankful'),
		'bankful_field_test_cb',
		'bankful',
		'bankful_section_settings',
		array(
			'label_for'         => 'bankful_field_live_username',
			'class'             => 'bankful_row ' . $hidden_validated_live,
			'type' => 'text',
			'desc' => 'Add API Key here.',
			'default' => '',
		)
	);

	// Register a new field in the "bankful_field_test_cb" section, inside the "bankful" page.
	add_settings_field(
		'bankful_field_live_password',
		__('API Secret', 'bankful'),
		'bankful_field_test_cb',
		'bankful',
		'bankful_section_settings',
		array(
			'label_for'         => 'bankful_field_live_password',
			'class'             => 'bankful_row ' . $hidden_validated_live,
			//'type' => 'password',
			'type' => 'text',
			'desc' => 'Add Secret Key here.',
			'default' => '',
		)
	);

	// Register a new field in the "bankful_field_live_subscription_status" section, inside the "bankful" page.
	add_settings_field(
		'bankful_field_live_subscription_status',
		__('Live Subscription Status', 'bankful'),
		'bankful_field_test_cb',
		'bankful',
		'bankful_section_settings',
		array(
			'label_for'         => 'bankful_field_live_subscription_status',
			'class'             => 'bankful_row hidden ',
			'type'              => 'text',
			'desc'              => '',
			'default'           => 'no',
		)
	);

	// Register a new field in the "bankful_field_test_cb" section, inside the "bankful" page.
	add_settings_field(
		'bankful_field_enable_subscription',
		__( 'Bankful Subscription Module:', 'bankful' ),
		'bankful_field_dropdown_subscription',
		'bankful',
		'bankful_section_settings',
		array(
			'label_for'         => 'bankful_field_enable_subscription',
			'class'             => 'bankful_row ' . $hidden_subscription,
			'type'              => 'text',
			'desc'              => 'Bankful Subscription Module for Bankful Payment Gateway',
			'default'           => 'Disable',
		)
	);
};

/**
 * Bankful Select Environment field callback function.
 *
 * @param array $args
 */
function bankful_field_dropdown( $args ) {
	$options = get_option('bankful_options');
	$items = array( 'Live', 'Test' );
	echo "<select id='bankful_field_environment' name='bankful_options[bankful_field_environment]'>";
	foreach ($items as $item) {
		$selected = ( is_array($options) && strtolower($options['bankful_field_environment']) == strtolower($item) ) ? 'selected="selected"' : '';
		echo "<option value='" . esc_attr($item) . "' " . esc_attr($selected) . '>' . esc_html($item) . '</option>';
	}
	?>
	</select>
<?php
}

/**
 * Bankful Select Environment field callback function.
 *
 * @param array $args
 */
function bankful_field_dropdown_subscription( $args ) {
	$options = get_option('bankful_options');
	$items = array( 'Disable', 'Enable' );
	$wc_sub = false;
	if ( is_plugin_active( 'woocommerce-subscriptions/woocommerce-subscriptions.php' ) ) {
		$wc_sub = true;
	} 
	echo "<select id='bankful_field_enable_subscription' name='bankful_options[bankful_field_enable_subscription]' " . ( $wc_sub ? 'disabled' : '' ) . '>';
	foreach ($items as $item) {
		$selected = ( is_array($options) && strtolower($options['bankful_field_enable_subscription'])==strtolower($item) ) ? 'selected="selected"' : '';
		echo "<option value='" . esc_attr($item) . "' " . esc_attr($selected) . '>' . esc_html($item) . '</option>';
	}
	echo '</select>';
	if ( $wc_sub ) {
		echo '<span>Please Disable WooCommerce Subscription Plugin to work with Bankful Subscriptions</span>';
	} 
}

function sync_subscription_products() {
	global $LIVE_API_SRV;

	$options = get_option( 'bankful_options' );
	$site_id = get_option( 'bankful_options_site_id' );
	$currency_store = get_option('woocommerce_currency');
	
	$api_endpoint = $LIVE_API_SRV . 'api/';
	$request_url = $api_endpoint . 'woocommerce-v2/sync-products';
	$request_site_id = $api_endpoint . 'woocommerce-v2/register-site';
	$req_username = $options['bankful_field_live_username'];
	$req_password = $options['bankful_field_live_password'];

	$merchant_info = array();
	if (class_exists('WC_Bankful_WS_Gateway')) {
		$class_obj = new WC_Bankful_WS_Gateway();
		$merchant_info  = $class_obj->merchant_credential_new();
	} else if (class_exists('WC_Gateway_Bankful')) {
		$class_obj = new WC_Gateway_Bankful();
		$merchant_info  = $class_obj->merchant_credential_new();
	}

	if (!isset($site_id) || empty($site_id)) {

			$args = array(
				'body' => array( 'site_url' => get_site_url(), 'site_title' => get_bloginfo('name') ),
				'headers'     => array(
					'Content-Type' => 'application/x-www-form-urlencoded',
					'Authorization' => 'Bearer ' . $merchant_info['bf_access_token'],
				),
			);

			$response = bankful_remote_post($request_site_id, $args);

			$body = wp_remote_retrieve_body($response);
			$json_response = json_decode($body);
			$data_response = $json_response->data;
			if (isset($data_response) && !empty($data_response)) {
				// write_logs_bf($data_response, 'info');
				if ($data_response->site_id) {
					// write_logs_bf($data_response->site_id, 'info');
					add_option('bankful_options_site_id', $data_response->site_id);
					update_option('bankful_options_site_id', $data_response->site_id);
				}
			}
			// write_logs_bf($body, 'info');
		
	}

	if (isset($site_id) && !empty($site_id)) {
		$products = wc_get_products( array( 'type' => array( 'simple', 'subscription', 'subscription_variation', 'variable-subscription' ), 'status' => 'publish', 'limit' => -1 ) );

		$products_array = array();
		foreach ($products as $product) {
			if (class_exists( 'WCS_ATT_Product_Schemes' ) && WCS_ATT_Product_Schemes::get_subscription_schemes( $product )) {
				$subscriptionSchemes = WCS_ATT_Product_Schemes::get_subscription_schemes( $product );
			}
			if ('simple' === $product->get_type() && !empty($subscriptionSchemes)) {
				foreach ($subscriptionSchemes as $subscriptionScheme) {
					$schemeData = $subscriptionScheme->get_data();
					$products_array[] = array(
						'id' => $product->get_ID() . '_' . $subscriptionScheme->get_key(),
						'title' => $product->get_title() . '_' . $subscriptionScheme->get_key(),
						'price' => $schemeData['price'],
						'type' => $product->get_type(),
						'image' => wp_get_attachment_url($product->get_image_id()),
						'description' => $product->get_description(),
						'date_created' => $product->get_date_created()->date('Y-m-d H:i:s'),
						'interval' => $subscriptionScheme->get_interval(),
						'period' => $subscriptionScheme->get_period(),
						'length' => $subscriptionScheme->get_length(),
					); 
				}
			} else if ('simple' !== $product->get_type()) {

				if ($product->is_type('subscription')) {
					$products_array[] = array(
						'id' => $product->get_ID(),
						'title' => $product->get_title(),
						'price' => $product->get_price(),
						'type' => $product->get_type(),
						'image' => wp_get_attachment_url($product->get_image_id()),
						'description' => $product->get_description(),
						'date_created' => $product->get_date_created()->date('Y-m-d H:i:s'),
						'interval' => WC_Subscriptions_Product::get_interval($product),
						'period' => WC_Subscriptions_Product::get_period($product),
						'length' => WC_Subscriptions_Product::get_length($product),
					);
				} elseif ($product->is_type('variable-subscription')) {
					$variation_ids = $product->get_children();
					foreach ($variation_ids as $variation_id) {
						$variation = wc_get_product($variation_id);

						$attributes = $variation->get_attributes();
						$attributes_string = '';
						foreach ($attributes as $key => $value) {
							$term = get_term_by('slug', $value, $key);
							if ($term) {
								$attributes_string .= ' - ' . $term->name;
							} else {
								$attributes_string .= ' - ' . ucfirst($value);
							}
						}
			
						$products_array[] = array(
							'id' => $variation->get_ID(),
							'title' => $variation->get_title() . $attributes_string,
							'price' => $variation->get_price(),
							'type' => $variation->get_type(),
							'image' => wp_get_attachment_url($variation->get_image_id()),
							'description' => $variation->get_description(),
							'date_created' => $variation->get_date_created()->date('Y-m-d H:i:s'),
							'interval' => WC_Subscriptions_Product::get_interval($variation),
							'period' => WC_Subscriptions_Product::get_period($variation),
							'length' => WC_Subscriptions_Product::get_length($variation),
						);
					}
				}

			}
		}

			
		$args = array(
			'body' => array( 'products' => $products_array, 'currency' => $currency_store, 'site_id' => $site_id ),
			'headers'     => array(
				'Content-Type' => 'application/x-www-form-urlencoded',
				'Authorization' => 'Bearer ' . $merchant_info['bf_access_token'],
			),
		);

		$response = bankful_remote_post($request_url, $args);

		$body = wp_remote_retrieve_body($response);
		$json_response = json_decode($body);
		wp_send_json( $json_response, 200, null );
		
	}
	return null;
}

function migrate_subscription_products() {
	global $LIVE_API_SRV;
	if ( ! class_exists( 'WC_Subscriptions_Product' ) ) {
		return false;
	}
	
	$options = get_option( 'bankful_options' );
	$site_id = get_option( 'bankful_options_site_id' );
	
	$api_endpoint = $LIVE_API_SRV . 'api/';

	$request_site_id = $api_endpoint . 'woocommerce-v2/register-site';
	$req_username = $options['bankful_field_live_username'];
	$req_password = $options['bankful_field_live_password'];


	$merchant_info = array();
	if (class_exists('WC_Bankful_WS_Gateway')) {
		$class_obj = new WC_Bankful_WS_Gateway();
		$merchant_info  = $class_obj->merchant_credential_new();
	} else if (class_exists('WC_Gateway_Bankful')) {
		$class_obj = new WC_Gateway_Bankful();
		$merchant_info = $class_obj->merchant_credential_new();
	}


	if (!isset($site_id) || empty($site_id)) {
		$params = array( 'site_url' => get_site_url(), 'site_title' => get_bloginfo('name') );
		$args   = array(
			'body'    => http_build_query($params),
			'headers' => array(
				'Content-Type'  => 'application/x-www-form-urlencoded',
				'Authorization' => 'Bearer ' . $merchant_info['bf_access_token'],
			),
		);

		$response = bankful_remote_post($request_site_id, $args);

		if (!is_wp_error($response)) {
			$body = wp_remote_retrieve_body($response);
			$json_response = json_decode($body);
			$data_response = $json_response->data;
			if (isset($data_response) && !empty($data_response)) {
				if ($data_response->site_id) {
					add_option('bankful_options_site_id', $data_response->site_id);
				}
			}
		}
	}
	
	$params = array(
		'type' => array( 'simple', 'subscription' ),
		'post_status' => array( 'publish' ),
		'recurring_product' => 'yes',
	);


	$updatedCount = 0;
	$products = wc_get_products($params);

	foreach ($products as $product) {
		
		$fetchObj = new stdClass();
		$fetchObj->site_id = $site_id;
		$fetchObj->product_id = $product->get_id();
		$fetchObj->cart_id = 10006;

		$args = array(
			'method'    => 'POST', 
			'body'      => wp_json_encode( $fetchObj ),
			'headers'   => array(
				'Content-Type'  => 'application/json', 
				'Authorization' => 'Bearer ' . $merchant_info['bf_access_token'],
			),
		);

		$request_url = $api_endpoint . 'handle-webhook/cart/woocommerce/verify_rulesV2';
		
		$response = bankful_remote_post($request_url, $args);

		if (!is_wp_error($response)) {
			$body = wp_remote_retrieve_body($response);
			$server_output = json_decode($body);

			$updatedCount = ++$updatedCount;
			wp_remove_object_terms( 65, 'simple', 'product_type', true );
			wp_set_object_terms( 65, 'subscription', 'product_type', true );
			
			$product->update_meta_data('_subscription_length', $server_output->expire_after);
			$product->update_meta_data('_subscription_period_interval', $server_output->frequency);
			$product->update_meta_data('_subscription_period', $server_output->rebill);
			
			$product->save();

			wp_remove_object_terms( $product->get_ID(), 'simple', 'product_type', true );
			wp_set_object_terms( $product->get_ID(), 'subscription', 'product_type', true );
		
		}
	}

	wp_send_json( array( 'updatedCount' => $updatedCount ), 200, null );
}

/**
 * Bankful field callback function.
 *
 * @param array $args
 */
function bankful_field_test_cb( $args ) {
	// Get the value of the setting we've registered with register_setting()
	$options = get_option('bankful_options');
	?>
	<input id="<?php echo esc_attr($args['label_for']); ?>" name="bankful_options[<?php echo esc_attr($args['label_for']); ?>]" value="<?php echo isset($options[$args['label_for']]) ? esc_attr($options[$args['label_for']]) : esc_attr($args['default']); ?>" type="<?php echo esc_attr($args['type']); ?>" class="<?php echo isset($args['class']) ? esc_attr($args['class']) : ''; ?> " <?php echo ( isset($args['info']) && !empty($args['info']) ) ? 'readonly' : ''; ?> />
	<?php
	if ( isset( $args['info'] ) && !empty( $args['info'] ) && ( !empty( $options['bankful_field_live_validate'] ) ) ) {

		$accounts_array_live = array();
		( isset($options['bankful_field_live_validated_account_cc']) && 'yes' == $options['bankful_field_live_validated_account_cc'] ) ?
			array_push($accounts_array_live, 'Credit Card') : '';
		( isset($options['bankful_field_live_validated_account_hg']) && 'yes' == $options['bankful_field_live_validated_account_hg'] ) ?
			array_push($accounts_array_live, 'Hosted Page') : '';

		echo ( 'LIVE' == $args['info'] ) ? ( ( isset($options['bankful_field_live_subscription_status']) && 'yes' == $options['bankful_field_live_subscription_status'] ) ?
			'<span class="dashicons dashicons-update-alt" title="Live Subscription Enabled"></span>' : '' ) : '';
		?>
		<span class="dashicons dashicons-yes-alt" style="color: green;" title="Activated"></span>
		<span class="block">Activated with account(s):
			<?php echo esc_html( implode( ', ', $accounts_array_live ) ); ?>
			(<a id="<?php echo esc_attr($args['info']); ?>_edit" href="">Update</a>)
		</span>
	<?php
	}
	?>
	<p class="description <?php echo esc_attr($args['label_for']); ?>">
		<?php esc_html_e($args['desc'], 'bankful'); ?>
	</p>
<?php
}

/**
 * Developers section callback function.
 *
 * @param array $args  The settings array, defining title, id, callback.
 */
function bankful_section_settings_callback( $args ) {
	$site_id = get_option( 'bankful_options_site_id' );
	?>
	<p id="<?php echo esc_attr($args['id']); ?>"><?php esc_html_e('Here you can define Credentials for your plugin. ', 'bankful'); ?><?php echo 'Site ID: ' . esc_html($site_id) ; ?></p>
<?php
}

function bankful_activate() {
	global $woocommerce;
	global $wp_version;
	global $LIVE_API_SRV;
	
	$request_url = $LIVE_API_SRV . 'api/woocommerce-v2/record-plugin-activity';

	$params = array(
		'woo_version' => isset($woocommerce->version) ? $woocommerce->version : '',
		'request_type' => 'A',
		'bf_site_url' => get_site_url(),
		'wp_version' => $wp_version,
		'php_version' => phpversion(),
		'bf_plugin_source' => 'woo_market',
		'site_admin_email' =>  get_bloginfo('admin_email'),
		'hash_salt' => '6a631f095832598284f22b5be8c0cc2e',
	);


	$args = array(
		'body' => http_build_query($params),
		'headers'     => array(
			'Content-Type' => 'application/x-www-form-urlencoded',
		),
	);

	$response = bankful_remote_post($request_url, $args);

	$body = wp_remote_retrieve_body($response);
}
register_activation_hook(__FILE__, 'bankful_activate');

function bankful_deactivate() {
	global $woocommerce;
	global $wp_version;
	global $LIVE_API_SRV;

	$request_url = $LIVE_API_SRV . 'api/woocommerce-v2/record-plugin-activity';

	$params = array(
		'woo_version' => $woocommerce ? $woocommerce->version : '',
		'request_type' => 'D',
		'bf_site_url' => get_site_url(),
		'wp_version' => $wp_version,
		'php_version' => phpversion(),
		'bf_plugin_source' => 'woo_market',
		'site_admin_email' =>  get_bloginfo('admin_email'),
		'hash_salt' => '6a631f095832598284f22b5be8c0cc2e',
	);

	$args = array(
		'body' => http_build_query($params),
		'headers'     => array(
			'Content-Type' => 'application/x-www-form-urlencoded',
		),
	);

	$response = bankful_remote_post($request_url, $args);
	$body = wp_remote_retrieve_body($response);
}
register_deactivation_hook( __FILE__, 'bankful_deactivate' );


// API endpoint for syncing Orders
add_action('rest_api_init', function () {
	register_rest_route( 'bankful/v1', 'recurring-order/', array(
				'methods'  => 'POST',
				'callback' => 'create_recurring_order_bankful',
				'permission_callback' => 'check_permission_rest_create_order',
	));
});

function check_permission_rest_create_order( $request ) {
	// Check if the parameter has the expected value
	if (isset($request['req_username']) && isset($request['req_password'])) {
		return true; // Permission granted
	} else {
		return false; // Permission denied
	}
}

function create_recurring_order_bankful( $request ) {

	$status = $request['status'];

	if ('pending' == $status) {
		$args = array(
			'req_username' => $request['req_username'],
			'req_password' => $request['req_password'],
			'product' => $request['product'],
			'customer_email' => $request['customer_email'],
			'billing_address' => $request['billing_address'],
			'shipping_address' => $request['shipping_address'],
		);
		$pending = true;
	} else {
		$args = array(
			'req_username' => $request['req_username'],
			'req_password' => $request['req_password'],
			'transaction_id' => $request['transaction_id'],
			'order_id' => $request['order_id'],
		);
		$complete = true;
	}

	$options = get_option( 'bankful_options' );

	$req_username = isset($options['bankful_field_live_username']) ? $options['bankful_field_live_username'] : '';
	$req_password = isset($options['bankful_field_live_password']) ? $options['bankful_field_live_password'] : '';

	$payment_gateway_id = get_current_active_gateway_id();

	$payment_gateway = WC()->payment_gateways->payment_gateways()[$payment_gateway_id];
	$method_title = $payment_gateway->method_title;

	if (strcmp($req_username, $args['req_username']) !== 0) {
		return new WP_Error( 'bankful_merchant_error', 'incorrect credentials', array( 'status' => 404 ) );
	}

	if (strcmp($req_password, $args['req_password']) !== 0) {
		return new WP_Error( 'bankful_merchant_error', 'incorrect credentials', array( 'status' => 404 ) );
	}

	if ($pending) {

		$order_email = $args['customer_email'];

		$billing_address = array(
			'first_name' => $args['billing_address']['first_name'],           
			'last_name'  => $args['billing_address']['last_name'],     
			'email'      => $order_email,
			'phone'      => $args['billing_address']['phone'],   
			'address_1'  => $args['billing_address']['address1'],     
			'address_2'  => $args['billing_address']['address2'],             
			'city'       => $args['billing_address']['city'],     
			'state'      => $args['billing_address']['state'],             
			'postcode'   => $args['billing_address']['zip'],            
			'country'    => $args['billing_address']['phone'],                
		);

		$shipping_address = array(
			'first_name' => $args['shipping_address']['first_name'],
			'last_name'  => $args['shipping_address']['last_name'],
			'email'      => $order_email,
			'phone'      => $args['shipping_address']['phone'],
			'address_1'  => $args['shipping_address']['address1'],
			'address_2'  => $args['shipping_address']['address2'],
			'city'       => $args['shipping_address']['city'],
			'state'      => $args['shipping_address']['state'],
			'postcode'   => $args['shipping_address']['zip'],
			'country'    => $args['shipping_address']['phone'],
		);

		$user = get_user_by('email', $order_email);

		if ( !$user ) {
			$default_password = wp_generate_password();
			$user = wp_create_user( $order_email, $default_password, $order_email );
		}
	
		$order = wc_create_order(array( 'customer_id' => $user->id ));
	
		$order->add_product( wc_get_product($args['product']), 1); // This is an existing SIMPLE product
		$order->set_address( $billing_address, 'billing' );
		$order->set_address( $shipping_address, 'shipping' );

		$order->calculate_totals();

		$note = __('This is Recurring Order, Created By Bankful Recurring Service and waiting for Payment, If Product is Physical do not ship the Product until successful payment.', 'bankful');
	}

	if ($complete) {
		$order = wc_get_order( $args['order_id'] );

		$order->set_payment_method( $method_title );
		$order->set_payment_method_title( $method_title );
		$order->set_transaction_id( $args['transaction_id'] );
		$order->set_date_paid( time() );

		$note = __('This is Recurring Order, Completed By Bankful Recurring Service after Successful Payment, If Product is Physical you can now ship the Product.', 'bankful');
	}

	// Add the note
	$order->add_order_note( $note );

	update_post_meta($order->id, 'bfp_recurring', true);

	$order->update_status($status, 'Recurring order', true);  

	return $order->id;
}

// API endpoint for cancelling subscription
add_action('rest_api_init', function () {
	register_rest_route( 'bankful/v1', 'stop-recurring-order/', array(
		'methods'  => 'POST',
		'callback' => 'stop_bankful_subscription',
		'permission_callback' => 'check_permission_rest_stop_order',
	));
});

function check_permission_rest_stop_order( $request ) {
	// Check if the parameter has the expected value
	if (isset($request['recurringSubscriptionId'])) {
		return true; // Permission granted
	} else {
		return false; // Permission denied
	}
}

function stop_bankful_subscription( $request ) {

	$options = get_option( 'bankful_options' );
	
	$req_username = isset($options['bankful_field_live_username']) ? $options['bankful_field_live_username'] : '';
	$req_password = isset($options['bankful_field_live_password']) ? $options['bankful_field_live_password'] : '';

	if (!strcmp($req_username, $request['req_username']) === 0 || !strcmp($req_password, $request['req_password']) === 0) {
		return 'Merchant Not found';
	}

	$subsOrderID = $request['recurringSubscriptionId'];
	
	if (!class_exists('WC_Subscription')) {
		return 'Bankful Subscription is not enabled on this store.';
	}

	$subscription = new WC_Subscription( $subsOrderID );

	if ( $subscription->get_id() ) {
		$subscription->update_status( 'on-hold' );
	} else {
		return 'Bankful Subscription ID not found.';
	}
	return $subsOrderID;
}

function get_current_active_gateway_id() {
	$options = get_option( 'bankful_options' );
	$active_gateway_id = 'bankful_credit_card';
	
	( isset($options['bankful_field_live_validated_account_cc']) && 'yes' == $options['bankful_field_live_validated_account_cc'] ) ?
	$active_gateway_id = 'bankful_credit_card' : '';
	( isset($options['bankful_field_live_validated_account_hg']) && 'yes' == $options['bankful_field_live_validated_account_hg'] ) ?
	$active_gateway_id = 'bankful_hosted_gateway' : '';

	return $active_gateway_id;
}

add_action( 'woocommerce_subscription_renewal_payment_complete', 'subscription_renewal_payment_complete', 11, 2 );
function subscription_renewal_payment_complete( $subscription, $order ) {
	global $SANDBOX_API_SRV;
	global $LIVE_API_SRV;

	$options = get_option( 'bankful_options' );
	$site_id = get_option( 'bankful_options_site_id' );
	
	$api_endpoint = $LIVE_API_SRV . 'api/';

	$request_url = $api_endpoint . 'woocommerce-v2/sync-subscription';
	$req_username = $options['bankful_field_live_username'];
	$req_password = $options['bankful_field_live_password'];

	$subscription_id    = $subscription->get_id();
	$next_payment       = $subscription->get_date('next_payment', 'site');

	$fetchObj = new stdClass(); 

	$fetchObj->site_id = $site_id;
	$fetchObj->next_payment_date = $next_payment;
	$fetchObj->subscription_id = $subscription_id;


	$params = (array) $fetchObj;

	$merchant_info = array();
	if (class_exists('WC_Bankful_WS_Gateway')) {
		$class_obj = new WC_Bankful_WS_Gateway();
		$merchant_info  = $class_obj->merchant_credential_new();
	} else if (class_exists('WC_Gateway_Bankful')) {
		$class_obj = new WC_Gateway_Bankful();
		$merchant_info  = $class_obj->merchant_credential_new();
	}
	$payloadHash = generateSignatureHash($params, $merchant_info['bf_hash_salt']);

	$args = array(
		'method'    => 'POST',
		'body'      => wp_json_encode( $fetchObj ),
		'headers'   => array(
			'Content-Type'  => 'application/json',
			'Authorization' => 'Bearer ' . $merchant_info['bf_access_token'],
			'X-Bankful-Hmac-SHA256' => $payloadHash,
		),
	);
	
	$response = bankful_remote_post($request_url, $args);

	if (!is_wp_error($response)) {
		$body = wp_remote_retrieve_body($response);
		$body_pre = json_decode($body);
	}
}

add_action( 'woocommerce_subscription_status_updated', 'update_bankful_on_status_change', 11, 3);
function update_bankful_on_status_change( $subscription, $new_status, $old_status ) {
	global $LIVE_API_SRV;

	$options = get_option( 'bankful_options' );
	$site_id = get_option( 'bankful_options_site_id' );
	
	$api_endpoint = $LIVE_API_SRV . 'api/';

	$request_url = $api_endpoint . 'woocommerce-v2/stop-subscription';
	$req_username = $options['bankful_field_live_username'];
	$req_password = $options['bankful_field_live_password'];
	write_logs_bf('update_bankful_on_status_change STOP Recurring ID: ' . $subscription->get_id() . '. new status: ' . $new_status . '. Old Status: ' . $old_status, 'info');
	if (in_array($new_status, array( 'cancel', 'cancelled', 'expired' ))) {
		$fetchObj = new stdClass(); 
	
		$fetchObj->site_id = $site_id;
		$fetchObj->subscription_id = $subscription->get_id();

		$params = (array) $fetchObj;

		$merchant_info = array();
		if (class_exists('WC_Bankful_WS_Gateway')) {
			$class_obj = new WC_Bankful_WS_Gateway();
			$merchant_info  = $class_obj->merchant_credential_new();
		} else if (class_exists('WC_Gateway_Bankful')) {
			$class_obj = new WC_Gateway_Bankful();
			$merchant_info  = $class_obj->merchant_credential_new();
		}

		$args = array(
			'method'    => 'POST', 
			'body'      => wp_json_encode( $fetchObj ),
			'headers'   => array(
				'Content-Type'  => 'application/json', 
				'Authorization' => 'Bearer ' . $merchant_info['bf_access_token'],
			),
		);
		
		$response = bankful_remote_post($request_url, $args);

		if (!is_wp_error($response)) {
			$body = wp_remote_retrieve_body($response);
			$body_pre = json_decode($body);
		}
	}
}

/**
 * Handle a custom 'customvar' query var to get products with the 'customvar' meta.
 *
 * @param array $query - Args for WP_Query.
 * @param array $query_vars - Query vars from WC_Product_Query.
 * @return array modified $query
 */
function handle_custom_query_var( $query, $query_vars ) {
	if ( ! empty( $query_vars['recurring_product'] ) ) {
		$query['meta_query'][] = array(
			'key' => 'recurring_product',
			'value' => esc_attr( $query_vars['recurring_product'] ),
		);
	}

	return $query;
}
add_filter( 'woocommerce_product_data_store_cpt_get_products_query', 'handle_custom_query_var', 10, 2 );

//Suspension and Reactivation
add_filter('wcs_view_subscription_actions', 'add_suspend_subscription_button', 10, 3);

function add_suspend_subscription_button( $actions, $subscription, $user_id ) {

	if ( ! $subscription->can_be_updated_to( 'on-hold' ) ) {
		return $actions;
	}

	if ( ! user_can( $user_id, 'edit_shop_subscription_status', $subscription->get_id() ) ) {
		return $actions;
	}

	if ( current_user_can( 'manage_woocommerce' ) || wcs_can_user_put_subscription_on_hold( $subscription, $user_id ) ) {
		if ($subscription->has_status(array( 'active', 'on-hold' ))) {
			$actions['suspend'] = array(
				'url'  => wp_nonce_url(add_query_arg('suspend_subscription', $subscription->get_id()), 'suspend_subscription'),
				'name' => __('Suspend', 'bankful'),
			);
		}
	}
	return $actions;
}

add_action('init', 'handle_suspend_subscription_action');

function handle_suspend_subscription_action() {
	if (isset($_GET['suspend_subscription']) && isset($_GET['_wpnonce'])) {
		if (!wp_verify_nonce(sanitize_key($_GET['_wpnonce']), 'suspend_subscription')) {
			return;
		}

		$subscription_id = absint($_GET['suspend_subscription']);
		$subscription = wcs_get_subscription($subscription_id);

		if ($subscription && $subscription->has_status(array( 'active', 'on-hold' ))) {
			$subscription->update_status('on-hold');
			wc_add_notice(__('Subscription suspended successfully.', 'bankful'), 'success');
			wp_safe_redirect(wc_get_account_endpoint_url('subscriptions'));
			exit();
		}
	}
}

add_filter('woocommerce_subscription_actions', 'add_resume_subscription_button', 10, 2);

function add_resume_subscription_button( $actions, $subscription ) {
	if ($subscription->has_status('on-hold')) {
		$actions['resume'] = array(
			'url'  => wp_nonce_url(add_query_arg('resume_subscription', $subscription->get_id()), 'resume_subscription'),
			'name' => __('Resume', 'bankful'),
		);
	}
	return $actions;
}

add_action('init', 'handle_resume_subscription_action');

function handle_resume_subscription_action() {
	if (isset($_GET['resume_subscription']) && isset($_GET['_wpnonce'])) {
		if (!wp_verify_nonce(sanitize_key($_GET['_wpnonce']), 'resume_subscription')) {
			return;
		}

		$subscription_id = absint($_GET['resume_subscription']);
		$subscription = wcs_get_subscription($subscription_id);

		if ($subscription && $subscription->has_status('on-hold')) {
			$subscription->update_status('active');
			wc_add_notice(__('Subscription resumed successfully.', 'bankful'), 'success');
			wp_safe_redirect(wc_get_account_endpoint_url('subscriptions'));
			exit();
		}
	}
}

add_filter('wcs_view_subscription_actions', 'add_renew_now_button', 10, 2);

function add_renew_now_button( $actions, $subscription ) {
	if ($subscription->has_status(array( 'active', 'on-hold' ))) {
		$actions['renew_now'] = array(
			'url'  => wp_nonce_url(add_query_arg('renew_subscription', $subscription->get_id()), 'renew_subscription'),
			'name' => __('Renew Now', 'bankful'),
		);
	}
	return $actions;
}

add_action('init', 'handle_renew_subscription_action');

function handle_renew_subscription_action() {
	if (isset($_GET['renew_subscription']) && isset($_GET['_wpnonce'])) {
		if (!wp_verify_nonce(sanitize_key($_GET['_wpnonce']), 'renew_subscription')) {
			return;
		}

		$subscription_id = absint($_GET['renew_subscription']);
		$subscription = wcs_get_subscription($subscription_id);

		if ($subscription && $subscription->has_status(array( 'active', 'on-hold' ))) {
			$order = wcs_create_renewal_order($subscription);
			$order_total = $order->get_total();
			if ($order) {
				if (class_exists('WC_Bankful_WS_Gateway')) {
					$class_obj = new WC_Bankful_WS_Gateway();
					$class_obj->process_subscription_payment($order_total, $order);
				} else if (class_exists('WC_Gateway_Bankful')) {
					$class_obj = new WC_Gateway_Bankful();
					$class_obj->process_subscription_payment($order_total, $order);
				}
				// Remove any overdue status
				$subscription->update_status('active');
				wc_add_notice(__('Subscription renewed successfully.', 'bankful'), 'success');
				wp_safe_redirect(wc_get_account_endpoint_url('subscriptions'));
				exit();
			} else {
				wc_add_notice(__('Failed to renew the subscription.', 'bankful'), 'error');
			}
		}
	}
}

add_action('before_woocommerce_init', function () {
	if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) {
		\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true);
		\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('cart_checkout_blocks', __FILE__, true);
	}
});

 //Validate Merchant
add_action('wp_ajax_nopriv_validate_bankful_merchant', 'validate_bankful_merchant');    
add_action('wp_ajax_validate_bankful_merchant', 'validate_bankful_merchant');
function validate_bankful_merchant() {
	if ( isset($_POST['postdata']['_bfcrednonce']) && ! wp_verify_nonce( sanitize_text_field(wp_unslash($_POST['postdata']['_bfcrednonce'])), 'bf-creds-nonce' ) ) {
		die();
	}
	global $WP_SITE_URL;
	global $woocommerce;

	if (isset($_POST['postdata']['req_username']) && isset($_POST['postdata']['req_password']) && isset($_POST['postdata']['site_url'])) {
		$bf_api_key      = sanitize_text_field(wp_unslash($_POST['postdata']['req_username']));
		$bf_api_secret   = sanitize_text_field(wp_unslash($_POST['postdata']['req_password']));
		$site_url        = sanitize_text_field(wp_unslash($_POST['postdata']['site_url']));
		$woo_version     = isset($woocommerce->version) ? $woocommerce->version : '';
		$bankful_version = BANKFUL_VERSION;
		$result        = validateBankfulCredentials( $bf_api_key, $bf_api_secret, $site_url, $woo_version, $bankful_version);

		if ( ! empty( $result ) ) { 
			exit(wp_json_encode($result));
		}
	}
}

 //Get bankful token public key and hash salt
function getBankfulToken() {
	$wp_bf_api_token  = get_option('bankful_options_api_access_token');
	$wp_bf_public_key = get_option('bankful_options_public_key');
	$wp_bf_hash_salt  = get_option('bankful_options_hash_salt');
	
	$result = array(); 
	// IF TOKEN and PUBLIC KEY AND HASH SALT ARE Already Exist in WP DB 
	if ( false !== $wp_bf_api_token && false !== $wp_bf_public_key ) {
		$result['bf_access_token'] = $wp_bf_api_token;
		$result['bf_public_key'] = $wp_bf_public_key;
		$result['bf_hash_salt'] = $wp_bf_hash_salt;
	}
	return $result;
}

 //Validate Merchant Credentials
function validateBankfulCredentials( $bf_api_key, $bf_api_secret, $site_url, $woo_version, $bankful_version ) {
	global $LIVE_API_SRV;
	
	$validate_api_url = $LIVE_API_SRV . 'api/woocommerce-v2/validate-credentials';
	$result = array();
	$params = array(
		'bf_api_key' => $bf_api_key,
		'bf_api_secret' => $bf_api_secret,
		'site_url' => $site_url,
		'woo_version' => $woo_version,
		'bf_plugin_version' => $bankful_version,
	);

	$args = array(
		'body' => $params,
	);

	$response = bankful_remote_post($validate_api_url, $args);

	if ( ! is_wp_error( $response ) ) {
		$result = json_decode( wp_remote_retrieve_body( $response ), true );
		$bf_access_token = get_option( 'bankful_options_api_access_token' );
		if ( empty( $bf_access_token ) ) {
			if ( ! empty( $result ) && 'success' === $result['status']) {
				add_option('bankful_options_api_access_token', $result['data']['bf_api_access_token']);
				add_option('bankful_options_public_key', $result['data']['merchant_public_key']);
				add_option('bankful_options_hash_salt', $result['data']['bf_salt']);
				
			}
		} else if ( ! empty( $result ) && 'success' === $result['status'] ) {
				update_option('bankful_options_api_access_token', $result['data']['bf_api_access_token']);
				update_option('bankful_options_public_key', $result['data']['merchant_public_key']);
				update_option('bankful_options_hash_salt', $result['data']['bf_salt']);
		}
		unset($result['data']['bf_api_access_token']);
		unset($result['data']['merchant_public_key']);
		unset($result['data']['bf_salt']);
	} else {
		$error_message = $response->get_error_message();
		write_logs_bf('validateBankfulCredentials Invalid Credentials Error Msg: ' . $error_message . 'info');
	}

	return $result;
}

/**
 * Encrypt a payload using a public key from the database.
 *
 * @param string $payload The data to encrypt.
 * @param string $publicKey public key to be use for encrypt.
 * @return string|false The Base64-encoded encrypted payload, or false on failure.
 */
function encryptPayload( $payload, $publicKey ) {
	// Encrypt the payload using the public key
	$encrypted = '';
	
	$startPublicKey = '-----BEGIN PUBLIC KEY-----' . PHP_EOL;
	$endPublicKey = PHP_EOL . '-----END PUBLIC KEY-----';
	
	$publicKey = $startPublicKey . $publicKey . $endPublicKey;
	$success = openssl_public_encrypt($payload, $encrypted, $publicKey);

	if (!$success) { 
		return false;
	}
	return base64_encode($encrypted);
}

/**
 * Send HTTP POST request using WordPress HTTP API.
 *
 * @param string $url  Target URL.
 * @param array  $args Request arguments.
 * @return array|WP_Error Response array or WP_Error on failure.
 */
function bankful_remote_post( $url, $args ) {
	// Use wp_safe_remote_post which validates the URL against an allowlist of safe hosts.
	$response = wp_safe_remote_post($url, $args);
	return $response;
}
