<?php
namespace Prodigy\Includes\Frontend\Actions;

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

use Prodigy\Includes\Helpers\Prodigy_Logger;

/**
 * PunchOut return handler.
 *
 * Ariba expects a browser return using an HTML form POST to BrowserFormPost URL.
 * This endpoint renders an auto-submit form with hidden cXML payload.
 */
class Prodigy_Punchout_Return {
	const ACTION_NAME  = 'punchout_return';
	const NONCE_ACTION = 'prodigy-punchout-return';

	public function __construct() {
		add_action( 'init', array( $this, 'custom_url_structure' ), 999 );
		add_action( 'template_redirect', array( $this, 'custom_action_listener' ), 999 );
		add_filter( 'query_vars', array( $this, 'custom_query_vars' ), 999 );
	}

	/**
	 * Add rewrite rule for the custom URL structure (punchout-return).
	 */
	public function custom_url_structure(): void {
		add_rewrite_rule( '^punchout-return/?', 'index.php?custom_action=' . self::ACTION_NAME, 'top' );
	}

	/**
	 * Register custom query var.
	 *
	 * @param array $vars
	 *
	 * @return array
	 */
	public function custom_query_vars( array $vars ): array {
		$vars[] = 'custom_action';

		return $vars;
	}

	/**
	 * Render auto-submit form.
	 *
	 * @return void
	 */
	public function custom_action_listener(): void {
		if ( ! isset( $_GET['_wpnonce'] ) ) {
			return;
		}

		$custom_action = get_query_var( 'custom_action' );
		if ( ! $custom_action ) {
			$custom_action = isset( $_GET['custom_action'] ) ? sanitize_key( wp_unslash( $_GET['custom_action'] ) ) : '';
		}

		if ( $custom_action !== self::ACTION_NAME ) {
			return;
		}

		// Nonce can contain characters outside the strict key charset; don't sanitize as key.
		$nonce = sanitize_text_field( wp_unslash( (string) $_GET['_wpnonce'] ) );
		if ( ! wp_verify_nonce( $nonce, self::NONCE_ACTION ) ) {
			if ( PRODIGY_DEBUG_MODE ) {
				Prodigy_Logger::add_record(
					Prodigy_Logger::TYPE_ERROR,
					'PunchOut return nonce validation failed',
					'prodigy-punchout-return'
				);
			}
			return;
		}

		$return_key = isset( $_GET['return_key'] ) ? sanitize_text_field( wp_unslash( (string) $_GET['return_key'] ) ) : '';
		if ( $return_key === '' ) {
			if ( PRODIGY_DEBUG_MODE ) {
				Prodigy_Logger::add_record(
					Prodigy_Logger::TYPE_ERROR,
					'PunchOut return missing return_key',
					'prodigy-punchout-return'
				);
			}
			wp_die( esc_html__( 'Invalid PunchOut return session.', 'prodigy-commerce' ) );
		}

		$transient_name = 'prodigy_punchout_return_' . $return_key;
		$data           = get_transient( $transient_name );
		delete_transient( $transient_name );

		if ( empty( $data ) || empty( $data['browser_form_post_url'] ) || empty( $data['payload'] ) ) {
			if ( PRODIGY_DEBUG_MODE ) {
				Prodigy_Logger::add_record(
					Prodigy_Logger::TYPE_ERROR,
					'PunchOut return transient data is missing',
					'prodigy-punchout-return',
					wp_json_encode(
						array(
							'transient_name' => $transient_name,
							'return_key'     => $return_key,
						)
					)
				);
			}
			wp_die( esc_html__( 'Invalid PunchOut return session.', 'prodigy-commerce' ) );
		}

		$browser_form_post_url = (string) $data['browser_form_post_url'];
		$field_name            = isset( $data['field_name'] ) && is_string( $data['field_name'] ) ? $data['field_name'] : 'cxml-urlencoded';
		$payload               = (string) $data['payload'];
		if ( PRODIGY_DEBUG_MODE ) {
			Prodigy_Logger::add_record(
				Prodigy_Logger::TYPE_INFO,
				'PunchOut return page rendering auto-submit form',
				'prodigy-punchout-return',
				wp_json_encode(
					array(
						'return_key'            => $return_key,
						'browser_form_post_url' => $browser_form_post_url,
						'field_name'            => $field_name,
						'payload_length'        => strlen( $payload ),
					)
				)
			);
		}

		// Prevent caching of the return payload.
		if ( ! headers_sent() ) {
			header( 'Cache-Control: no-store, no-cache, must-revalidate, max-age=0' );
			header( 'Pragma: no-cache' );
		}

		$form_action = esc_url( $browser_form_post_url );

		echo '<!doctype html>';
		echo '<html><head><meta charset="utf-8"><title>PunchOut return</title></head><body>';
		echo '<form id="punchout-return" method="post" action="' . esc_url( $form_action ) . '">';
		echo '<input type="hidden" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $payload ) . '"/>';
		echo '</form>';
		echo '<script>';
		echo 'document.getElementById("punchout-return").submit();';
		echo '</script>';
		echo '</body></html>';

		exit;
	}
}
