<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\AdminBundle\ApplicationSystem;

use Doctrine\ORM\EntityManagerInterface;
use Ferienpass\CoreBundle\Entity\Attendance;
use Ferienpass\CoreBundle\Enum\AttendanceTransition;
use Symfony\Component\Uid\Uuid;
use Symfony\Component\Workflow\WorkflowInterface;

class ParticipantListFacade
{
    public function __construct(private readonly EntityManagerInterface $entityManager, private readonly WorkflowInterface $attendanceStateMachine)
    {
    }

    /**
     * @param Attendance[] $attendances
     */
    public function confirm(array $attendances, bool $notify = true, bool $commit = true, ?Uuid $group = null): void
    {
        $this->applyTransition($attendances, AttendanceTransition::CONFIRM, $notify, $commit, $group);
    }

    /**
     * @param Attendance[] $attendances
     */
    public function reject(array $attendances, bool $notify = true, bool $commit = true, ?Uuid $group = null): void
    {
        $this->applyTransition($attendances, AttendanceTransition::REJECT, $notify, $commit, $group);
    }

    /**
     * @param Attendance[] $attendances
     */
    private function applyTransition(array $attendances, string $transition, bool $notify = true, bool $commit = true, ?Uuid $group = null): void
    {
        if ($notify && !$commit) {
            throw new \RuntimeException('Notification cannot be sent without committing the changes');
        }

        foreach ($attendances as $attendance) {
            if (null === $attendance->getParticipant()) {
                continue;
            }

            if (!$this->attendanceStateMachine->can($attendance, $transition)) {
                continue;
            }

            $context = ['notify' => $notify, 'commit' => $commit, 'reorder' => false];
            if ($group) {
                $context['group'] = (string) $group;
            }

            $this->attendanceStateMachine->apply($attendance, $transition, $context);
        }

        $this->entityManager->flush();
    }
}
