<?php

declare( strict_types=1 );

namespace Simplyin\Simplyin_W_Plugin\Tests\Unit;

use Brain\Monkey;
use Brain\Monkey\Functions;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
use ReflectionMethod;
use Simplyin\Simplyin_W_Plugin\Controller\Ajax\Widget\Widget_Controller;

/**
 * Widget_Controller::update_array_with_plugin_info() / get_shop_language() contract test.
 *
 * The backend locale validator only accepts an uppercase, 2-letter code under the
 * `language` key; a wrongly-named/shaped field is silently ignored server-side, so this
 * pins the exact key + value shape sent on every widget AJAX call — including the calls
 * that build their body separately and use get_shop_language() directly instead of going
 * through update_array_with_plugin_info().
 */
final class Widget_Controller_Plugin_Info_Test extends TestCase {

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

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

	public function test_sends_shop_locale_under_language_key_as_uppercase_2_letter_code(): void {
		Functions\when( 'SimplyInGetPluginVersion' )->justReturn( '7.2.20' );
		Functions\when( 'get_bloginfo' )->justReturn( 'Test Shop' );
		Functions\when( 'sanitize_text_field' )->returnArg();
		Functions\when( 'get_locale' )->justReturn( 'pl_PL' );

		$result = $this->invoke( [ 'email' => 'shopper@example.com' ] );

		$this->assertSame( 'PL', $result['language'] );
		$this->assertArrayNotHasKey( 'lng', $result );
	}

	public function test_uppercases_and_truncates_a_non_default_locale(): void {
		Functions\when( 'SimplyInGetPluginVersion' )->justReturn( '7.2.20' );
		Functions\when( 'get_bloginfo' )->justReturn( 'Test Shop' );
		Functions\when( 'sanitize_text_field' )->returnArg();
		Functions\when( 'get_locale' )->justReturn( 'en_US' );

		$result = $this->invoke( [] );

		$this->assertSame( 'EN', $result['language'] );
	}

	public function test_get_shop_language_matches_update_array_with_plugin_info(): void {
		Functions\when( 'get_locale' )->justReturn( 'pl_PL' );

		$this->assertSame( 'PL', $this->invoke_get_shop_language() );
	}

	/**
	 * @param array<string, mixed> $body_data
	 * @return array<string, mixed>
	 */
	private function invoke( array $body_data ): array {
		$controller = ( new ReflectionClass( Widget_Controller::class ) )->newInstanceWithoutConstructor();
		$method     = new ReflectionMethod( Widget_Controller::class, 'update_array_with_plugin_info' );
		$method->setAccessible( true ); // Required on the plugin's PHP floor (7.4); harmless no-op on 8.1+.

		return $method->invoke( $controller, $body_data );
	}

	private function invoke_get_shop_language(): string {
		$controller = ( new ReflectionClass( Widget_Controller::class ) )->newInstanceWithoutConstructor();
		$method     = new ReflectionMethod( Widget_Controller::class, 'get_shop_language' );
		$method->setAccessible( true ); // Required on the plugin's PHP floor (7.4); harmless no-op on 8.1+.

		return $method->invoke( $controller );
	}
}
