<?php

declare(strict_types=1);

namespace CpCreation\VitiCore\Tests\Marketing;

use CpCreation\VitiCore\Marketing\ReviewDataRetentionPurger;
use CpCreation\VitiCore\Marketing\ReviewPublicationPolicy;
use Doctrine\DBAL\Connection;
use PHPUnit\Framework\TestCase;

final class ReviewDataRetentionPurgerTest extends TestCase
{
    public function testItPurgesUnusedAndExpiredReviewDataInOneTransaction(): void
    {
        $connection = $this->createMock(Connection::class);
        $connection
            ->expects(self::once())
            ->method('transactional')
            ->willReturnCallback(static fn(callable $callback): mixed => $callback($connection))
        ;
        $connection
            ->expects(self::exactly(2))
            ->method('fetchFirstColumn')
            ->willReturnOnConsecutiveCalls(
                ['00000000-0000-0000-0000-000000000001'],
                ['00000000-0000-0000-0000-000000000002'],
            )
        ;
        $connection
            ->expects(self::exactly(4))
            ->method('executeStatement')
            ->willReturnOnConsecutiveCalls(4, 3, 1, 2)
        ;

        $result = new ReviewDataRetentionPurger(
            $connection,
            new ReviewPublicationPolicy(),
        )->purge(new \DateTimeImmutable('2031-07-23 10:00:00'));

        self::assertSame(1, $result->unusedInvitationsPurged);
        self::assertSame(1, $result->reviewInvitationsPurged);
        self::assertSame(3, $result->reviewsDeleted);
        self::assertSame(4, $result->emailLogsDeleted);
    }

    public function testItDoesNothingWhenNoDataReachedItsRetentionLimit(): void
    {
        $connection = $this->createMock(Connection::class);
        $connection
            ->expects(self::once())
            ->method('transactional')
            ->willReturnCallback(static fn(callable $callback): mixed => $callback($connection))
        ;
        $connection
            ->expects(self::exactly(2))
            ->method('fetchFirstColumn')
            ->willReturn([])
        ;
        $connection
            ->expects(self::never())
            ->method('executeStatement')
        ;

        $result = new ReviewDataRetentionPurger(
            $connection,
            new ReviewPublicationPolicy(),
        )->purge(new \DateTimeImmutable('2026-07-23 10:00:00'));

        self::assertSame(0, $result->unusedInvitationsPurged);
        self::assertSame(0, $result->reviewInvitationsPurged);
        self::assertSame(0, $result->reviewsDeleted);
        self::assertSame(0, $result->emailLogsDeleted);
    }
}
