<?php
/**
 * Handles responses from Bankful Webhook.
 *
 * @package WooCommerce\Bankful
 * @version 3.0.4
 */

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


function verify_signature_hash( $request ) {
	// Get the required parameter from the request
	$body = $request->get_params();
	if (verifyHashSignatureFromRequest($body)) {
		return true; // Permission granted
	} else {
		return false; // Permission denied
	}
}

// API endpoint for redirect
add_action('rest_api_init', function () {
	register_rest_route( 'bankful/v1', 'redirect-pending/', array(
		'methods'  => 'GET',
		'callback' => 'get_redirect_order_bankful',
		'permission_callback' => 'verify_signature_hash',
	));
});

function get_redirect_order_bankful( $request ) {
	try {
		$order_id = $request['XTL_ORDER_ID'];
		$order_complete_url = $request['TRANS_COMPLETE_URL'];

		$body = $request->get_params();
		// write_logs_bf(print_r($body, true));

		$order = new WC_Order( $order_id );
		$is_subscription = false;
		// write_logs_bf($order->get_status());

		$transStatus = strtolower($request['TRANS_STATUS_NAME']);
		$orderStatus = strtolower($order->get_status());

		$validTransStatus = in_array($transStatus, ['approved', 'pending', 'declined']);
		$invalidOrderStatus = in_array($orderStatus, ['completed', 'processing']);

		// If transaction status is not approved/pending AND order is failed,
		// OR if order is already completed/processing — then return early
		if ((!$validTransStatus && $orderStatus === 'failed') || $invalidOrderStatus) {
			return;
		}
				
		if (verifyHashSignatureFromRequest($body)) {

			if (function_exists('wcs_order_contains_subscription') && function_exists('wcs_get_subscriptions_for_order') && wcs_order_contains_subscription($order_id)) {
				$subscriptions = wcs_get_subscriptions_for_order($order_id);
				$is_subscription = true;
			} elseif (function_exists('wcs_order_contains_renewal') && wcs_order_contains_renewal($order_id) && function_exists('wcs_get_subscriptions_for_renewal_order')) {
				$subscriptions = wcs_get_subscriptions_for_renewal_order($order_id);
				$is_subscription = true;
			} else {
				$is_subscription = false;
			}

			$status = strtoupper($request['TRANS_STATUS_NAME']);

			if ( empty( $log ) ) {
				$log = wc_get_logger();
			}
			$log->add( 'bankful_hosted', 'Redirecting for Order Status => ' . $status . ' --- ' . $order_id );

			if ('APPROVED' == $status) {
				$order->add_order_note('Bankful Payment Gateway Transaction Completed and Transaction Id: ' . $request['TRANS_ORDER_ID'] );
				$order->add_meta_data( '_transaction_id', $request['TRANS_ORDER_ID'], true );
				$order->payment_complete( $request['TRANS_ORDER_ID'] );
				wc_reduce_stock_levels($order->get_id());

				if ($is_subscription) {
					if (isset($request['CUSTOMER_VAULT_ID']) && $request['CUSTOMER_VAULT_ID']) {
						foreach ($subscriptions as $subscription) {
							$subscription->update_meta_data('_bankful_customer_id', $request['CUSTOMER_VAULT_ID']);
							if (class_exists('WC_Subscriptions_Manager') && function_exists('activate_subscriptions_for_order')) {
								WC_Subscriptions_Manager::activate_subscriptions_for_order($order);
							}

							$subscription_id = $subscription->get_id();
							$found_object = new stdClass();
							// write_logs_bf($request['RECURRING_SCHEDULES']);
							$recurring_array = json_decode($request['RECURRING_SCHEDULES']);
							foreach ($recurring_array as $schedule) {
								if ($schedule->WOO_SUBSCRIPTION_ID == $subscription_id) {
									$found_object = $schedule;
									// write_logs_bf(print_r($found_object, true));

									break;
								}
							}

							if (isset($found_object->RECURRING_SCHEDULE_ID)) {
								$subscription->update_meta_data('_bankful_recurring_id', $found_object->RECURRING_SCHEDULE_ID);

								$order->add_order_note(' Payment completed with Bankful and Recurring ID:' . $body->RECURRING_SCHEDULE_ID);
							} else {
								$order->add_order_note(' RECURRING_SCHEDULE_ID not found');
							}
							if (class_exists('WC_Subscriptions_Manager') && function_exists('activate_subscriptions_for_order')) {
								WC_Subscriptions_Manager::activate_subscriptions_for_order($order);
							}
							$subscription->save();
						}
					} else {
						$order->add_order_note('Customer Vault ID not found, so next scheduled subscription transaction will not work. Contact Bankful Support for this.');
						foreach ($subscriptions as $subscription) {
							$subscription->add_order_note('Customer Vault ID not found, so next scheduled subscription transaction will not work. Contact Bankful Support for this.');
							$subscription->save();
						}
					}
				}
	
			} else if ('PENDING' == $status) {
				$order->add_order_note('Bankful Payment Gateway Transaction is Pending now and Transaction Id: ' . $request['TRANS_ORDER_ID'] . '. We Strongly recommend do not ship order yet.');
				$order->add_meta_data( '_transaction_id', $request['TRANS_ORDER_ID'], true );
				$order->update_status('on-hold');
			} else if ('DECLINED' == $status) {
				$order->add_order_note('Bankful Payment Gateway Transaction is FAILED and Transaction Id: ' . $request['TRANS_ORDER_ID'] . '. We Strongly recommend do not ship order.');
				$order->add_order_note('Bankful Payment Gateway Transaction is DECLINED due to: ' . $request['ERROR_MESSAGE'] . ', API-ADVICE: ' . $request['API_ADVICE'] . '. We Strongly recommend do not ship order.');
				$order->add_meta_data( '_transaction_id', $request['TRANS_ORDER_ID'], true );
				$order->update_status('failed');
				wp_safe_redirect( $order->get_cancel_order_url() );
				exit;
			}
			wp_safe_redirect( $order_complete_url );
			exit;
		} else {
			$order->add_order_note('Bankful Payment Gateway Transaction is Transaction Id: ' . $request['TRANS_ORDER_ID'] . '. But response Data is altered.');
			$order->add_order_note('Signature Mismatched');
			$order->add_meta_data( '_transaction_id', $request['TRANS_ORDER_ID'], true );
			$order->update_status('failed');
			wp_safe_redirect( $order->get_cancel_order_url() );
			exit;
		}

	} catch ( Exception $ex ) { // Add log
		if ( empty( $log ) ) {
			$log = wc_get_logger();
		}
		$log->log( 'error', $ex->getMessage() . ', Order ID: ' . $order_id, array( 'source' => 'bankful_hosted' ) );
	}
}

// API endpoint for STATUS
add_action('rest_api_init', function () {
	register_rest_route( 'bankful/v1', 'order-updated/', array(
				'methods'  => 'POST',
				'callback' => 'order_status_changed_bankful',
				'permission_callback' => 'verify_signature_hash',
	));
});

function order_status_changed_bankful( $request ) {

	$order_id = $request['XTL_ORDER_ID'];
	$body = $request->get_params();
	// write_logs_bf(print_r($body, true));

	if (verifyHashSignatureFromRequest($body)) {
		$order = new WC_Order( $order_id );

		$transStatus = strtolower($request['TRANS_STATUS_NAME']);
		$orderStatus = strtolower($order->get_status());

		$validTransStatus = in_array($transStatus, ['approved', 'pending', 'declined']);
		$invalidOrderStatus = in_array($orderStatus, ['completed', 'processing']);

		// If transaction status is not approved/pending AND order is failed,
		// OR if order is already completed/processing — then return early
		if ((!$validTransStatus && $orderStatus === 'failed') || $invalidOrderStatus) {
			return;
		}
		
		$status = strtoupper($request['TRANS_STATUS_NAME']);
		
		if ( empty( $log ) ) {
			$log = wc_get_logger();
		}
		$log->add( 'bankful_hosted', 'Changing Order Status to => ' . $status . '--- For Order ID: ' . $order_id );

		if ('APPROVED' == $status) {
			$order->add_order_note( 'Bankful Payment Gateway Transaction Completed and Transaction Id: ' . $request['TRANS_ORDER_ID'] );
			$order->add_meta_data( '_transaction_id', $request['TRANS_ORDER_ID'], true );
			$order->payment_complete( $request['TRANS_ORDER_ID'] );
			wc_reduce_stock_levels($order_id);
		} else if ('PENDING' == $status) {
			$order->add_order_note('Bankful Payment Gateway PENDING Transaction and Transaction Id: ' . $request['TRANS_ORDER_ID'] );
			$order->add_meta_data( '_transaction_id', $request['TRANS_ORDER_ID'], true );
			$order->update_status('on-hold');
		} else if ('DECLINED' == $status) {
			$order->add_order_note('Bankful Payment Gateway FAILED Transaction and Transaction Id: ' . $request['TRANS_ORDER_ID'] );
			$order->add_order_note('Bankful Payment Gateway Transaction is DECLINED due to: ' . $request['ERROR_MESSAGE'] . ', API-ADVICE: ' . $request['API_ADVICE'] . '. We Strongly recommend do not ship order.');
			$order->add_meta_data( '_transaction_id', $request['TRANS_ORDER_ID'], true );
			$order->update_status('failed');
		}
		return $request;
		exit;
	} else {
		write_logs_bf('Signature Not Matched');
		throw new Error('Signature Mismatched');
	}
}
