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

use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\UserJob;
use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;

/**
 * @internal
 *
 * @coversNothing
 */
class UserTest extends TestCase
{
    use ProphecyTrait;

    public function testMainScopeHistory()
    {
        $user = new User();
        $scopeA = new Scope();
        $scopeB = new Scope();

        $user->setMainScope($scopeA);
        $user->setMainScope($scopeB);

        // 1. check getMainScope get now scopeB, not scopeA
        self::assertSame($scopeB, $user->getMainScope());

        // 2. get scopeA history, check endDate is not null
        self::assertNotNull(
            $user
                ->getMainScopeHistories()
                ->filter(fn (User\UserScopeHistory $userScopeHistory) => $userScopeHistory->getScope() === $scopeA)
                ->first()->getEndDate()
        );
    }

    public function testUserJobHistory()
    {
        $user = new User();
        $jobA = new UserJob();
        $jobB = new UserJob();

        $user->setUserJob($jobA);
        $user->setUserJob($jobB);

        // 1. check getUserJob get now jobB, not jobA
        self::assertSame($jobB, $user->getUserJob());

        // 2. get jobA history, check endDate is not null
        self::assertNotNull(
            $user
                ->getUserJobHistories()
                ->filter(fn (User\UserJobHistory $userJobHistory) => $userJobHistory->getJob() === $jobA)
                ->first()->getEndDate()
        );
    }

    public function testIsAbsent()
    {
        $user = new User();

        // Absent: today is within absence period
        $absenceStart = new \DateTimeImmutable('-1 day');
        $absenceEnd = new \DateTimeImmutable('+1 day');
        $user->setAbsenceStart($absenceStart);
        $user->setAbsenceEnd($absenceEnd);
        self::assertTrue($user->isAbsent(), 'Should be absent when now is between start and end');

        // Absent: end is null
        $user->setAbsenceStart(new \DateTimeImmutable('-2 days'));
        $user->setAbsenceEnd(null);
        self::assertTrue($user->isAbsent(), 'Should be absent when started and no end');

        // Not absent: absenceStart is in the future
        $user->setAbsenceStart(new \DateTimeImmutable('+2 days'));
        $user->setAbsenceEnd(null);
        self::assertFalse($user->isAbsent(), 'Should not be absent if start is in the future');

        // Not absent: absenceEnd is in the past
        $user->setAbsenceStart(new \DateTimeImmutable('-5 days'));
        $user->setAbsenceEnd(new \DateTimeImmutable('-1 day'));
        self::assertFalse($user->isAbsent(), 'Should not be absent if end is in the past');

        // Not absent: both are null
        $user->setAbsenceStart(null);
        $user->setAbsenceEnd(null);
        self::assertFalse($user->isAbsent(), 'Should not be absent if start is null');
    }

    public function testSetNotification(): void
    {
        $user = new User();

        self::assertTrue($user->isNotificationSendImmediately('dummy'));
        self::assertFalse($user->isNotificationDailyDigest('dummy'));

        $user->setNotificationImmediately('dummy', false);
        self::assertFalse($user->isNotificationSendImmediately('dummy'));

        $user->setNotificationDailyDigest('dummy', true);
        self::assertTrue($user->isNotificationDailyDigest('dummy'));

        $user->setNotificationImmediately('dummy', true);
        self::assertTrue($user->isNotificationSendImmediately('dummy'));
        self::assertTrue($user->isNotificationDailyDigest('dummy'));
    }
}
