<?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\Repository;

use Chill\MainBundle\Entity\NewsItem;
use Chill\MainBundle\Repository\NewsItemRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Clock\ClockInterface;
use Symfony\Component\Clock\MockClock;

/**
 * @internal
 *
 * @coversNothing
 */
class NewsItemRepositoryTest extends KernelTestCase
{
    private EntityManagerInterface $entityManager;

    /**
     * @var list<array{0: class-string, 1: NewsItem}>
     */
    private array $toDelete = [];

    protected function setUp(): void
    {
        self::bootKernel();
        $this->entityManager = self::getContainer()->get(EntityManagerInterface::class);
    }

    protected function tearDown(): void
    {
        foreach ($this->toDelete as [$class, $entity]) {
            $query = $this->entityManager->createQuery(sprintf('DELETE FROM %s e WHERE e.id = :id', $class))
                ->setParameter('id', $entity->getId());
            $query->execute();
        }

        $this->toDelete = [];
    }

    private function getNewsItemsRepository(ClockInterface $clock): NewsItemRepository
    {
        return new NewsItemRepository($this->entityManager, $clock);
    }

    public function testFindCurrentNews()
    {
        $clock = new MockClock($now = new \DateTimeImmutable('2023-01-10'));
        $repository = $this->getNewsItemsRepository($clock);

        $newsItem1 = new NewsItem();
        $newsItem1->setTitle('This is a mock news item');
        $newsItem1->setContent('We are testing that the repository returns the correct news items');
        $newsItem1->setStartDate(new \DateTimeImmutable('2023-01-01'));
        $newsItem1->setEndDate(new \DateTimeImmutable('2023-01-05'));

        $newsItem2 = new NewsItem();
        $newsItem2->setTitle('This is a mock news item');
        $newsItem2->setContent('We are testing that the repository returns the correct news items');
        $newsItem2->setStartDate(new \DateTimeImmutable('2023-01-01'));
        $newsItem2->setEndDate($now->add(new \DateInterval('P1D')));

        $newsItem3 = new NewsItem();
        $newsItem3->setTitle('This is a mock news item');
        $newsItem3->setContent('We are testing that the repository returns the correct news items');
        $newsItem3->setStartDate(new \DateTimeImmutable('2033-11-03'));
        $newsItem3->setEndDate(null);

        $newsItem4 = new NewsItem();
        $newsItem4->setTitle('This is a mock news item');
        $newsItem4->setContent('We are testing that the repository returns the correct news items');
        $newsItem4->setStartDate(new \DateTimeImmutable('2023-01-03'));
        $newsItem4->setEndDate(null);

        $this->entityManager->persist($newsItem1);
        $this->entityManager->persist($newsItem2);
        $this->entityManager->persist($newsItem3);
        $this->entityManager->persist($newsItem4);
        $this->entityManager->flush();

        $this->toDelete = [
            [NewsItem::class, $newsItem1],
            [NewsItem::class, $newsItem2],
            [NewsItem::class, $newsItem3],
            [NewsItem::class, $newsItem4],
        ];

        // Call the method to test
        $result = $repository->findCurrentNews();

        // Assertions
        $this->assertCount(2, $result);
        $this->assertInstanceOf(NewsItem::class, $result[0]);
        $this->assertContains($newsItem2, $result);
        $this->assertContains($newsItem4, $result);
    }
}
