<?php

declare( strict_types=1 );

namespace Simplyin\Simplyin_W_Plugin\Tests\Unit;

use Brain\Monkey;
use Brain\Monkey\Functions;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use PHPUnit\Framework\TestCase;
use ReflectionProperty;
use Simplyin\Simplyin_W_Plugin\Lib\Remote\Sin_Core_Api\Simplyin_Api_Legacy_Client;

/**
 * The backend authenticates the legacy merchant API key exclusively via the
 * `X-Auth-Merchant-Api-Key` header — it is never read from the JSON body. sendRequest()
 * used to duplicate it into the body too. Guards against the header staying and the
 * body copy not silently coming back.
 */
final class Simplyin_Api_Legacy_Client_Test extends TestCase {

	/** @var mixed Previous value of the global, restored in tearDown() to avoid leaking state into other tests. */
	private $previous_simplyin_config;

	protected function setUp(): void {
		parent::setUp();
		Monkey\setUp();

		Functions\when( 'wp_json_encode' )->alias( 'json_encode' );
		Functions\when( 'home_url' )->justReturn( 'https://shop.example' );
		Functions\when( 'simplyin' )->justReturn(
			new class() {
				public function get_simplyin_logger() {
					return new class() {
						public function log_if_wpdebug_on( $message, $context = '' ) {}
					};
				}
			}
		);

		global $simplyin_config;
		$this->previous_simplyin_config = $simplyin_config ?? null;
		$simplyin_config                = [
			'backendSimplyIn'    => 'https://api.example',
			'environmentVersion' => 'prod',
		];

		Functions\when( 'get_option' )->alias(
			static function ( $name, $default = '' ) {
				if ( 'simplyin_api_key' === $name ) {
					return 'legacy-secret-key';
				}
				// RSA option keys (credential id / private key / disabled flag) all fall
				// through to the default, empty string -> Plugin_Rsa_Signer::is_active() is
				// false and sendRequest() takes the legacy API-key path under test.
				return $default;
			}
		);
	}

	protected function tearDown(): void {
		Monkey\tearDown();

		global $simplyin_config;
		$simplyin_config = $this->previous_simplyin_config;

		parent::tearDown();
	}

	public function test_legacy_post_sends_key_only_in_header_not_in_body(): void {
		$client = new Simplyin_Api_Legacy_Client( 'simplyin', '7.2.22' );

		$mock    = new MockHandler( [ new Response( 200, [], '{"status":"ok"}' ) ] );
		$history = [];
		$stack   = HandlerStack::create( $mock );
		$stack->push( \GuzzleHttp\Middleware::history( $history ) );

		$guzzle_client_prop = new ReflectionProperty( Simplyin_Api_Legacy_Client::class, 'client' );
		$guzzle_client_prop->setAccessible( true );
		$guzzle_client_prop->setValue( $client, new Client( [ 'handler' => $stack ] ) );

		$client->sendRequest( 'payments/getAvailablePaymentMethods', 'POST', [ 'foo' => 'bar' ] );

		$this->assertCount( 1, $history );
		$sent_request = $history[0]['request'];

		$this->assertSame( 'legacy-secret-key', $sent_request->getHeaderLine( 'X-Auth-Merchant-Api-Key' ) );

		$sent_body = json_decode( (string) $sent_request->getBody(), true );
		$this->assertArrayNotHasKey( 'merchantApiKey', $sent_body, 'Body must not carry a duplicated merchantApiKey field.' );
		$this->assertSame( 'bar', $sent_body['foo'] ?? null, 'The caller-supplied body payload must still reach the wire untouched.' );
	}
}
