<?php

namespace App\Tests\Entity;

use App\Entity\OrganizerInvitation;
use PHPUnit\Framework\TestCase;

class OrganizerInvitationTest extends TestCase
{
    public function testDefaults(): void
    {
        $inv = new OrganizerInvitation();

        self::assertNull($inv->getId());
        self::assertNull($inv->getCompanyName());
        self::assertNull($inv->getFirstName());
        self::assertNull($inv->getLastName());
        self::assertNull($inv->getEmail());
        self::assertNull($inv->getMessage());
        self::assertNull($inv->getOffer());
        self::assertNull($inv->getCommissionRate());
        self::assertSame(OrganizerInvitation::STATUS_SENT, $inv->getStatus());
        self::assertSame(64, \strlen($inv->getToken()));
        self::assertNull($inv->getRespondedAt());
        self::assertInstanceOf(\DateTimeImmutable::class, $inv->getCreatedAt());
    }

    public function testSetAndGetCompanyName(): void
    {
        $inv = new OrganizerInvitation();
        $result = $inv->setCompanyName('Asso Test');

        self::assertSame('Asso Test', $inv->getCompanyName());
        self::assertSame($inv, $result);
    }

    public function testSetAndGetNames(): void
    {
        $inv = new OrganizerInvitation();
        $inv->setFirstName('Jean');
        $inv->setLastName('Dupont');
        $inv->setEmail('jean@test.fr');

        self::assertSame('Jean', $inv->getFirstName());
        self::assertSame('Dupont', $inv->getLastName());
        self::assertSame('jean@test.fr', $inv->getEmail());
    }

    public function testSetAndGetMessage(): void
    {
        $inv = new OrganizerInvitation();
        $result = $inv->setMessage('Bienvenue !');

        self::assertSame('Bienvenue !', $inv->getMessage());
        self::assertSame($inv, $result);

        $inv->setMessage(null);
        self::assertNull($inv->getMessage());
    }

    public function testSetAndGetOffer(): void
    {
        $inv = new OrganizerInvitation();
        $result = $inv->setOffer('basic');

        self::assertSame('basic', $inv->getOffer());
        self::assertSame($inv, $result);
    }

    public function testSetAndGetCommissionRate(): void
    {
        $inv = new OrganizerInvitation();
        $result = $inv->setCommissionRate(5.5);

        self::assertSame(5.5, $inv->getCommissionRate());
        self::assertSame($inv, $result);
    }

    public function testSetAndGetBillingAmount(): void
    {
        $inv = new OrganizerInvitation();

        self::assertNull($inv->getBillingAmount());

        $result = $inv->setBillingAmount(1000);

        self::assertSame(1000, $inv->getBillingAmount());
        self::assertSame($inv, $result);

        $inv->setBillingAmount(0);
        self::assertSame(0, $inv->getBillingAmount());
    }

    public function testSetAndGetStatus(): void
    {
        $inv = new OrganizerInvitation();
        $result = $inv->setStatus(OrganizerInvitation::STATUS_ACCEPTED);

        self::assertSame(OrganizerInvitation::STATUS_ACCEPTED, $inv->getStatus());
        self::assertSame($inv, $result);
    }

    public function testSetAndGetRespondedAt(): void
    {
        $inv = new OrganizerInvitation();
        $date = new \DateTimeImmutable();
        $result = $inv->setRespondedAt($date);

        self::assertSame($date, $inv->getRespondedAt());
        self::assertSame($inv, $result);
    }

    public function testUniqueTokens(): void
    {
        $inv1 = new OrganizerInvitation();
        $inv2 = new OrganizerInvitation();

        self::assertNotSame($inv1->getToken(), $inv2->getToken());
    }

    public function testIsExpiredFreshInvitation(): void
    {
        $inv = new OrganizerInvitation();
        self::assertFalse($inv->isExpired());
    }

    public function testIsExpiredOldInvitation(): void
    {
        $inv = new OrganizerInvitation();
        $ref = new \ReflectionProperty($inv, 'createdAt');
        $ref->setValue($inv, new \DateTimeImmutable('-8 days'));

        self::assertTrue($inv->isExpired());
    }

    public function testIsExpiredAcceptedNeverExpires(): void
    {
        $inv = new OrganizerInvitation();
        $ref = new \ReflectionProperty($inv, 'createdAt');
        $ref->setValue($inv, new \DateTimeImmutable('-30 days'));
        $inv->setStatus(OrganizerInvitation::STATUS_ACCEPTED);

        self::assertFalse($inv->isExpired());
    }

    public function testIsExpiredRefusedNeverExpires(): void
    {
        $inv = new OrganizerInvitation();
        $ref = new \ReflectionProperty($inv, 'createdAt');
        $ref->setValue($inv, new \DateTimeImmutable('-30 days'));
        $inv->setStatus(OrganizerInvitation::STATUS_REFUSED);

        self::assertFalse($inv->isExpired());
    }

    public function testIsExpiredCustomDays(): void
    {
        $inv = new OrganizerInvitation();
        $ref = new \ReflectionProperty($inv, 'createdAt');
        $ref->setValue($inv, new \DateTimeImmutable('-4 days'));

        self::assertFalse($inv->isExpired(7));
        self::assertTrue($inv->isExpired(3));
    }
}
