<?php
/**
 * File: Tami_WooCommerce_GW.php
 * Year: 2023
 */

use Tami\WooCommerce\Response;
use Tami\WooCommerce\TamiAdminSettings;
use Tami\WooCommerce\TamiCheckout;
use Tami\WooCommerce\TamiPaymentClient;
use Automattic\WooCommerce\Utilities\OrderUtil;
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

class Tami_WooCommerce_GW extends WC_Payment_Gateway_CC {

	const MAKE_PAYMENT_ENDPOINT = "tami-payment-make-payment";
	const CALLBACK_ENDPOINT = "tami-payment-callback";
	const INSTALLMENT_ENDPOINT = "tami-payment-installment";

	public function __construct() {
		$this->id                 = 'tami_woocommerce';
		$this->method_title       = __( 'Tami WooCommerce', 'tami-payment' );
		$this->supports           = [ 'refunds', 'default_credit_card_form' ];
		$this->method_description = __( 'Tami WooCommerce payment gateway!', 'tami-payment' );
		$this->has_fields         = true;
		$this->settings           = TamiAdminSettings::get_api_settings( true );
		$this->enabled            = $this->settings['enabled'] === 'yes' ?? false;
		$woocommerce_settings     = TamiAdminSettings::get_module_settings();
		add_action( 'woocommerce_api_' . self::MAKE_PAYMENT_ENDPOINT, array( $this, 'make_payment' ) );
		add_action( 'woocommerce_api_' . self::CALLBACK_ENDPOINT, array( $this, 'callback' ) );
		add_action( 'woocommerce_api_' . self::INSTALLMENT_ENDPOINT, array( $this, 'installment' ) );
		add_action( 'woocommerce_after_settings_checkout', array( $this, 'output' ) );
		add_action( 'woocommerce_receipt_' . $this->id, array( $this, 'receipt_page' ) );
		$this->title = $woocommerce_settings['title'] ?? __( 'Credit Card Payment', 'tami-payment' );

		$this->init_form_fields();
		$this->init_settings();

		// save settings
		add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array(
			$this,
			'process_admin_options'
		) );

		if ( ! class_exists( '\Tami\WooCommerce\TamiPaymentClient' ) ) {
			include TAMI_PLUGIN_PATH . '/lib/TamiPaymentClient.php';
		}
	}

	public function output() {
		global $current_tab, $current_section;
		if ( $current_section !== $this->id || isset( $GLOBALS['tami-payment-settings-output-ok'] ) ) {
			return "";
		}
		$buttonLabel                                = __( 'Merchant Settings', 'tami-payment' );
		$GLOBALS['tami-payment-settings-output-ok'] = true;
		$url                                        = admin_url( 'admin.php?page=tami-admin' );
		$backgroundImage                            = \Tami\WooCommerce\TamiAdmin::get_assets( 'images/tami-white.svg' );
		echo sprintf( '<a href="%s" style="background: #44318b; background-image: url(\'%s\'); background-size:48px !important; background-repeat:no-repeat; background-position: 10px center; padding: 10px; padding-left: 65px; border-radius: 4px; color: #fff; text-decoration: none" type="submit" value="%s">%s</a>',
			esc_url( $url ),
			esc_attr( $backgroundImage ),
			esc_attr( $buttonLabel ),
			esc_attr( $buttonLabel )
		);
	}


	public static function get_success_url( $order = null ) {
		if ( ! is_null( $order ) && method_exists( $order, 'get_id' ) ) {
			$orderId = $order->get_id();
		} else {
			$orderId = '_orderId_';
		}

		if ( ! is_null( $order ) && method_exists( $order, 'get_order_key' ) ) {
			$orderKey = $order->get_order_key();
		} else {
			$orderKey = '_orderKey_';
		}

		$order_received_url = wc_get_endpoint_url( 'order-received', $orderId, wc_get_checkout_url() );

		return add_query_arg( 'key', $orderKey, $order_received_url );
	}

	public static function getCityName( $cityCode ): string {
		if ( substr( $cityCode, 0, 2 ) == 'TR' ) {

			$cities = WC()->countries->get_states( "TR" );

			if ( ! isset( $cities[ $cityCode ] ) ) {
				$i = 1;
				foreach ( $cities as $city ) {
					if ( $i > $cityCode ) {
						break;
					}
					if ( $i == $cityCode ) {
						$cityCode = $city;
					}
					$i ++;
				}
			} else {
				$cityCode = $cities[ $cityCode ];
			}
		}

		return $cityCode;
	}

	public function payment_object(): TamiPaymentClient {
		if ( ! class_exists( 'Tami\WooCommerce\TamiPaymentClient' ) ) {
			include TAMI_PLUGIN_PATH . '/TamiPaymentClient.php';
		}

		$debugMode   = ( TamiAdminSettings::get_module_settings( 'debug_mode', '0' ) == '1' );
		$apiSettings = TamiAdminSettings::get_api_settings( true );

		return ( new TamiPaymentClient() )
			->setTest( ( $apiSettings['environment'] ) == 'test' )
			->setPaymentMethod( $apiSettings['payment_method'] )
			->enableDebug( $debugMode )
			->setTerminalId( $apiSettings['terminal_id'] ?? '' )
			->setMerchantId( $apiSettings['merchant_id'] ?? '' )
			->setSecretKey( $apiSettings['secret_key'] ?? '' )
			->setApiVersion( $apiSettings['use_v3'] ? 'v3' : 'v2' )
			->setFixedKidValue( $apiSettings['kid_value'] ?? '' )
			->setFixedKValue( $apiSettings['k_value'] ?? '' );
	}

	public static function getBinNumber( $in ) {
		$bin = TamiPaymentClient::filterOnlyNumbers( $in );

		return apply_filters( 'tami_woocommerce_get_bin_number', substr( $bin, 0, 8 ), $in );
	}

	/**
	 * @throws Exception
	 */
	public function make_payment() {
		try {
			if ( ! isset( $_POST['tami-checkout-nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['tami-checkout-nonce'] ), 'tami_woocommerce_checkout_nonce' ) ) {
				Response::sendMessageToParent( [
					'status'  => false,
					'message' => __( 'Nonce unverified!', 'tami-payment' ),
				] );
			}
			$tami = $this->payment_object();

			$orderId = WC()->session->get( 'order_awaiting_payment' );
			if ( ! $orderId ) {
				$orderId = isset( $_POST['tami-checkout-order-id'] ) ? sanitize_text_field( wp_unslash( $_POST['tami-checkout-order-id'] ) ?? '' ) : '';
			}

			do_action( 'woocommerce_resume_order', $orderId );
			$order       = wc_get_order( $orderId );
			$installment = isset( $_POST['installment'] ) ? sanitize_text_field( wp_unslash( $_POST['installment'] ) ?? '1' ) : '1';

			if ( ! $this->installment_available(
				$order->get_total()
			) ) {
				$installment = '1';
			}


			$buyerId = $order->get_user_id();
			if ( ! $buyerId ) {
				$buyerId = $this->generateBuyerId();
			}

			$cardNumber     = isset( $_POST['cardNumber'] ) ? TamiPaymentClient::filterOnlyNumbers( sanitize_text_field( wp_unslash( $_POST['cardNumber'] ) ?? '' ) ) : '';
			$amount         = $this->calculateAmount( $order->get_total(), $installment, self::getBinNumber( $cardNumber ) );
			$installmentFee = 0;

			if ( $amount > $order->get_total() ) {
				$installmentFee = $amount - $order->get_total();
			}

			$data = [
				'order'      => [
					'orderId'               => TamiPaymentClient::encodeOrderId( $orderId ),
					'amount'                => $amount,
					'currency'              => $order->get_currency(),
					'buyerId'               => $buyerId,
					'email'                 => $order->get_billing_email(),
					'billingAddress'        => trim( sprintf( '%s %s', $order->get_billing_address_1(), $order->get_billing_address_2() ) ),
					'billingCity'           => self::getCityName( $order->get_billing_state() ),
					'billingCompany'        => $order->get_billing_company(),
					'billingCountry'        => $order->get_billing_country(),
					'billingEmailAddress'   => $order->get_billing_email(),
					'billingFirstname'      => $order->get_billing_first_name(),
					'billingLastname'       => $order->get_billing_last_name(),
					'billingPhone'          => $order->get_billing_phone(),
					'billingZipcode'        => $order->get_billing_postcode(),
					'billingDistrict'       => $order->get_billing_city(),
					'shippingAddress'       => trim( sprintf( '%s %s', $order->get_shipping_address_1(), $order->get_shipping_address_2() ) ),
					'shippingCity'          => self::getCityName( $order->get_shipping_state() ),
					'shippingCompany'       => $order->get_shipping_company(),
					'shippingCountry'       => $order->get_shipping_country(),
					'shippingContactName'   => trim( sprintf( '%s %s', $order->get_shipping_first_name(), $order->get_shipping_last_name() ) ),
					'shippingEmailAddress'  => $order->get_billing_email(),
					'shippingPhone'         => null,
					'shippingZipcode'       => $order->get_shipping_postcode(),
					'shippingDistrict'      => $order->get_shipping_city(),
					'billingIdentityNumber' => null
				],
				'card'       => [
					'number'      => $cardNumber,
					'expireMonth' => isset( $_POST['cardMonth'] ) ? TamiPaymentClient::filterOnlyNumbers( sanitize_text_field( wp_unslash( $_POST['cardMonth'] ) ?? '' ) ) : '',
					'expireYear'  => isset( $_POST['cardYear'] ) ? TamiPaymentClient::filterOnlyNumbers( sanitize_text_field( wp_unslash( $_POST['cardYear'] ) ?? '' ) ) : '',
					'cvv'         => isset( $_POST['cardCvv'] ) ? TamiPaymentClient::filterOnlyNumbers( sanitize_text_field( wp_unslash( $_POST['cardCvv'] ) ?? '' ) ) : '',
					'cardHolder'  => isset( $_POST['cardHolder'] ) ? sanitize_text_field( wp_unslash( $_POST['cardHolder'] ) ?? '' ) : ''
				],
				'payment'    => [
					'installmentCount' => $installment,
					'ipAddress'        => TamiPaymentClient::getClientIpAddress(),
					'basketId'         => sprintf( "BASKET_%s_%s", $order->get_order_number(), TamiPaymentClient::random_numbers( 5 ) )
				],
				'other'      => [
					'callback' => self::get_callback_url()
				],
				'cart_items' => $this->organizeCartItems( $order )
			];

			$extra   = [
				'installment_fee' => floatval( number_format( floatval( $installmentFee ), 2, '.', '' ) )
			];
			$preAuth = $tami->authRequest( $data, $extra );

			if ( $tami->getThreeDEnabled() ) {
				if ( isset( $preAuth->card ) ) {
					$order->update_meta_data( 'tami_threeD_started_card_info', wp_json_encode( $preAuth->card ) );
				}
				// save card data
				$threeDSHtmlContent = isset( $preAuth->threeDSHtmlContent ) ? base64_decode( $preAuth->threeDSHtmlContent ) : '';
				if ( $threeDSHtmlContent ) {
//					if(!$tami->authResponseHashIsValid($preAuth))
//					{
//						throw new \Exception(__('Response hash not valid!', 'tami-payment'));
//					}
					Response::sendHtmlResult( $threeDSHtmlContent );
				} else {
					Response::sendMessageToParent( [
						'status'  => false,
						'message' => __( 'threeDSHtmlContent data missing!', 'tami-payment' )
					] );
				}
			} else {
				if ( is_object( $preAuth ) && isset( $preAuth->success ) && $preAuth->success ) {
					$this->tami_order_success(
						$orderId,
						( $preAuth->orderId ?? 'TRANSACTION_ID_ERROR' ),
						( $preAuth->installmentCount ?? 'INSTALLMENT_COUNT_ERROR' ),
						( $preAuth->amount ?? $order->get_total() )
					);

					Response::sendMessageToParent( [
						'status'   => true,
						'message'  => '',
						'orderId'  => $order->get_id(),
						'orderKey' => $order->get_order_key()
					] );
				}
			}
			$order->save();
		} catch ( Exception $exception ) {
			do_action( 'tami_woocommerce_order_failed', $order->get_id(), $exception->getMessage() );
			Response::sendMessageToParent( [
				'status'  => false,
				'message' => $exception->getMessage()
			] );
		}
	}

	/**
	 * @throws Exception
	 */
	public function tami_order_success( $order_id, $trans_id, $installment = 1, $totalAmount = null ): bool {
		$order_status = TamiAdminSettings::get_module_settings( 'order_status', 'default' );
		$order        = wc_get_order( $order_id );
		if ( ! $order_status ) {
			$order_status = 'default';
		}

		if ( ! method_exists( $order, 'get_id' ) ) {
			throw new Exception( esc_html( __( 'Order could not found!', 'tami-payment' ) ) );
		}
		if (
			intval( $installment ) > 1 &&
			floatval( $order->get_total() ) < floatval( $totalAmount )
		) {
			$amountOfFee = floatval( $totalAmount ) - floatval( $order->get_total() );
			$item_fee    = new WC_Order_Item_Fee();
			/* translators: %d is replaced with installment number */
			$label = __( 'Payment Fee (%d Installments)', 'tami-payment' );
			$item_fee->set_name( sprintf( $label, $installment ) );
			$item_fee->set_amount( $amountOfFee );
			$item_fee->set_total( $amountOfFee );
			$item_fee->set_total_tax( $amountOfFee );
			$item_fee->set_tax_status( 'none' );
			$item_fee->save();
			$order->add_item( $item_fee );
			$order->calculate_totals();
		}

		if ( $order_status === 'default' ) {
			$order->payment_complete( $trans_id );
			$order->add_order_note(
				sprintf(
				/* translators: %1$s is replaced with order ID, %2$s is replaced with payment transaction ID */
					__( '%1$s payment completed with Transaction Id of "%2$s"', 'tami-payment' ),
					$order->get_id(),
					$trans_id
				)
			);
		} else {
			$order->set_transaction_id( $trans_id );
			$order->update_status(
				str_replace( 'wc-', '', $order_status ),
				sprintf(
				/* translators: %1$s is replaced with order ID, %2$s is replaced with payment transaction ID */
					__( '%1$s payment completed with Transaction Id of %2$s', 'tami-payment' ),
					$order->get_id(),
					$trans_id
				)
			);
		}


		WC()->cart->empty_cart();

		if ( $this->payment_object()->isTest() ) {
			$order->update_meta_data( 'tami_test_environment_payment', '1' );
		}
		do_action( 'tami_woocommerce_order_completed_success', $order_id, [
			'transaction_id' => $trans_id,
			'order_id'       => $order_id,
			'installment'    => $installment,
			'amount'         => $totalAmount
		] );
		$order->save();

		return true;
	}

	public function callback() {
		try {
			/* if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['nonce'] ) ), \Tami_WooCommerce_GW::CALLBACK_ENDPOINT ) ) {
				throw new \Exception( esc_attr__( 'Nonce could not verified!', 'tami-payment' ) );
			} */

			$tami        = $this->payment_object();
			$result      = $tami->callback();
			$trans_id    = $result['transactionId'] ?? '';
			$order_id    = $result['orderId'] ?? '';
			$installment = $result['installment'] ?? '';
			$totalAmount = $result['amount'];

			$this->tami_order_success(
				$order_id,
				$trans_id,
				$installment,
				$totalAmount
			);

			$order          = wc_get_order( $order_id );
			$successPageUrl = self::get_success_url( $order );
			Response::sendMessageToParent( [
				'status'   => true,
				'message'  => '',
				'orderId'  => $order->get_id(),
				'orderKey' => $order->get_order_key()
			], $successPageUrl );
			exit;

		} catch ( Exception $exception ) {
			$order_id = isset( $_POST['orderId'] ) ? sanitize_text_field( wp_unslash( $_POST['orderId'] ) ?? '' ) : '';
			if ( $order_id ) {
				$order_id = TamiPaymentClient::decodeOrderId( $order_id );
				do_action( 'tami_woocommerce_order_failed', $order_id, $exception->getMessage() );
				Response::sendMessageToParent( [
					'status'  => false,
					'message' => $exception->getMessage()
				] );
			}
		}

	}


	function init_form_fields() {
		$this->form_fields = array(
			'enabled' => array(
				'title'    => __( 'Enable / Disable', 'tami-payment' ),
				'desc_tip' => __( 'Enable payment gateway.', 'tami-payment' ),
				'type'     => 'checkbox',
				'default'  => 'yes'
			),
			'title'   => array(
				'title'    => __( 'Title', 'tami-payment' ),
				'desc_tip' => __( 'Enter title for checkout page.', 'tami-payment' ),
				'type'     => 'text',
				'default'  => __( 'Credit Card Payment', 'tami-payment' )
			)/*,
            'description' => array(
                'title' => __('Description', 'tami-payment'),
                'desc_tip' => __('Enter description for checkout page.', 'tami-payment'),
                'type' => 'text',
                'default' => __('Make online payment with your credit or debit card.', 'tami-payment')
            )*/
		);
	}

	public function installment_available( $amount = '' ) {
		if ( ! $amount ) {
			return true;
		}
		$installment_settings = TamiAdminSettings::get_installment_settings();
		if ( isset( $installment_settings['minimum_installment_amount'] ) ) {
			$minimum_data = $installment_settings['minimum_installment_amount'];
			if ( $minimum_data == '-1' ) {
				$minimum_data = 0;
			}
		} else {
			$minimum_data = 0;
		}
		$available = ! ( $minimum_data && floatval( $minimum_data ) > floatval( $amount ) );

		return apply_filters( 'tami_woocommerce_installment_available', $available );
	}

	public function installment( $bin = '', $amount = '', $returnType = 'html' ) {
		$nonce = isset( $_GET['nonce'] ) ? sanitize_text_field( wp_unslash( $_GET['nonce'] ) ) : '';
		if ( ! wp_verify_nonce( $nonce, 'tami-checkout' ) && $returnType !== 'object' ) {
			throw new \Exception( 'Nonce verification failed!' );
		}

		if ( ! $bin ) {
			$bin = isset( $_GET['bin'] ) ? sanitize_text_field( wp_unslash( $_GET['bin'] ) ?? '' ) : '';
		}
		if ( ! $amount ) {
			$amount = isset( $_GET['amount'] ) ? sanitize_text_field( wp_unslash( $_GET['amount'] ) ?? '' ) : '';
		}
		$data = [
			'bin'    => TamiPaymentClient::filterOnlyNumbers( $bin ),
			'amount' => (float) ( $amount ),
		];

		$ratesFormatted = [ '1' => 0 ];
		if ( ! $this->installment_available( $data['amount'] ) ) {
			$response = [
				'status' => true,
				'rates'  => $ratesFormatted
			];
		} else {
			$rates = TamiAdminSettings::get_installment_settings();
			if (
				! ( isset( $rates['installments_enabled'] ) && $rates['installments_enabled'] == '1' )
			) {
				$response = [
					'status' => true,
					'rates'  => $ratesFormatted
				];
			} else {
				try {
					$tami     = $this->payment_object();
					$binCheck = $tami->getInstallmentInfo( $data['bin'] );

					if ( ! isset( $binCheck->success ) || ! $binCheck->success ) {
						$msg = $binCheck->errorMessage ?? __( 'Invalid installment list!', 'tami-payment' );
						throw new \Exception( $msg );
					}

					// simulation start
//					$binCheck = (object) [
//						'installments' => [1,3,5]
//					];
					// simulation end
					$installments = $binCheck->installments ?? [];
					foreach ( $rates as $k => $rate ) {
						if ( $rate === '-1' ) {
							continue;
						}
						if ( in_array( $k, [ 'minimum_installment_amount', 'installments_enabled' ] ) ) {
							continue;
						}
						$rateKey = str_replace( 'installment_', '', $k );
						if ( ! in_array( $rateKey, $installments ) ) {
							continue;
						}
						$ratesFormatted[ $rateKey ] = (float) number_format( $rate, 2 );
					}
					$response = [
						'status' => true,
						'rates'  => $ratesFormatted
					];
				} catch ( Exception $exception ) {
					$response = [
						'status' => false,
						'rates'  => $ratesFormatted
					];
				}
			}
		}
		$result = apply_filters( 'tami_woocommerce_installment_query_response', $response );
		if ( $returnType === 'object' ) {
			return $result;
		}

		Response::json_output( $result );

		return true;
	}

	public static function get_payment_url() {
		$url = wp_sanitize_redirect(
			esc_url_raw(
				add_query_arg( 'wc-api', self::MAKE_PAYMENT_ENDPOINT, trailingslashit( get_home_url() ) )
			)
		);

		return apply_filters( 'tami_woocommerce/wc_api_payment_url', $url );
	}

	public static function get_callback_url() {
		$url = wp_sanitize_redirect(
			esc_url_raw(
				add_query_arg( array(
					'wc-api' => self::CALLBACK_ENDPOINT,
					'nonce'  => wp_create_nonce( self::CALLBACK_ENDPOINT )
				), trailingslashit( get_home_url() ) )
			)
		);

		return apply_filters( 'tami_woocommerce/wc_api_callback_url', $url );
	}

	public static function get_installment_url() {
		$url = wp_sanitize_redirect(
			esc_url_raw(
				add_query_arg( 'wc-api', self::INSTALLMENT_ENDPOINT, trailingslashit( get_home_url() ) )
			)
		);

		return apply_filters( 'tami_woocommerce/wc_api_installment_url', $url );
	}

	/**
	 * @return boolean
	 */
	protected function is_enabled() {
		return false;
	}

	public static function get_tami_hidden_form( $order_id ): string {
		$tami_form = '<div style="display:none">';
		$tami_form .= ( '<input type="hidden" name="tami-checkout-status" id="tami-checkout-status" value="1" />' );
		$tami_form .= sprintf( '<input type="hidden" name="tami-order-id" id="tami-order-id" value="%s" />', $order_id );
		$tami_form .= sprintf( '<input type="hidden" name="tami-checkout-nonce" id="tami-checkout-nonce" value="%s" />', wp_create_nonce( 'tami_woocommerce_checkout_nonce' ) );
		$tami_form .= '</div>';

		return $tami_form;
	}

	public function isPageBlockPayment( $pageId = null ): bool {
		if ( is_null( $pageId ) ) {
			$pageId = get_option( 'woocommerce_checkout_page_id' );
		}
		$pageItem    = get_post( $pageId );
		$pageContent = $pageItem->post_content;

		return strpos( $pageContent, '<!-- wp:woocommerce/checkout-payment-block -->' ) !== false;
	}

	/**
	 * @throws Exception
	 */
	public function process_payment( $order_id ): array {
		$order = wc_get_order( $order_id );
		if ( $this->payment_object()->getPaymentMethod() === 'Commonpayment' ) {
			$tami              = $this->payment_object();
			$hostedPaymentLink = $tami->generateOneTimeHostedToken( [
				'amount'      => $order->get_total(),
				'phonenumber' => $order->get_billing_phone(),
				'callback'    => self::get_callback_url(),
				'orderid'     => TamiPaymentClient::encodeOrderId( $order_id )
			] );

			return [
				'result'    => 'success',
				'redirect'  => $hostedPaymentLink,
				'reload'    => false,
				'tami_data' => [
					'tami_enabled' => true
				],
				'messages'  => '<div id="tami-processs-data">' .
				               '<p>' . __( 'Your payment continue...', 'tami-payment' ) . '</p>' .
				               '</div>'
			];
		}
		$tami_form            = self::get_tami_hidden_form( $order_id );
		$checkout_payment_url = $order->get_checkout_payment_url( true );

		return [
			'result'    => 'success',
			'redirect'  => $this->isPageBlockPayment() ? $checkout_payment_url : false,
			'reload'    => false,
			'tami_data' => [
				'tami_enabled' => true
			],
			'messages'  => '<div id="tami-processs-data">' .
			               '<p>' . __( 'Your payment continue...', 'tami-payment' ) . '</p>' .
			               $tami_form .
			               '</div>'
		];
	}

	public static function receipt_page( $order_id ) {
		if ( isset( $GLOBALS['form_loaded'] ) ) {
			return false;
		}
		$GLOBALS['form_loaded'] = true;
		$order                  = new WC_Order( $order_id );
		$order_price            = $order->get_total();

		echo '<div class="tami-receipt-page-container">';
		$cl = new Tami_WooCommerce_GW();
		echo '<form action="" id="tami-checkout-receipt-page-form" name="tami-checkout-receipt-page-form" method="post">';
		$cl->payment_fields();
		echo '<input type="hidden" name="tami-checkout-status" id="tami-checkout-status" value="1" />';
		echo '<input type="hidden" name="tami-order-id" id="tami-order-id" value="' . esc_attr( $order_id ) . '" />';
		echo '<input type="hidden" name="tami-checkout-nonce" id="tami-checkout-nonce" value="' . esc_attr( wp_create_nonce( 'tami_woocommerce_checkout_nonce' ) ) . '" />';
		echo '<div class="tami-button-container">' .
		     '<button form="tami-checkout-receipt-page-form" type="submit">' . esc_html__( 'Make Payment', 'tami-payment' ) . '</button>';
		echo '</div>';
		echo '</form>';
		echo '</div>';
	}

	public function payment_fields() {
		if ( $this->payment_object()->getPaymentMethod() === 'Commonpayment' ) {
			echo esc_html__( 'Your card information will be collected in the next step.', 'tami-payment' );

			return false;
		}

		$pay_for_order_page    = isset( $_GET['pay_for_order'] ) ? sanitize_text_field( wp_unslash( $_GET['pay_for_order'] ) ?? '' ) : '';// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$payment_key           = isset( $_GET['key'] ) ? sanitize_text_field( wp_unslash( $_GET['key'] ) ?? '' ) : '';// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$customer_payment_page = ( $pay_for_order_page && $payment_key );
		if ( $customer_payment_page ) {
			global $wp;
			$orderId = $wp->query_vars['order-pay'];
			echo wp_kses( self::get_tami_hidden_form( $orderId ), [
				'div'   => [ 'style' => [] ],
				'input' => [ 'name' => [], 'id' => [], 'type' => [], 'value' => [] ]
			] );
		}

		echo '<div id="tamiCreditCardFormApp"></div>';
		echo '<div id="tamiCreditCardFormPopup">';

		$template_name = 'popup.php';
		$default_path  = TAMI_PLUGIN_PATH . '/checkout/views/';


		$args = [
			'data'         => $data,
			'redirect_url' => $redirectUrl
		];

		wc_get_template( $template_name, $args, '', $default_path );

		echo '</div>';
	}

	public static function add_method_to_wc( $methods ): array {
		$methods[] = __CLASS__;

		return $methods;
	}

	public static function add_head_scripts() {
		wp_add_inline_script( 'jquery', 'var tamiCommonPageEnabled = true;' );
	}

	public function needs_setup() {
		$api_settings = TamiAdminSettings::get_api_settings( true );

		return ( empty( $api_settings['merchant_id'] ) || empty( $api_settings['terminal_id'] ) || empty( $api_settings['secret_key'] ) );
	}

	private function generateBuyerId(): string {
		$ip_address = TamiPaymentClient::getClientIpAddress();
		$ip_address = str_replace( '.', '', $ip_address );

		return sprintf( "VISITOR_%s", $ip_address );
	}

	/**
	 * @throws Exception
	 */
	private function calculateAmount( $get_total, $installment, $binNumber ) {
		$installmentRates = $this->installment( $binNumber, $get_total, 'object' );
		/* translators: %d is replaced with installment number */
		$message = __( '%d installment rate not defined!', 'tami-payment' );
		if ( ! isset( $installmentRates['rates'] ) || ! isset( $installmentRates['rates'][ $installment ] ) ) {
			throw new Exception( sprintf( esc_attr( $message ), esc_attr( $installment ) ) );
		}
		$installmentRate = floatval( $installmentRates['rates'][ $installment ] );
		$amount          = $get_total / ( ( 100 - $installmentRate ) / 100 );
		$amount          = floatval( number_format( $amount, 2, '.', '' ) );

		return apply_filters( 'tami_woocommerce_get_amount', $amount, $installment, $binNumber );
	}

	public function process_refund( $order_id, $amount = null, $reason = '' ) {
		do_action( 'tami_woocommerce_before_refund', $order_id, $amount, $reason );
		$order      = wc_get_order( $order_id );
		$funcReturn = false;
		if ( ! is_a( $order, '\WC_Order' ) ) {
			$funcReturn = new WP_Error( 'order-not-detect', __( 'Please check order is valid!', 'tami-payment' ) );
		}

		if ( ! $funcReturn ) {
			try {
				$tami           = $this->payment_object();
				$transaction_id = $order->get_transaction_id();
				$refund_result  = $tami->refund( $transaction_id, $amount, $reason );
				$order->update_meta_data( 'tami_refund_amount', $refund_result->amount );
				$order->update_meta_data( 'tami_refund_completed_time', time() );
				$order->save();
				do_action( 'tami_woocommerce_refund_completed', $refund_result, $order_id, $amount );
				$funcReturn = floatval( $amount ) === floatval( $refund_result->amount );
			} catch ( Exception $exception ) {
				do_action( 'tami_woocommerce_refund_failed', $order_id, $amount, $exception->getMessage() );

				$funcReturn = new WP_Error( 'other-exception', $exception->getMessage() );
			}
			do_action( 'tami_woocommerce_after_refund', $order_id, $amount, $reason );
		}

		return $funcReturn;
	}

	private function organizeCartItems( $order ) {
		$user_basket = array();
		if ( sizeof( $order->get_items() ) > 0 ) {
			foreach ( $order->get_items() as $item ) {
				if ( $item['qty'] ) {
					$product = $item->get_product();

					$item_name = $item['name'];

					// WC_Order_Item_Meta is deprecated since WooCommerce version 3.1.0
					if ( defined( 'WOOCOMMERCE_VERSION' ) && version_compare( WOOCOMMERCE_VERSION, '3.1.0', '>=' ) ) {
						$item_name .= wc_display_item_meta( $item, array(
							'before'    => '',
							'after'     => '',
							'separator' => ' | ',
							'echo'      => false,
							'autop'     => false
						) );
					} else {
						$item_meta = new WC_Order_Item_Meta( $item['item_meta'] );
						if ( $meta = $item_meta->display( true, true ) ) {
							$item_name .= ' ( ' . $meta . ' )';
						}
					}

					$item_name = wp_strip_all_tags( $item_name );
					if ( strlen( $item_name ) > 50 ) {
						$item_name = substr( $item_name, 0, 50 );
					}

					$item_total_inc_tax = $item->get_total();
					$item_total_inc_tax += $item->get_total_tax();

					$sku = '';

					if ( $product->get_sku() ) {
						$sku = '[SKU:' . $product->get_sku() . ']';
					}

					$user_basket[] = array(
						'id'          => $product->get_id(),
						'type'        => ( $product->is_virtual() ? 'VIRTUAL' : 'PHYSICAL' ),
						'name'        => trim( str_replace( ':', ' = ', $sku ) . ' ' . $item_name ),
						'category'    => '',
						'subCategory' => '',
						'unitPrice'   => ( $item_total_inc_tax / $item->get_quantity() ),
						'totalPrice'  => $item_total_inc_tax,
						'quantity'    => $item->get_quantity()
					);
				}
			}

			$shippingFee = $order->get_shipping_total();
			$shippingFee += $order->get_shipping_tax();
			if ( $shippingFee ) {
				$user_basket[] = [
					'id'          => 'SHIPPING',
					'type'        => ( 'PHYSICAL' ),
					'name'        => __( 'Shipping', 'tami-payment' ),
					'category'    => '',
					'subCategory' => '',
					'unitPrice'   => $shippingFee,
					'totalPrice'  => $shippingFee,
					'quantity'    => 1
				];
			}

			return $user_basket;
		}
	}

}
