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

use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Templating\Entity\UserRender;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Symfony\Component\Clock\MockClock;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Environment;

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

    public function testRenderUserWithJobAndScopeAtCertainDate(): void
    {
        // Create a user with a certain user job
        $user = new User();
        $userJobA = new UserJob();
        $scopeA = new Scope();

        $userJobA->setLabel(['fr' => 'assistant social'])
            ->setActive(true);
        $scopeA->setName(['fr' => 'service A']);
        $user->setLabel('BOB ISLA');

        $userJobB = new UserJob();
        $scopeB = new Scope();

        $userJobB->setLabel(['fr' => 'directrice'])
            ->setActive(true);
        $scopeB->setName(['fr' => 'service B']);

        $userJobHistoryA = (new User\UserJobHistory())
            ->setUser($user)
            ->setJob($userJobA)
            ->setStartDate(new \DateTimeImmutable('2023-11-01 12:00:00'))
            ->setEndDate(new \DateTimeImmutable('2023-11-30 00:00:00'));

        $userScopeHistoryA = (new User\UserScopeHistory())
            ->setUser($user)
            ->setScope($scopeA)
            ->setStartDate(new \DateTimeImmutable('2023-11-01 12:00:00'))
            ->setEndDate(new \DateTimeImmutable('2023-11-30 00:00:00'));

        $userJobHistoryB = (new User\UserJobHistory())
            ->setUser($user)
            ->setJob($userJobB)
            ->setStartDate(new \DateTimeImmutable('2023-12-01 12:00:00'));

        $userScopeHistoryB = (new User\UserScopeHistory())
            ->setUser($user)
            ->setScope($scopeB)
            ->setStartDate(new \DateTimeImmutable('2023-12-01 12:00:00'));

        $user->getUserJobHistories()->add($userJobHistoryA);
        $user->getUserScopeHistories()->add($userScopeHistoryA);

        $user->getUserJobHistories()->add($userJobHistoryB);
        $user->getUserScopeHistories()->add($userScopeHistoryB);

        // Create renderer
        $translatableStringHelperMock = $this->prophesize(TranslatableStringHelperInterface::class);
        $translatableStringHelperMock->localize(Argument::type('array'))->will(fn ($args) => $args[0]['fr']);

        $engineMock = $this->createMock(Environment::class);
        $translatorMock = $this->createMock(TranslatorInterface::class);
        $clock = new MockClock(new \DateTimeImmutable('2023-12-15 12:00:00'));

        $renderer = new UserRender($translatableStringHelperMock->reveal(), $engineMock, $translatorMock, $clock);

        $optionsNoDate['at_date'] = null;
        $options['at_date'] = new \DateTime('2023-11-25 12:00:00');
        $optionsTwo['at_date'] = new \DateTime('2024-01-30 12:00:00');

        // Check that the user render for the first activity corresponds with the first user job
        $expectedStringA = 'BOB ISLA (assistant social) (service A)';
        $this->assertEquals($expectedStringA, $renderer->renderString($user, $options));

        // Check that the user render for the second activity corresponds with the second user job
        $expectedStringB = 'BOB ISLA (directrice) (service B)';
        $this->assertEquals($expectedStringB, $renderer->renderString($user, $optionsTwo));

        // Check that the user renders the job and scope that is active now, when no date is given
        $expectedStringC = 'BOB ISLA (directrice) (service B)';
        $this->assertEquals($expectedStringC, $renderer->renderString($user, $optionsNoDate));
    }

    public function testRenderStringWithSplitLines(): void
    {

        // Create a user with a certain user job
        $user = new User();
        $userJobA = new UserJob();
        $scopeA = new Scope();

        $userJobA->setLabel(['fr' => 'assistant social en maison de service accompagné'])
            ->setActive(true);
        $scopeA->setName(['fr' => 'service de l\'assistant professionnel']);
        $user->setLabel('Robert Van Zorrizzeen Gorikke');

        $userJobHistoryA = (new User\UserJobHistory())
            ->setUser($user)
            ->setJob($userJobA)
            ->setStartDate(new \DateTimeImmutable('2023-11-01 12:00:00'))
            ->setEndDate(new \DateTimeImmutable('2023-11-30 00:00:00'));

        $userScopeHistoryA = (new User\UserScopeHistory())
            ->setUser($user)
            ->setScope($scopeA)
            ->setStartDate(new \DateTimeImmutable('2023-11-01 12:00:00'))
            ->setEndDate(new \DateTimeImmutable('2023-11-30 00:00:00'));

        $user->getUserJobHistories()->add($userJobHistoryA);
        $user->getUserScopeHistories()->add($userScopeHistoryA);

        // Create renderer
        $translatableStringHelperMock = $this->prophesize(TranslatableStringHelperInterface::class);
        $translatableStringHelperMock->localize(Argument::type('array'))->will(fn ($args) => $args[0]['fr']);

        $engineMock = $this->createMock(Environment::class);
        $translatorMock = $this->createMock(TranslatorInterface::class);
        $clock = new MockClock(new \DateTimeImmutable('2023-11-15 12:00:00'));

        $renderer = new UserRender($translatableStringHelperMock->reveal(), $engineMock, $translatorMock, $clock);

        $actual = $renderer->renderString($user, ['split_lines_before_characters' => 30]);
        self::assertEquals(<<<'STR'
            Robert Van Zorrizzeen Gorikke
            (assistant social en maison de
            service accompagné) (service de
            l'assistant professionnel)
            STR, $actual);

    }
}
