<?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\DataFixtures\ORM;

use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\ActivityBundle\Entity\ActivityType;
use Chill\MainBundle\DataFixtures\ORM\LoadScopes;
use Chill\MainBundle\DataFixtures\ORM\LoadUsers;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\Person;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ObjectManager;
use Faker\Factory as FakerFactory;

class LoadActivity extends AbstractFixture implements OrderedFixtureInterface
{
    use \Symfony\Component\DependencyInjection\ContainerAwareTrait;

    private readonly \Faker\Generator $faker;

    public function __construct(private readonly EntityManagerInterface $em)
    {
        $this->faker = FakerFactory::create('fr_FR');
    }

    public function getOrder(): int
    {
        return 16400;
    }

    public function load(ObjectManager $manager): void
    {
        $persons = $this->em
            ->getRepository(Person::class)
            ->findAll();

        foreach ($persons as $person) {
            $activityNbr = random_int(0, 3);

            for ($i = 0; $i < $activityNbr; ++$i) {
                $activity = $this->newRandomActivity($person);

                if (null !== $activity) {
                    $manager->persist($activity);
                }
            }
        }
        $manager->flush();
    }

    public function newRandomActivity($person): ?Activity
    {
        $activity = (new Activity())
            ->setUser($this->getRandomUser())
            ->setPerson($person)
            ->setDate($this->faker->dateTimeThisYear())
            ->setDurationTime($this->faker->dateTime(36000))
            ->setActivityType($this->getRandomActivityType())
            ->setScope($this->getRandomScope());

        //      ->setAttendee($this->faker->boolean())

        for ($i = 0; random_int(0, 4) > $i; ++$i) {
            $reason = $this->getRandomActivityReason();

            if (null !== $reason) {
                $activity->addReason($reason);
            } else {
                return null;
            }
        }

        return $activity;
    }

    /**
     * Return a random activityReason.
     */
    private function getRandomActivityReason(): ActivityReason
    {
        $reasonRef = LoadActivityReason::$references[array_rand(LoadActivityReason::$references)];

        return $this->getReference($reasonRef, ActivityReason::class);
    }

    /**
     * Return a random activityType.
     */
    private function getRandomActivityType(): ActivityType
    {
        $typeRef = LoadActivityType::$references[array_rand(LoadActivityType::$references)];

        return $this->getReference($typeRef, ActivityType::class);
    }

    /**
     * Return a random scope.
     */
    private function getRandomScope(): Scope
    {
        $scopeRef = LoadScopes::$references[array_rand(LoadScopes::$references)];

        return $this->getReference($scopeRef, Scope::class);
    }

    /**
     * Return a random user.
     */
    private function getRandomUser(): User
    {
        $userRef = array_rand(LoadUsers::$refs);

        return $this->getReference($userRef, User::class);
    }
}
