<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CoreBundle\Tests\Entity;

use Ferienpass\CoreBundle\Entity\Attendance;
use Ferienpass\CoreBundle\Entity\Debtor;
use Ferienpass\CoreBundle\Entity\Edition;
use Ferienpass\CoreBundle\Entity\MessengerLog;
use Ferienpass\CoreBundle\Entity\Offer\Base;
use Ferienpass\CoreBundle\Entity\Participant\BaseParticipant;
use Ferienpass\CoreBundle\Entity\Payment;
use Ferienpass\CoreBundle\Entity\User;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Uid\Uuid;

final class MessengerLogTest extends TestCase
{
    public function testGetMessageReturnsMessage(): void
    {
        $log = new MessengerLog('AccountCreated');

        self::assertSame('AccountCreated', $log->getMessage());
    }

    public function testGetUuidIsGeneratedByDefault(): void
    {
        $log = new MessengerLog('test');

        self::assertInstanceOf(Uuid::class, $log->getUuid());
    }

    public function testGetUuidUsesProvidedUuid(): void
    {
        $uuid = Uuid::v7();
        $log = new MessengerLog('test', [], $uuid);

        self::assertSame($uuid->toRfc4122(), $log->getUuid()->toRfc4122());
    }

    public function testGetCreatedAtIsSetOnConstruct(): void
    {
        $log = new MessengerLog('test');

        self::assertInstanceOf(\DateTimeInterface::class, $log->getCreatedAt());
    }

    public function testGetAttendancesIsEmptyByDefault(): void
    {
        $log = new MessengerLog('test');

        self::assertCount(0, $log->getAttendances());
    }

    public function testConstructWithAttendanceAddsToAttendances(): void
    {
        $offer = new Base();
        $participant = new BaseParticipant();
        $attendance = new Attendance($offer, $participant);

        $log = new MessengerLog('test', [$attendance]);

        self::assertCount(1, $log->getAttendances());
    }

    public function testConstructWithUserAddsToUsers(): void
    {
        $user = new User();
        $log = new MessengerLog('test', [$user]);

        self::assertCount(1, $log->getUsers());
    }

    public function testConstructWithOfferAddsToOffers(): void
    {
        $offer = new Base();
        $log = new MessengerLog('test', [$offer]);

        self::assertCount(1, $log->getOffers());
    }

    public function testConstructWithEditionAddsToEditions(): void
    {
        $edition = new Edition();
        $log = new MessengerLog('test', [$edition]);

        self::assertCount(1, $log->getEditions());
    }

    public function testAddUserDoesNotDuplicate(): void
    {
        $user = new User();
        $log = new MessengerLog('test');
        $log->addUser($user);
        $log->addUser($user);

        self::assertCount(1, $log->getUsers());
    }

    public function testGetGroupIsNullByDefault(): void
    {
        $log = new MessengerLog('test');

        self::assertNull($log->getGroup());
    }

    public function testSetGroupAndGetGroup(): void
    {
        $parent = new MessengerLog('parent');
        $child = new MessengerLog('child');
        $child->setGroup($parent);

        self::assertSame($parent, $child->getGroup());
    }

    public function testGetNotificationsIsEmptyByDefault(): void
    {
        $log = new MessengerLog('test');

        self::assertCount(0, $log->getNotifications());
    }

    public function testGetChildrenIsEmptyByDefault(): void
    {
        $log = new MessengerLog('test');

        self::assertCount(0, $log->getChildren());
    }

    public function testConstructWithPaymentAddsToPayments(): void
    {
        $user = new User();
        $debtor = new Debtor($user);
        $payment = new Payment($debtor);

        $log = new MessengerLog('test', [$payment]);

        self::assertCount(1, $log->getPayments());
    }

    public function testGetPaymentsIsEmptyByDefault(): void
    {
        $log = new MessengerLog('test');

        self::assertCount(0, $log->getPayments());
    }

    public function testSetId(): void
    {
        $log = new MessengerLog('test');
        $log->setId(42);

        self::assertSame(42, $log->getId());
    }
}
