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

use Chill\MainBundle\CRUD\Controller\ApiController;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Repository\CountryRepository;
use Chill\MainBundle\Repository\PostalCodeRepositoryInterface;
use Chill\MainBundle\Serializer\Model\Collection;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;

final class PostalCodeAPIController extends ApiController
{
    public function __construct(private readonly CountryRepository $countryRepository, private readonly PostalCodeRepositoryInterface $postalCodeRepository, private readonly PaginatorFactory $paginatorFactory) {}

    #[Route(path: '/api/1.0/main/postal-code/search.json')]
    public function search(Request $request): JsonResponse
    {
        $this->denyAccessUnlessGranted('ROLE_USER');

        if (!$request->query->has('q')) {
            throw new BadRequestHttpException('You must supply a "q" parameter');
        }

        $pattern = $request->query->get('q');

        if ('' === trim((string) $pattern)) {
            throw new BadRequestHttpException('the search pattern is empty');
        }

        if ($request->query->has('country')) {
            $country = $this->countryRepository->find($request->query->getInt('country'));

            if (null === $country) {
                throw new NotFoundHttpException('country not found');
            }
        } else {
            $country = null;
        }

        $nb = $this->postalCodeRepository->countByPattern($pattern, $country);
        $paginator = $this->paginatorFactory->create($nb);
        $codes = $this->postalCodeRepository->findByPattern(
            $pattern,
            $country,
            $paginator->getCurrentPageFirstItemNumber(),
            $paginator->getItemsPerPage()
        );

        return $this->json(
            new Collection($codes, $paginator),
            Response::HTTP_OK,
            [],
            [AbstractNormalizer::GROUPS => ['read']]
        );
    }

    protected function customizeQuery(string $action, Request $request, $qb): void
    {
        if ($request->query->has('country')) {
            $qb->where('e.country = :country')
                ->setParameter('country', $request->query->get('country'));
        }

        $qb->andWhere('e.origin = :zero')
            ->setParameter('zero', 0);
    }
}
