<?php

declare( strict_types=1 );

namespace Simplyin\Simplyin_W_Plugin\Tests\Unit;

use Brain\Monkey;
use Brain\Monkey\Functions;
use PHPUnit\Framework\TestCase;
use Simplyin\Simplyin_W_Plugin\Dto\Order\Order_DTO_Factory;

/**
 * Per-line tax math (Order_DTO_Factory::compute_line_tax): tax_rate must be derived from the
 * whole-line values so it stays correct at qty > 1, and tax_amount stays per-unit. Pure logic —
 * no WooCommerce (wc_format_decimal stubbed via Brain Monkey).
 */
final class Order_Item_Tax_Test extends TestCase {

	protected function setUp(): void {
		parent::setUp();
		Monkey\setUp();
		Functions\when( 'wc_format_decimal' )->alias(
			static function ( $value, $dp = 2 ) {
				return number_format( round( (float) $value, (int) $dp ), (int) $dp, '.', '' );
			}
		);
	}

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

	public function test_tax_rate_correct_at_quantity_greater_than_one(): void {
		// qty 2, unit net 100, 23% VAT -> line net 200, line tax 46.
		$result = Order_DTO_Factory::compute_line_tax( 46.0, 200.0, 2 );

		$this->assertSame( 23.0, $result['tax_amount'] ); // Per-unit tax.
		$this->assertSame( 23.0, $result['tax_rate'] );   // Effective rate, not understated by qty.
	}

	public function test_tax_rate_matches_single_unit(): void {
		$result = Order_DTO_Factory::compute_line_tax( 23.0, 100.0, 1 );

		$this->assertSame( 23.0, $result['tax_amount'] );
		$this->assertSame( 23.0, $result['tax_rate'] );
	}

	public function test_zero_tax_yields_zero_rate(): void {
		$result = Order_DTO_Factory::compute_line_tax( 0.0, 150.0, 3 );

		$this->assertSame( 0.0, $result['tax_amount'] );
		$this->assertSame( 0.0, $result['tax_rate'] );
	}

	public function test_zero_line_net_does_not_divide_by_zero(): void {
		$result = Order_DTO_Factory::compute_line_tax( 5.0, 0.0, 2 );

		$this->assertSame( 0.0, $result['tax_rate'] );
	}

	public function test_zero_quantity_falls_back_without_division_by_zero(): void {
		$result = Order_DTO_Factory::compute_line_tax( 10.0, 50.0, 0 );

		$this->assertSame( 10.0, $result['tax_amount'] ); // Falls back to the line tax.
		$this->assertSame( 20.0, $result['tax_rate'] );
	}
}
