<?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\PersonDocumentVoter;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactory;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;

final readonly class GenericDocForPerson
{
    public function __construct(
        private FilterOrderHelperFactory $filterOrderHelperFactory,
        private ManagerInterface $manager,
        private PaginatorFactory $paginator,
        private Security $security,
        private \Twig\Environment $twig,
    ) {}

    /**
     * @throws \Doctrine\DBAL\Exception
     */
    #[Route(path: '/{_locale}/doc-store/generic-doc/by-person/{id}/index', name: 'chill_docstore_generic-doc_by-person_index')]
    public function list(Person $person): Response
    {
        if (!$this->security->isGranted(PersonDocumentVoter::SEE, $person)) {
            throw new AccessDeniedHttpException('not allowed to see the documents for person');
        }

        $filterBuilder = $this->filterOrderHelperFactory
            ->create(self::class)
            ->addSearchBox()
            ->addDateRange('dateRange', 'generic_doc.filter.date-range');

        if ([] !== $places = $this->manager->placesForPerson($person)) {
            $filterBuilder->addCheckbox('places', $places, [], array_map(
                static fn (string $k) => 'generic_doc.filter.keys.'.$k,
                $places
            ));
        }

        $filter = $filterBuilder
            ->build();

        ['to' => $endDate, 'from' => $startDate] = $filter->getDateRangeData('dateRange');
        $content = $filter->getQueryString();

        $nb = $this->manager->countDocForPerson(
            $person,
            $startDate,
            $endDate,
            $content,
            $filter->hasCheckBox('places') ? array_values($filter->getCheckboxData('places')) : []
        );
        $paginator = $this->paginator->create($nb);

        $documents = $this->manager->findDocForPerson(
            $person,
            $paginator->getCurrentPageFirstItemNumber(),
            $paginator->getItemsPerPage(),
            $startDate,
            $endDate,
            $content,
            $filter->hasCheckBox('places') ? array_values($filter->getCheckboxData('places')) : []
        );

        return new Response($this->twig->render(
            '@ChillDocStore/GenericDoc/person_list.html.twig',
            [
                'person' => $person,
                'pagination' => $paginator,
                'documents' => iterator_to_array($documents),
                'filter' => $filter,
            ]
        ));
    }
}
