<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\MainBundle\Tests\Export\Messenger;

use Chill\MainBundle\Entity\ExportGeneration;
use Chill\MainBundle\Export\Messenger\RemoveExportGenerationMessage;
use Chill\MainBundle\Export\Messenger\RemoveExportGenerationMessageHandler;
use Chill\MainBundle\Repository\ExportGenerationRepository;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use Psr\Log\NullLogger;
use Symfony\Component\Clock\MockClock;

/**
 * @internal
 *
 * @coversNothing
 */
class RemoveExportGenerationMessageHandlerTest extends TestCase
{
    use ProphecyTrait;

    public function testInvokeUpdatesDeleteAtAndRemovesAndFlushes()
    {
        // Arrange

        // 1. Create a MockClock at a fixed point in time
        $now = new \DateTimeImmutable('2024-06-01T12:00:00');
        $clock = new MockClock($now);

        // 2. Create an ExportGeneration entity with a stored object
        $exportGeneration = new ExportGeneration('test-alias', ['foo' => 'bar']);
        $storedObject = $exportGeneration->getStoredObject();

        // 3. Mock ExportGenerationRepository to return the ExportGeneration
        $exportGenerationRepository = $this->prophesize(ExportGenerationRepository::class);
        $exportGenerationRepository
            ->find($exportGeneration->getId())
            ->willReturn($exportGeneration);

        // 4. Mock EntityManagerInterface and set expectations
        $entityManager = $this->prophesize(EntityManagerInterface::class);
        $entityManager->remove($exportGeneration)->shouldBeCalled();
        $entityManager->flush()->shouldBeCalled();

        // 6. Create message
        $message = new RemoveExportGenerationMessage($exportGeneration);

        // 7. Handler instantiation
        $handler = new RemoveExportGenerationMessageHandler(
            $exportGenerationRepository->reveal(),
            $entityManager->reveal(),
            new NullLogger(),
            $clock
        );

        // Pre-condition: deleteAt not set.
        $this->assertNull($storedObject->getDeleteAt());

        // Act
        $handler->__invoke($message);

        // Assert
        $this->assertEquals($now, $storedObject->getDeleteAt(), 'deleteAt of stored object was updated');
    }
}
