<?php
namespace Krokedil\Swedbank\Pay\CheckoutFlow;

use SwedbankPay\Checkout\WooCommerce\Swedbank_Pay_Subscription;
use WC_Order;

defined( 'ABSPATH' ) || exit;

/**
 * Class for processing the redirect checkout flow on the shortcode checkout page and pay for order pages.
 */
class Redirect extends CheckoutFlow {
	/**
	 * Process the payment for the WooCommerce order.
	 *
	 * @param \WC_Order   $order The WooCommerce order to be processed.
	 * @param string|null $instrument The instrument to use for the payment, e.g. 'CreditCard'. This is optional and may not be needed for all flows or gateways.
	 *
	 * @throws \Exception If there is an error during the payment processing.
	 * @return array{redirect: array|bool|string, result: string}
	 */
	public function process( $order, $instrument = null ) {
		$has_subscription = Swedbank_Pay_Subscription::order_has_subscription( $order );
		if ( $has_subscription || ( Swedbank_Pay_Subscription::is_change_payment_method() && $has_subscription ) ) {
			return $this->process_subscription( $order, $instrument );
		}

		if ( swedbank_pay_is_zero( $order->get_total() ) ) {
			throw new \Exception( 'Zero order is not supported.' );
		}

		// Initiate Payment Order.
		$result = $this->api->initiate_purchase( $order, $instrument );
		if ( is_wp_error( $result ) ) {
			throw new \Exception(
				esc_html( $result->get_error_message() ?? __( 'The payment could not be initiated.', 'swedbank-pay-payment-menu' ) ),
				absint( $result->get_error_code() )
			);
		}

		$redirect_url  = $result->getOperationByRel( 'redirect-checkout', 'href' );
		$payment_order = $result->getResponseResource()->getPaymentOrder();

		// Save payment ID.
		$order->update_meta_data( '_payex_paymentorder_id', $payment_order->getId() );
		$order->save_meta_data();

		return array(
			'result'   => 'success',
			'redirect' => $redirect_url,
		);
	}

	/**
	 * Process a subscription purchase.
	 *
	 * @param \WC_Order   $order The WooCommerce order to be processed.
	 * @param string|null $instrument The instrument to use for the payment, e.g. 'CreditCard'. This is optional and may not be needed for all flows or gateways.
	 *
	 * @throws \Exception If there is an error during the payment processing.
	 * @return array{redirect: array|bool|string, result: string}
	 */
	private function process_subscription( $order, $instrument = null ) {
		$result = swedbank_pay_is_zero( $order->get_total() ) ? Swedbank_Pay_Subscription::approve_for_renewal( $order ) : $this->api->initiate_purchase( $order, $instrument );
		if ( is_wp_error( $result ) ) {
			throw new \Exception(
				// translators: %s: order number.
				esc_html( sprintf( __( 'The payment change could not be initiated. Please contact store, and provide them the order number %s for more information.', 'swedbank-pay-payment-menu' ), $order->get_order_number() ) ),
				absint( $result->get_error_code() )
			);
		}

		$payment_order = $result->getResponseResource()->getPaymentOrder();
		if ( swedbank_pay_is_zero( $order->get_total() ) ) {
			$order->add_order_note( __( 'The order was successfully verified.', 'swedbank-pay-payment-menu' ) );
			Swedbank_Pay_Subscription::set_skip_om( $order, $payment_order->getCreated() );
		} else {
			$order->add_order_note( __( 'The payment was successfully initiated.', 'swedbank-pay-payment-menu' ) );
		}

		$order->update_meta_data( '_payex_paymentorder_id', $payment_order->getId() );
		$order->save_meta_data();

		return array(
			'result'   => 'success',
			'redirect' => $result->getOperationByRel( 'redirect-checkout', 'href' ),
		);
	}

	/**
	 * Output the payment fields content for the handler.
	 *
	 * Mirrors WooCommerce's default WC_Payment_Gateway::payment_fields() behavior
	 * by rendering the gateway description, which the gateway's payment_fields()
	 * override no longer does on its own. When called from a split instrument
	 * gateway, the per-instrument description is rendered instead of the main
	 * gateway's description.
	 *
	 * @param string $gateway_id The gateway ID whose description should be rendered.
	 *
	 * @return void
	 */
	protected function payment_fields_content( $gateway_id = 'payex_checkout' ) {
		$gateways = WC()->payment_gateways()->payment_gateways();
		$gateway  = $gateways[ $gateway_id ] ?? $this->gateway;

		$description = $gateway->get_description();
		if ( ! empty( $description ) ) {
			echo wp_kses_post( wpautop( wptexturize( $description ) ) );
		}
	}
}
