<?php

declare(strict_types=1);

namespace Autogedal\AwbRetry\Test\Unit\Cron;

use Autogedal\AwbRetry\Cron\Reconcile;
use Autogedal\AwbRetry\Model\Reconciliation;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;

class ReconcileTest extends TestCase
{
    public function testEmptyBatchDoesNotWriteOrLogErrors(): void
    {
        $service = $this->createMock(Reconciliation::class);
        $service->expects(self::once())->method('getCandidates')->with(100)->willReturn([]);
        $service->expects(self::never())->method('resolve');
        $logger = $this->createMock(LoggerInterface::class);
        $logger->expects(self::never())->method('error');

        (new Reconcile($service, $logger))->execute();
    }

    public function testFailedRowDoesNotPreventRemainingRowsFromBeingReconciled(): void
    {
        $rows = [['entity_id' => 1], ['entity_id' => 2]];
        $service = $this->createMock(Reconciliation::class);
        $service->method('getCandidates')->with(100)->willReturn($rows);
        $processed = [];
        $service->expects(self::exactly(2))->method('resolve')->willReturnCallback(
            function (array $row) use (&$processed): bool {
                $processed[] = $row['entity_id'];
                if ($row['entity_id'] === 1) {
                    throw new \RuntimeException('Write failed');
                }
                return true;
            }
        );
        $logger = $this->createMock(LoggerInterface::class);
        $logger->expects(self::once())->method('error')->with(
            'Automatic AWB retry log reconciliation failed.',
            self::callback(fn (array $context) => $context['error_log_id'] === 1
                && $context['exception'] instanceof \RuntimeException)
        );

        (new Reconcile($service, $logger))->execute();
        self::assertSame([1, 2], $processed);
    }
}
