<?php

app_require('classes/economic_transfer_queue.php');

use classes\economic_transfer_queue;

function economic_transfer_queue_invoke_private(economic_transfer_queue $queue, string $method, array $args = []): mixed
{
    $reflection = new ReflectionClass($queue);
    $target = $reflection->getMethod($method);
    return $target->invokeArgs($queue, $args);
}

function economic_transfer_queue_new_without_constructor(): economic_transfer_queue
{
    $reflection = new ReflectionClass(economic_transfer_queue::class);
    /** @var economic_transfer_queue $instance */
    $instance = $reflection->newInstanceWithoutConstructor();
    return $instance;
}

it('normalizes order payloads to strict positive integer ids', function (): void {
    $queue = economic_transfer_queue_new_without_constructor();

    $payload = economic_transfer_queue_invoke_private($queue, 'normalizePayloadForTransferType', [
        economic_transfer_queue::TYPE_ORDER_DRAFT_EXPORT,
        [
            'order_id' => '42',
            'requested_by' => '-7',
        ],
        123,
    ]);

    expect($payload['order_id'])->toBe(42);
    expect($payload['requested_by'])->toBe(0);
});

it('normalizes collected-invoice payload booleans to strict bool values', function (): void {
    $queue = economic_transfer_queue_new_without_constructor();

    $truePayload = economic_transfer_queue_invoke_private($queue, 'normalizePayloadForTransferType', [
        economic_transfer_queue::TYPE_COLLECTED_INVOICE_EXPORT,
        [
            'collected_invoice_id' => '77',
            'send_as_is' => 'true',
        ],
        456,
    ]);
    expect($truePayload['collected_invoice_id'])->toBe(77);
    expect($truePayload['send_as_is'])->toBeTrue();

    $falsePayload = economic_transfer_queue_invoke_private($queue, 'normalizePayloadForTransferType', [
        economic_transfer_queue::TYPE_COLLECTED_INVOICE_EXPORT,
        [
            'collected_invoice_id' => 78,
            'send_as_is' => '0',
        ],
        456,
    ]);
    expect($falsePayload['collected_invoice_id'])->toBe(78);
    expect($falsePayload['send_as_is'])->toBeFalse();
});

it('rejects invalid transfer payloads before enqueue write attempts', function (): void {
    $queue = economic_transfer_queue_new_without_constructor();

    expect(fn () => economic_transfer_queue_invoke_private($queue, 'normalizePayloadForTransferType', [
        economic_transfer_queue::TYPE_ORDER_DRAFT_EXPORT,
        [],
        1,
    ]))->toThrow(Exception::class, 'order_id is required and must be a positive number');

    expect(fn () => economic_transfer_queue_invoke_private($queue, 'normalizePayloadForTransferType', [
        economic_transfer_queue::TYPE_COLLECTED_INVOICE_EXPORT,
        [
            'collected_invoice_id' => 12,
            'send_as_is' => 'maybe',
        ],
        1,
    ]))->toThrow(Exception::class, 'send_as_is must be a boolean');
});
