<?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 Controller;

use Chill\MainBundle\Entity\Notification;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Repository\UserRepository;
use Chill\MainBundle\Test\PrepareClientTrait;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

/**
 * @internal
 *
 * @coversNothing
 */
final class NotificationApiControllerTest extends WebTestCase
{
    use PrepareClientTrait;

    private static array $toDelete = [];

    protected function tearDown(): void
    {
        $em = self::getContainer()->get(EntityManagerInterface::class);

        foreach (self::$toDelete as [$className, $id]) {
            $object = $em->find($className, $id);
            $em->remove($object);
        }

        $em->flush();

        self::$toDelete = [];
    }

    /**
     * @dataProvider generateDataMarkAsRead
     */
    public function testMarkAsReadOrUnRead(int $notificationId)
    {
        $client = $this->getClientAuthenticated();
        $client->request('POST', "/api/1.0/main/notification/{$notificationId}/mark/read");

        $this->assertResponseIsSuccessful('test marking as read');

        $em = self::getContainer()->get(EntityManagerInterface::class);
        /** @var Notification $notification */
        $notification = $em->find(Notification::class, $notificationId);
        $user = self::getContainer()->get(UserRepository::class)->findOneBy(['username' => 'center a_social']);

        $this->assertTrue($notification->isReadBy($user));

        $client->request('POST', "/api/1.0/main/notification/{$notificationId}/mark/unread");

        $this->assertResponseIsSuccessful('test marking as unread');

        $notification = $em->find(Notification::class, $notificationId);
        $user = $em->find(User::class, $user->getId());
        $em->refresh($notification);
        $em->refresh($user);

        $this->assertFalse($notification->isReadBy($user));
    }

    public static function generateDataMarkAsRead()
    {
        self::bootKernel();
        $em = self::getContainer()->get(EntityManagerInterface::class);
        $userRepository = self::getContainer()->get(UserRepository::class);
        $userA = $userRepository->findOneBy(['username' => 'center a_social']);
        $userB = $userRepository->findOneBy(['username' => 'center b_social']);

        $notification = new Notification();
        $notification
            ->setMessage('Test generated')
            ->setRelatedEntityClass(AccompanyingPeriod::class)
            ->setRelatedEntityId(0)
            ->setSender($userB)
            ->addAddressee($userA)
            ->setUpdatedAt(new \DateTimeImmutable());
        $em->persist($notification);
        $em->refresh($notification);
        $em->flush();

        self::$toDelete[] = [Notification::class, $notification->getId()];

        self::ensureKernelShutdown();

        yield [$notification->getId()];
    }
}
