<?php

app_require('modules/economic/economic_m.php');
app_require('modules/economic/customers/economicCustomers.php');

use customers\economicCustomers;

class economicCustomersDiscountFallbackTestDouble extends economicCustomers
{
    /** @var array<int, int|string> */
    public array $product_numbers = [];

    /** @var array<int, object|\RuntimeException> */
    public array $discount_responses = [];

    public function __construct()
    {
    }

    public function getCustomerProducts(int $customer_number, int $limit = 10, int $page = 1): object
    {
        return (object)[
            'collection' => array_map(
                fn (int|string $product_number): object => (object)[
                    'product' => (object)[
                        'productNumber' => (string)$product_number,
                    ],
                ],
                $this->product_numbers
            ),
        ];
    }

    public function getCustomerProductDiscount(int $customer_number, int $product_id)
    {
        $response = $this->discount_responses[$product_id] ?? (object)[
            'discountPercentage' => 0,
        ];

        if ($response instanceof \RuntimeException) {
            throw $response;
        }

        return $response;
    }
}

it('falls back to a later customer template product when earlier probes fail on missing currency prices', function (): void {
    $economic = new economicCustomersDiscountFallbackTestDouble();
    $economic->product_numbers = [1, 5, 9];
    $economic->discount_responses = [
        1 => new RuntimeException('e-conomic request failed with HTTP 400: No price in currency EUR can be found for the product. | details={"httpStatusCode":400}'),
        5 => (object)['discountPercentage' => 12],
    ];

    expect($economic->getCustomerDiscountPercentage(23152645))->toBe(12);
});

it('returns zero when every customer template lookup fails due to missing currency prices', function (): void {
    $economic = new economicCustomersDiscountFallbackTestDouble();
    $economic->product_numbers = [1, 2, 3];
    $economic->discount_responses = [
        1 => new RuntimeException('e-conomic request failed with HTTP 400: No price in currency EUR can be found for the product. | details={"httpStatusCode":400}'),
        2 => new RuntimeException('e-conomic request failed with HTTP 400: No price in currency EUR can be found for the product. | details={"httpStatusCode":400}'),
        3 => new RuntimeException('e-conomic request failed with HTTP 400: No price in currency EUR can be found for the product. | details={"httpStatusCode":400}'),
    ];

    expect($economic->getCustomerDiscountPercentage(23152645))->toBe(0);
});

it('rethrows unrelated discount lookup failures', function (): void {
    $economic = new economicCustomersDiscountFallbackTestDouble();
    $economic->product_numbers = [1];
    $economic->discount_responses = [
        1 => new RuntimeException('HTTP 503 upstream unavailable'),
    ];

    expect(fn () => $economic->getCustomerDiscountPercentage(23152645))
        ->toThrow(RuntimeException::class, 'HTTP 503 upstream unavailable');
});
