<?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\Notification;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Repository\NotificationRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
 * @internal
 *
 * @coversNothing
 */
class NotificationRepositoryTest extends KernelTestCase
{
    private EntityManagerInterface $entityManager;
    private NotificationRepository $repository;

    protected function setUp(): void
    {
        self::bootKernel();
        $this->entityManager = static::$kernel->getContainer()->get('doctrine.orm.entity_manager');
        $this->repository = new NotificationRepository($this->entityManager);
    }

    public function testMarkAllNotificationAsReadForUser(): void
    {
        $user = $this->entityManager->createQuery('SELECT u FROM '.User::class.' u')
            ->setMaxResults(1)->getSingleResult();

        $notification = (new Notification())
            ->setRelatedEntityClass('\Dummy')
            ->setRelatedEntityId(0)
        ;
        $notification->addAddressee($user)->markAsUnreadBy($user);

        $this->entityManager->persist($notification);
        $this->entityManager->flush();
        $notification->markAsUnreadBy($user);
        $this->entityManager->flush();

        $this->entityManager->refresh($notification);

        if ($notification->isReadBy($user)) {
            throw new \LogicException('Notification should not be marked as read');
        }

        $notificationsIds = $this->repository->markAllNotificationAsReadForUser($user);
        self::assertContains($notification->getId(), $notificationsIds);

        $this->entityManager->clear();

        $notification = $this->entityManager->find(Notification::class, $notification->getId());

        self::assertTrue($notification->isReadBy($user));
    }

    public function testMarkAllNotificationAsUnreadForUser(): void
    {
        $user = $this->entityManager->createQuery('SELECT u FROM '.User::class.' u')
            ->setMaxResults(1)->getSingleResult();

        $notification = (new Notification())
            ->setRelatedEntityClass('\Dummy')
            ->setRelatedEntityId(0)
        ;
        $notification->addAddressee($user); // we do not mark the notification as unread by the user

        $this->entityManager->persist($notification);
        $this->entityManager->flush();
        $notification->markAsReadBy($user);
        $this->entityManager->flush();

        $this->entityManager->refresh($notification);

        if (!$notification->isReadBy($user)) {
            throw new \LogicException('Notification should be marked as read');
        }

        $notificationsIds = $this->repository->markAllNotificationAsUnreadForUser($user, [$notification->getId()]);

        self::assertContains($notification->getId(), $notificationsIds);
    }
}
