<?php

/**
 * 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.
 */

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\CalendarBundle\Controller;

use Chill\CalendarBundle\Entity\Calendar;
use Chill\CalendarBundle\Entity\Invite;
use Chill\CalendarBundle\Messenger\Message\InviteUpdateMessage;
use Chill\CalendarBundle\Security\Voter\InviteVoter;
use Chill\MainBundle\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;

class InviteApiController
{
    public function __construct(private readonly EntityManagerInterface $entityManager, private readonly MessageBusInterface $messageBus, private readonly Security $security) {}

    /**
     * Give an answer to a calendar invite.
     */
    #[Route(path: '/api/1.0/calendar/calendar/{id}/answer/{answer}.json', methods: ['post'])]
    public function answer(Calendar $calendar, string $answer): Response
    {
        $user = $this->security->getUser();

        if (!$user instanceof User) {
            throw new AccessDeniedHttpException('not a regular user');
        }

        if (null === $invite = $calendar->getInviteForUser($user)) {
            throw new AccessDeniedHttpException('not invited to this calendar');
        }

        if (!$this->security->isGranted(InviteVoter::ANSWER, $invite)) {
            throw new AccessDeniedHttpException('not allowed to answer on this invitation');
        }

        if (!\in_array($answer, Invite::STATUSES, true)) {
            throw new BadRequestHttpException('answer not valid');
        }

        $invite->setStatus($answer);
        $this->entityManager->flush();

        $this->messageBus->dispatch(new InviteUpdateMessage($invite, $this->security->getUser()));

        return new JsonResponse(null, Response::HTTP_ACCEPTED, [], false);
    }
}
