<?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\DocStoreBundle\Controller;

use Chill\DocStoreBundle\GenericDoc\ManagerInterface;
use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter;
use Chill\MainBundle\Pagination\PaginatorFactoryInterface;
use Chill\MainBundle\Serializer\Model\Collection;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\SerializerInterface;

/**
 * Provide the list of GenericDoc for an accompanying period.
 */
final readonly class GenericDocForAccompanyingPeriodListApiController
{
    public function __construct(
        private ManagerInterface $manager,
        private Security $security,
        private PaginatorFactoryInterface $paginator,
        private SerializerInterface $serializer,
    ) {}

    #[Route('/api/1.0/doc-store/generic-doc/by-period/{id}/index', methods: ['GET'])]
    public function __invoke(AccompanyingPeriod $accompanyingPeriod): JsonResponse
    {
        if (!$this->security->isGranted(AccompanyingCourseDocumentVoter::SEE, $accompanyingPeriod)) {
            throw new AccessDeniedHttpException('not allowed to see the documents for accompanying period');
        }

        $nb = $this->manager->countDocForAccompanyingPeriod($accompanyingPeriod);
        $paginator = $this->paginator->create($nb);

        $docs = $this->manager->findDocForAccompanyingPeriod($accompanyingPeriod, $paginator->getCurrentPageFirstItemNumber(), $paginator->getItemsPerPage());

        $collection = new Collection($docs, $paginator);

        return new JsonResponse(
            $this->serializer->serialize($collection, 'json', [AbstractNormalizer::GROUPS => ['read']]),
            json: true,
        );
    }
}
