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

use Ferienpass\CoreBundle\Entity\Edition;
use Ferienpass\CoreBundle\Notification\ActionUrlTrait;
use Ferienpass\CoreBundle\Notification\AttachmentTrait;
use Ferienpass\CoreBundle\Notification\EditionEntityTrait;
use Ferienpass\CoreBundle\Notification\EmailToTrait;
use Ferienpass\CoreBundle\Notification\LoggableNotificationTrait;
use Ferienpass\CoreBundle\Notification\ReplyToTrait;
use Ferienpass\CoreBundle\Notifier\Message\Attachment;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Uid\Uuid;

final class NotificationTraitsTest extends TestCase
{
    public function testActionUrlTraitSetsAndReturnsUrl(): void
    {
        $obj = new class {
            use ActionUrlTrait;

            public function getActionUrl(): ?string
            {
                return $this->actionUrl;
            }
        };

        $result = $obj->actionUrl('https://example.com/action');

        self::assertSame($obj, $result);
        self::assertSame('https://example.com/action', $obj->getActionUrl());
    }

    public function testReplyToTraitSetsAndReturnsReplyTo(): void
    {
        $obj = new class {
            use ReplyToTrait;

            public function getReplyToValue(): ?string
            {
                return $this->replyTo;
            }
        };

        $result = $obj->replyTo('reply@example.com');

        self::assertSame($obj, $result);
        self::assertSame('reply@example.com', $obj->getReplyToValue());
    }

    public function testAttachmentTraitSetsAndGetsAttachment(): void
    {
        $obj = new class {
            use AttachmentTrait;
        };

        self::assertNull($obj->getAttachment());

        $attachment = new Attachment($this->createStub(\Contao\CoreBundle\Filesystem\VirtualFilesystemInterface::class), new \Contao\CoreBundle\Filesystem\FilesystemItem(true, 'path/to/file', null, null, null, null));
        $result = $obj->attachment($attachment);

        self::assertSame($obj, $result);
        self::assertSame($attachment, $obj->getAttachment());
    }

    public function testAttachmentTraitAcceptsNull(): void
    {
        $obj = new class {
            use AttachmentTrait;
        };

        $attachment = new Attachment($this->createStub(\Contao\CoreBundle\Filesystem\VirtualFilesystemInterface::class), new \Contao\CoreBundle\Filesystem\FilesystemItem(true, 'path/to/file', null, null, null, null));
        $obj->attachment($attachment);
        $obj->attachment(null);

        self::assertNull($obj->getAttachment());
    }

    public function testEditionEntityTraitSetsAndGetsEdition(): void
    {
        $obj = new class {
            use EditionEntityTrait;
        };

        self::assertNull($obj->getEdition());

        $edition = new Edition();
        $result = $obj->edition($edition);

        self::assertSame($obj, $result);
        self::assertSame($edition, $obj->getEdition());
    }

    public function testEmailToTraitSetsAndGetsEmailTo(): void
    {
        $obj = new class {
            use EmailToTrait;
        };

        self::assertNull($obj->getEmailTo());

        $result = $obj->emailTo('user@example.com');

        self::assertSame($obj, $result);
        self::assertSame('user@example.com', $obj->getEmailTo());
    }

    public function testEmailToTraitAcceptsNull(): void
    {
        $obj = new class {
            use EmailToTrait;
        };

        $obj->emailTo('user@example.com');
        $obj->emailTo(null);

        self::assertNull($obj->getEmailTo());
    }

    public function testLoggableNotificationTraitSetsAndGetsBelongsTo(): void
    {
        $obj = new class {
            use LoggableNotificationTrait;
        };

        self::assertNull($obj->getBelongsTo());

        $uuid = Uuid::v7();
        $result = $obj->belongsTo($uuid);

        self::assertSame($obj, $result);
        self::assertSame($uuid, $obj->getBelongsTo());
    }
}
