<?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\AttendanceStash;
use Ferienpass\CoreBundle\Entity\Offer\Base;
use Ferienpass\CoreBundle\Entity\Participant\BaseParticipant;
use PHPUnit\Framework\TestCase;

final class AttendanceStashTest extends TestCase
{
    public function testNameCanBeSetInConstructor(): void
    {
        $stash = new AttendanceStash('My Stash');

        self::assertSame('My Stash', $stash->getName());
    }

    public function testNameNullByDefault(): void
    {
        $stash = new AttendanceStash();

        self::assertNull($stash->getName());
    }

    public function testSetName(): void
    {
        $stash = new AttendanceStash();
        $stash->setName('Updated Name');

        self::assertSame('Updated Name', $stash->getName());
    }

    public function testAttendancesInitiallyEmpty(): void
    {
        $stash = new AttendanceStash();

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

    public function testAddAttendanceSetsStash(): void
    {
        $stash = new AttendanceStash('Test');
        $attendance = new Attendance(new Base(), new BaseParticipant());

        $stash->addAttendance($attendance);

        self::assertCount(1, $stash->getAttendances());
        self::assertSame($stash, $attendance->getStash());
    }

    public function testAddAttendanceIsIdempotent(): void
    {
        $stash = new AttendanceStash('Test');
        $attendance = new Attendance(new Base(), new BaseParticipant());

        $stash->addAttendance($attendance);
        $stash->addAttendance($attendance); // second add should be ignored

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

    public function testRemoveAttendanceClearsStash(): void
    {
        $stash = new AttendanceStash('Test');
        $attendance = new Attendance(new Base(), new BaseParticipant());

        $stash->addAttendance($attendance);
        self::assertCount(1, $stash->getAttendances());

        $stash->removeAttendance($attendance);

        self::assertCount(0, $stash->getAttendances());
        self::assertNull($attendance->getStash());
    }

    public function testSetStashOnAttendanceAddsToStash(): void
    {
        $stash = new AttendanceStash('Test');
        $attendance = new Attendance(new Base(), new BaseParticipant());

        $attendance->setStash($stash);

        self::assertSame($stash, $attendance->getStash());
        self::assertTrue($stash->getAttendances()->contains($attendance));
    }

    public function testSetStashToNullRemovesFromOldStash(): void
    {
        $stash = new AttendanceStash('Test');
        $attendance = new Attendance(new Base(), new BaseParticipant());

        $attendance->setStash($stash);
        $attendance->setStash(null);

        self::assertNull($attendance->getStash());
    }

    public function testIdIsNullByDefault(): void
    {
        $stash = new AttendanceStash();

        self::assertNull($stash->getId());
    }
}
