<?php
/**
 * Authorize.net Gateway Credit Card API Class
 *
 * Handles Credit Card API payments through Authorize.net gateway for WooCommerce.
 *
 * @package    Authorize_Net_Payments_For_Woocommerce
 * @subpackage Authorize_Net_Payments_For_Woocommerce/includes
 * @since      1.0.0
 */

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

use net\authorize\api\contract\v1 as AnetAPI;
use net\authorize\api\controller as AnetController;

require_once plugin_dir_path(__FILE__) . '../../trait-anet-order-meta.php';
/**
 * Class Anet_Credit_Card_Api
 *
 * Provides methods to execute credit card transactions
 */
class Anet_Credit_Card_Api
{
	use Anet_Order_Meta;
	/**
	 * Executes a credit card transaction request to Authorize.net.
	 *
	 * @param array     $payment_args Payment arguments including amount, card details, etc.
	 * @param \WC_Order $wc_order     WooCommerce order object.
	 *
	 * @return array Result of the transaction execution.
	 */
	public static function execute($payment_args, $wc_order)
	{
		try {
			// Set up merchant authentication.
			$helper = new Anet_Api_Helper(ANET_PAYMENT_TYPE_CREDIT_CARD);
			$merchant_auth_request = $helper->merchant_authentication_request();
			// Create the transaction request.
			$transaction_request = $helper->build_transaction_request($payment_args);
			$processing_options = new AnetAPI\ProcessingOptionsType();
			$anet_subscription = new Anet_Subscriptions();
			if ($anet_subscription->is_subscription_active) {
				$self = new self();
				if ((wcs_order_contains_subscription($wc_order) || wcs_order_contains_renewal($wc_order)) &&  empty($self->get_order_meta($wc_order, 'anet_subscription_token'))) {
					//subscription isfirstrecurringpayment.
					$processing_options->setIsFirstRecurringPayment(true);
					$transaction_request->setProcessingOptions($processing_options);
				} else if (wcs_order_contains_renewal($wc_order) &&  !empty($self->get_order_meta($wc_order, 'anet_subscription_token'))) {
					$processing_options->setIsSubsequentAuth(true);
					$transaction_request->setProcessingOptions($processing_options);
				}
			}
			// Create the transaction request.
			$request = new AnetAPI\CreateTransactionRequest();
			$request->setMerchantAuthentication($merchant_auth_request);
			$request->setTransactionRequest($transaction_request);
			// Set the refId.
			if (isset($payment_args['refId'])) {
				$request->setRefId($payment_args['refId']);
			}
			// Log the request with masked data.
			$sanitized_request = Anet_Api_Helper::mask_sensitive_data($request); // Call the mask_sensitive_data function.
			Anet_Setting_Helper::log("\nRequest:\n" . $sanitized_request, ANET_PAYMENT_TYPE_CREDIT_CARD, 'debug');
			// Execute the request.
			$controller = new AnetController\CreateTransactionController($request);
			$response = $controller->executeWithApiResponse($helper->controller_response());
			return self::process_response($response);
		} catch (Throwable $e) {
			Anet_Setting_Helper::log("\nException:\n" . $e->getMessage(), ANET_PAYMENT_TYPE_CREDIT_CARD, 'error');
			return array("success" => false);
		}
	}
	/**
	 * Creates a customer profile for tokenization using credit card details.
	 *
	 * @param int   $user_id      WordPress user ID.
	 * @param array $payment_args Payment arguments including card details.
	 *
	 * @return mixed Result from the tokenization class.
	 */
	public static function create_customer_profile($user_id, $payment_args)
	{
		require_once(dirname(__FILE__) . '/../../api/tokenization/class-anet-credit-card-tokenization.php');
		$customer_profile = new Anet_Credit_Card_Tokenization();
		return $customer_profile->create_customer_profile($user_id, $payment_args);
	}
	/**
	 * Processes the response returned from the Authorize.net API.
	 *
	 * @param mixed $response The API response object.
	 *
	 * @return array Result array indicating success or failure with transaction details.
	 */
	public static function process_response($response)
	{
		$transaction_response = $response->getTransactionResponse();
		$build_response = fn($success, $message = []) =>
		array_merge([
			'success'        => $success,
			'transaction_id' => $transaction_response->getTransId(),
			'accountNumber'  => $transaction_response->getAccountNumber(),
			'accountType'    => $transaction_response->getAccountType(),
			'authCode'       => $transaction_response->getAuthCode(),
			'responseCode'   => $transaction_response->getResponseCode(),
			'resultCode'     => $response->getMessages()->getResultCode(),
		], $message);
		// Null transaction response.
		if (null === $response || null === $transaction_response) {
			Anet_Setting_Helper::log('Error: No response from Authorize.net.', ANET_PAYMENT_TYPE_CREDIT_CARD, 'error');
			return array('success' => false);
		}
		Anet_Setting_Helper::log("\nResponse:\n" . wp_json_encode($response->getTransactionResponse(), JSON_PRETTY_PRINT) . wp_json_encode($response, JSON_PRETTY_PRINT), ANET_PAYMENT_TYPE_CREDIT_CARD, 'debug');
		// Check for failed result code.
		if (ANET_SANDBOX_STATUS_AUTHORIZED !== $response->getMessages()->getResultCode()) {
			$error_messages = $response->getMessages()->getMessage();
			Anet_Setting_Helper::log('Error: ' . $error_messages[0]->getText(), ANET_PAYMENT_TYPE_CREDIT_CARD, 'error');
			return $build_response(false, [
				'errors' => $transaction_response->getErrors()[0]->getErrorText()
			]);
		}
		// Successful transaction.
		if (null !== $transaction_response && null !== $transaction_response->getMessages()) {
			return $build_response(true, [
				'message'    => $transaction_response->getMessages()[0]->getDescription()
			]);
		} elseif (null !== $transaction_response && null !== $transaction_response->getErrors()) {
			$error_messages = $transaction_response->getErrors();
			Anet_Setting_Helper::log('Transaction Error: ' . $error_messages[0]->getErrorText(), ANET_PAYMENT_TYPE_CREDIT_CARD, 'error');
			return $build_response(false, [
				'errors' => $error_messages[0]->getErrorText()
			]);
		}
		Anet_Setting_Helper::log('Error: Unable to process request.', ANET_PAYMENT_TYPE_CREDIT_CARD, 'error');
		return array('success' => false);
	}
}
