<?php
/**
 * Ideal
 *
 * Payment type     : Online banking
 * Payment flow     : Redirect
 * Countries        : NL
 * Currencies       : EUR
 */

namespace WkwcAdyen\Includes\Payment_Methods;

// prevent direct access data leaks
defined( 'ABSPATH' ) || exit;

use Automattic\WooCommerce\StoreApi\Utilities\NoticeHandler;

use WkwcAdyen\Helper\Common\Wkwc_Adyen_Service_Util;

use WkwcAdyen\Helper\Common\Wkwc_Adyen_Checkout_Action;

class Wkwc_Adyen_Klarna_Ideal extends Wkwc_Adyen_Abstract_Gateway {

	/**
	 * $checkout_action
	 *
	 * @var Wkwc_Adyen_Checkout_Action
	 */
	public $checkout_action;

	/**
	 * Constructor of this class.
	 *
	 * @param bool $init_hooks
	 * @since 1.1.0
	 */
	public function __construct( $init_hooks = true ) {

		parent::__construct( $init_hooks );

		$this->has_fields = false;

		$this->supports = array(
			'products',
			'refunds',
		);

		$this->checkout_action = new Wkwc_Adyen_Checkout_Action();
	}

	/**
	 * List of countries where is available.
	 *
	 * @since 1.1.0
	 * @return array
	 */
	public function available_countries() {

		return array(
			'NL' => array(
				'currencies' => array( 'EUR' ),
			),
		);
	}

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

	/**
	 * Gets default payment method description.
	 *
	 * @since 1.1.0 - display supported countries
	 * @since 1.0.0
	 * @return string
	 */
	public function get_default_description() {
		return sprintf( __( 'To enable recurring payments with iDeal, you must first activate SEPA Direct Debit functionality. %s', 'wkwc-adyen' ), '<br/>' . $this->show_supported_country() );
	}

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



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

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

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

		parent::payment_fields();

		echo $this->generate_extra_fields_html();
	}

	/**
	 * Validates extra added fields.
	 *
	 * @since 1.0.0
	 * @return bool
	 */
	public function validate_fields() {

		$is_valid = parent::validate_fields();

		$issuer = $_POST[ WKWC_ADN_PREFIX . '_' . $this->payment_method_type() . '_issuer' ];

		if ( empty( $issuer ) ) {
			$is_valid = false;
			wc_add_notice( __( 'Please select your bank account.', 'wkwc-adyen' ), 'error' );
		}

		return $is_valid;
	}


	/**
	 * Generates extra fields HTML.
	 *
	 * @since 1.1.0 - added CSS class
	 * @since 1.0.0
	 * @return string
	 */
	public function generate_extra_fields_html() {
		?>
		<div id="<?php echo esc_attr( 'wkwc-adyen-' . $this->payment_method_type() . '-container' ); ?>"></div>
		<input type="hidden" id="<?php echo esc_attr( 'wkwc-adyen_' . $this->payment_method_type() . '_issuer' ); ?>" name="<?php echo esc_attr( WKWC_ADN_PREFIX . '_' . $this->payment_method_type() . '_issuer' ); ?>">
		<?php
	}

	/**
	 * Builds the required payment payload
	 *
	 * @since 1.1.0 - use parent function to get common data
	 * @since 1.0.0
	 * @param \WC_Order $order
	 * @param string    $reference
	 * @return array
	 */
	public function build_payment_payload( \WC_Order $order, $reference ) {

		$issuer = $_POST[ WKWC_ADN_PREFIX . '_' . $this->payment_method_type() . '_issuer' ];

		$payload = parent::build_payment_payload( $order, $reference );

		$payload['paymentMethod']['issuer'] = $issuer;

		return $payload;
	}

	/**
	 * Processes the payment.
	 *
	 * @since 1.1.0 - replace `_#subscription#_` with `-S`
	 * @since 1.0.7 - use \WC_Order instance to manipulate metadata
	 * @since 1.0.0
	 * @param int $order_id
	 * @return array
	 */
	public function process_payment( $order_id ) {

		parent::process_payment( $order_id );

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

		$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.
	 *
	 * @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'];

		$extra_action_codes = array( 'RedirectShopper' );
		$error_codes        = array( 'Refused', 'Error', 'Cancelled' );

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

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

		if ( in_array( $result_code, $extra_action_codes ) ) {

			// 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 )
				),
			);

		} elseif ( in_array( $result_code, $error_codes ) ) {

			wc_add_notice( __( 'The transaction could not be processed! Either it has been refused or an error has occurred! Please make sure you provide a valid bank account.', 'wkwc-adyen' ), 'error' );

			NoticeHandler::convert_notices_to_exceptions( 'woocommerce_rest_payment_error' );

			$result = array(
				'result' => 'failure',
			);

		}

		return $result;
	}
}
