<?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 Chill\ActivityBundle\Tests\Service\DocGenerator;

use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Service\DocGenerator\ListActivitiesByAccompanyingPeriodContext;
use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Repository\UserRepositoryInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
 * @internal
 *
 * @coversNothing
 */
class ListActivitiesByAccompanyingPeriodContextTest extends KernelTestCase
{
    private ListActivitiesByAccompanyingPeriodContext $listActivitiesByAccompanyingPeriodContext;
    private AccompanyingPeriodRepository $accompanyingPeriodRepository;
    private UserRepositoryInterface $userRepository;

    protected function setUp(): void
    {
        self::bootKernel();
        $this->listActivitiesByAccompanyingPeriodContext = self::getContainer()->get(ListActivitiesByAccompanyingPeriodContext::class);
        $this->accompanyingPeriodRepository = self::getContainer()->get(AccompanyingPeriodRepository::class);
        $this->userRepository = self::getContainer()->get(UserRepositoryInterface::class);
    }

    /**
     * @dataProvider provideAccompanyingPeriod
     */
    public function testGetDataWithoutFilteringActivityNorWorks(int $accompanyingPeriodId, int $userId): void
    {
        $context = $this->getContext();
        $template = new DocGeneratorTemplate();
        $template->setOptions([
            'mainPerson' => false,
            'person1' => false,
            'person2' => false,
            'thirdParty' => false,
        ]);

        $data = $context->getData(
            $template,
            $this->accompanyingPeriodRepository->find($accompanyingPeriodId),
            ['myActivitiesOnly' => false, 'myWorksOnly' => false]
        );

        self::assertIsArray($data);
        self::assertArrayHasKey('activities', $data);
        self::assertIsArray($data['activities']);
        self::assertGreaterThan(0, count($data['activities']));
        self::assertIsArray($data['activities'][0]);
        self::assertArrayHasKey('user', $data['activities'][0]);
        self::assertIsArray($data['activities'][0]['user']);
    }

    /**
     * @dataProvider provideAccompanyingPeriod
     */
    public function testGetDataWithoutFilteringActivityByUser(int $accompanyingPeriodId, int $userId): void
    {
        $context = $this->getContext();
        $template = new DocGeneratorTemplate();
        $template->setOptions([
            'mainPerson' => false,
            'person1' => false,
            'person2' => false,
            'thirdParty' => false,
        ]);

        $data = $context->getData(
            $template,
            $this->accompanyingPeriodRepository->find($accompanyingPeriodId),
            ['myActivitiesOnly' => true, 'myWorksOnly' => false, 'creator' => $this->userRepository->find($userId)]
        );

        self::assertIsArray($data);
        self::assertArrayHasKey('activities', $data);
        self::assertIsArray($data['activities']);
        self::assertGreaterThan(0, count($data['activities']));
        self::assertIsArray($data['activities'][0]);
        self::assertArrayHasKey('user', $data['activities'][0]);
        self::assertIsArray($data['activities'][0]['user']);
    }

    public static function provideAccompanyingPeriod(): array
    {
        self::bootKernel();
        $em = self::getContainer()->get(EntityManagerInterface::class);

        if (null === $period = $em->createQuery('SELECT a FROM '.AccompanyingPeriod::class.' a')
            ->setMaxResults(1)
            ->getSingleResult()) {
            throw new \RuntimeException('no period found');
        }

        if (null === $user = $em->createQuery('SELECT u FROM '.User::class.' u')
            ->setMaxResults(1)
            ->getSingleResult()
        ) {
            throw new \RuntimeException('no user found');
        }

        $activity = new Activity();
        $activity
            ->setAccompanyingPeriod($period)
            ->setUser($user)
            ->setDate(new \DateTime());

        $em->persist($activity);
        $em->flush();

        self::ensureKernelShutdown();

        return [
            [$period->getId(), $user->getId()],
        ];
    }

    private function getContext(): ListActivitiesByAccompanyingPeriodContext
    {
        return $this->listActivitiesByAccompanyingPeriodContext;
    }
}
