<?php
/**
 * Google Pay
 */

namespace WkwcAdyen\Includes\Payment_Methods;

// prevent direct access data leaks
use Automattic\WooCommerce\StoreApi\Utilities\NoticeHandler;

defined( 'ABSPATH' ) || exit;

use WkwcAdyen\Helper\Common\Wkwc_Adyen_Service_Util;

use WkwcAdyen\Helper\Common\Wkwc_Adyen_Checkout_Action;

class Wkwc_Adyen_Applepay extends Wkwc_Adyen_Abstract_Gateway {

	/**
	 * Checkout action instance
	 *
	 * @var Wkwc_Adyen_Checkout_Action
	 */
	public $checkout_action;

	/**
	 * Constructor of this class.
	 *
	 * @param bool $init_hooks
	 * @since 1.0.4
	 * @since 1.1.0 - add support for subscriptions
	 */
	public function __construct( $init_hooks = true ) {
		parent::__construct( $init_hooks );
		$this->checkout_action = new Wkwc_Adyen_Checkout_Action();
		$this->has_fields      = true;
	}

	/**
	 * Gets default payment method title.
	 *
	 * @return string
	 */
	public function get_default_title() {
		return __( 'Adyen - Apple Pay', 'wkwc-adyen' );
	}

	/**
	 * Gets default payment method description.
	 *
	 * @since 1.1.0 - display supported countries
	 * @since 1.0.4
	 * @return string
	 */
	public function get_default_description() {
		return $this->show_supported_country();
	}

	/**
	 * Gets default description set in settings.
	 *
	 * @return string
	 */
	public function get_settings_description() {
		$this->description = ( $this->settings['description'] ) ? $this->settings['description'] : __( 'Pay with apple pay', 'wkwc-adyen' );
		return $this->description;
	}



	/**
	 * Type of the payment method (e.g ideal, scheme. bcmc).
	 *
	 * @return string
	 */
	public function payment_method_type() {
		return 'applepay';
	}

	/**
	 * Returns the payment method to be used for recurring payments
	 *
	 * @return string
	 */
	public function recurring_payment_method() {}

	/**
	 * Adds an array of fields to be displayed on the gateway's settings screen.
	 *
	 * @since 1.1.0
	 * @return void
	 */
	public function init_form_fields() {

		$is_enabled = parent::init_form_fields();

		if ( $is_enabled === false ) {
			return;
		}

		if ( 'applepay' === $this->payment_method_type() ) {
			$this->form_fields = array_merge(
				$this->form_fields,
				array(
					'apple_token_error'           => array(
						'title'       => __( 'Token Error', 'wkwc-adyen' ),
						'type'        => 'text',
						'description' => __( 'Provide a token error message to display as an error for the Apple token', 'wkwc-adyen' ),
					),
					'no_apple_device_description' => array(
						'title'       => __( 'Description for Non-Apple Devices', 'wkwc-adyen' ),
						'type'        => 'text',
						'description' => __( 'Provide a description message to display for non-Apple devices.', 'wkwc-adyen' ),
						'default'     => __( 'Please choose an apple device', 'wkwc-adyen' ),
					),
					'config_desc'                 => array(
						'title' => '',
						'label' => '',
						'type'  => 'config_desc',
					),
				)
			);
		}
	}

	/**
	 * Generates the HTML for `config_desc` field type
	 *
	 * @since 1.1.0
	 * @return string
	 */
	public function generate_config_desc_html() {
		ob_start();
		?>
		<tr valign="top">
		<td colspan="2" class="forminp" style="padding: 0;">
			<h3><?php _e( 'Configuration', 'wkwc-adyen' ); ?></h3>
			<ol>
				<li>
					<p><?php printf( __( 'Download and unzip the %1$sAdyen\'s Apple Pay certificate%2$s', 'wkwc-adyen' ), '<a href="https://docs.adyen.com/payment-methods/apple-pay/web-component/apple-developer-merchantid-domain-association-2024.zip" target="_blank">', '</a>' ); ?></p>
				</li>
				<li>
					<p><?php printf( __( 'Host the certificate file with the name %1$sapple-developer-merchantid-domain-association%2$s on each domain you want to use, including subdomains, under the following path: %3$s', 'wkwc-adyen' ), '<b>', '</b>', '<code>/.well-known/apple-developer-merchantid-domain-association</code>' ); ?></p>
					<p><?php _e( 'The file must:', 'wkwc-adyen' ); ?></p>
					<ul style="list-style: disc;padding-left: 20px;">
					<li><?php _e( 'Be externally accessible.', 'wkwc-adyen' ); ?></li>
					<li><?php _e( 'Not be password protected.', 'wkwc-adyen' ); ?></li>
					<li><?php _e( 'The file cannot be behind a proxy or redirect.', 'wkwc-adyen' ); ?></li>
					</ul>
					<p><?php printf( __( 'See an example of a %1$sworking certificate file.%2$s', 'wkwc-adyen' ), '<a href="https://eu.adyen.link/.well-known/apple-developer-merchantid-domain-association" target="_blank">', '</a>' ); ?></p>
				</li>
				<li>
					<p><?php printf( __( '%1$sAdd Apple Pay in your live Customer Area%2$s, where you will be asked for:', 'wkwc-adyen' ), '<a href="https://docs.adyen.com/payment-methods/add-payment-methods/" target="_blank">', '</a>' ); ?></p>
					<ul style="list-style: disc;padding-left: 20px;">
					<li><b>Shop website:</b> <?php printf( __( 'your main website URL, for example %s.', 'wkwc-adyen' ), '<code>https://www.mystore.com</code>' ); ?></li>
					<li><b>Additional shop websites:</b> <?php printf( __( 'Add any other domains you use for your shop website, for example %1$s, or %2$s. You must register all top-level domains and subdomains.', 'wkwc-adyen' ), '<code>https://www.mystore1.com</code>', '<code>https://www.mystore1.com</code>' ); ?></li>
					</ul>
				</li>
			</ol>
		</td>
		</tr>
		<?php
		return ob_get_clean();
	}

	/**
	 * Adds extra fields.
	 *
	 * @return void
	 */
	public function payment_fields() {

		parent::payment_fields();

		echo $this->generate_extra_fields_html();
	}

	/**
	 * Generates extra fields HTML.
	 *
	 * @return string
	 */
	public function generate_extra_fields_html() {
		?>
		<div id="wkwc-adyen-applepay-container"></div>
		<input type="hidden" id="<?php echo esc_attr( $this->id . '_token' ); ?>" name="<?php echo esc_attr( $this->id . '_token' ); ?>">
		<?php
	}


	/**
	 * Validates extra added fields.
	 *
	 * @return bool
	 */
	public function validate_fields() {
		wkwc_adn_log( 'Apple Pay Request data: ' . print_r( $_POST, true ) );
		$is_valid = parent::validate_fields();
		$token    = $_POST[ $this->id . '_token' ];

		if ( empty( $token ) ) {
			$apple_token_error = $this->get_option( 'apple_token_error' );
			wc_add_notice( $apple_token_error, 'error' );
			$is_valid = false;
		}

		return $is_valid;
	}



	/**
	 * Builds the required payment payload
	 *
	 * @param \WC_Order $order
	 * @param string    $reference
	 * @return array
	 */
	public function build_payment_payload( \WC_Order $order, $reference ) {

		$token = stripslashes( $_POST[ $this->id . '_token' ] );

		$payload = array_merge(
			parent::build_payment_payload( $order, $reference ),
			array(
				'paymentMethod' => array(
					'type'           => $this->payment_method_type(),
					'applepay.token' => $token,
				),
			)
		);

		return $payload;
	}



	/**
	 * Processes the payment.
	 *
	 * @param int $order_id Order ID.
	 * @return array
	 */
	public function process_payment( $order_id ) {

		parent::process_payment( $order_id );

		$order = wc_get_order( $order_id );

		$payload = $this->build_payment_payload( $order, $order_id );

		$response = $this->checkout_action->send_payment( $payload );

		if ( $response->status == 200 ) {

			return $this->process_payment_result( $response, $order );

		} else {

			wc_add_notice( $response->body['message'], 'error' );

			NoticeHandler::convert_notices_to_exceptions( 'woocommerce_rest_payment_error' );

		}

		return array( 'result' => 'failure' );
	}



	/**
	 * Processes the payment result.
	 *
	 * @since 1.3.2
	 * @param object    $response
	 * @param \WC_Order $order
	 * @return array
	 */
	protected function process_payment_result( $response, $order ) {

		$body_response = $this->adyen_helper::wkwc_adyen_obj_to_arr( $response->body );
		$result_code   = $body_response['resultCode'];
		$action        = $body_response['action'];

		$result = array(
			'result'   => 'success',
			'redirect' => Wkwc_Adyen_Service_Util::get_return_page_url( $order, $result_code ),
		);

		$result_code = $body_response['resultCode'];
		$reference   = $body_response['pspReference'];
		$action      = $body_response['action'];

		$order->read_meta_data();

		$order_psp_reference = $order->get_meta( '_' . WKWC_ADN_PREFIX . '_payment_pspReference' );

		if ( $order_psp_reference !== $reference ) {

			$order->update_meta_data( '_' . WKWC_ADN_PREFIX . '_refund_pspReference', $reference );
		}

		$order->update_meta_data( '_' . WKWC_ADN_PREFIX . '_payment_resultCode', $result_code );
		$order->update_meta_data( '_' . WKWC_ADN_PREFIX . '_payment_action', $action );
		$order->save();

		if ( 'RedirectShopper' == $result_code ) {

			// redirect to process payment action via Web Component
			$result = array(
				'result'   => 'success',
				'redirect' => add_query_arg(
					array(
						WKWC_ADN_PREFIX . '_payment_method' => $this->payment_method_type(),
						WKWC_ADN_PREFIX . '_order_id' => $order->get_id(),
					),
					Wkwc_Adyen_Service_Util::get_checkout_url( $order )
				),
			);

		}

		// Payment went through.
		if ( 'Authorised' === $result_code ) {
			$order->update_meta_data( '_woocommerce_' . $this->payment_method_type() . '_payment_data', $body_response );

			if ( $this->adyen_config->wkwc_adyen_is_capture_immediately() ) {
				$order->update_meta_data( '_wkwc_adyen_payment_captured', 'yes' );
				$order->payment_complete();
				/* translators: %s: is Transaction reference */
				$order->set_transaction_id( $reference );
				$order->add_order_note( sprintf( __( 'Payment was complete via Adyen (PSP Reference: %s)', 'wkwc-adyen' ), $this->adyen_helper->wkwc_adyen_get_adyen_transaction_url( $reference ) ) );
				$order->save();
			} else {
				$order->update_status( 'on-hold', __( 'Payment was successful via Adyen', 'wkwc-adyen' ) );
			}
		}

		return $result;
	}
}
