<?php

declare(strict_types=1);

namespace App\Module\Transport\Infrastructure\ApiPlatform\State\Provider;

use ApiPlatform\Doctrine\Orm\Paginator;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\Pagination\Pagination;
use ApiPlatform\State\ProviderInterface;
use App\Module\Transport\Domain\Entity\QualimatCarrier;
use App\Module\Transport\Domain\Repository\QualimatCarrierRepositoryInterface;
use Doctrine\ORM\Tools\Pagination\Paginator as DoctrinePaginator;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

/**
 * Provider de la saisie assistee QUALIMAT (spec-back § 4.7 / RG-4.01).
 *
 * GET /api/qualimat_carriers?search=<texte> :
 *  - restreint aux lignes actives (is_active = true) — regle serveur, pas un
 *    filtre client desactivable ;
 *  - recherche fuzzy insensible a la casse sur name (+ siret) ;
 *  - tri par name ASC ;
 *  - pagination Hydra (regle n°13) + echappatoire ?pagination=false (selects).
 *
 * Branche uniquement sur la GetCollection ; le Get unitaire reste servi par le
 * provider ORM par defaut (lecture seule, aucune ecriture exposee).
 *
 * @implements ProviderInterface<QualimatCarrier>
 */
final class QualimatCarrierSearchProvider implements ProviderInterface
{
    public function __construct(
        #[Autowire(service: 'App\Module\Transport\Infrastructure\Doctrine\DoctrineQualimatCarrierRepository')]
        private readonly QualimatCarrierRepositoryInterface $repository,
        private readonly Pagination $pagination,
    ) {}

    /**
     * @return list<QualimatCarrier>|Paginator<QualimatCarrier>
     */
    public function provide(Operation $operation, array $uriVariables = [], array $context = []): array|Paginator
    {
        $filters = $context['filters'] ?? [];
        $search  = $filters['search'] ?? null;

        $qb = $this->repository->createSearchQueryBuilder(is_string($search) ? $search : null);

        // Echappatoire ?pagination=false : collection complete (selects front).
        if (!$this->pagination->isEnabled($operation, $context)) {
            // @var list<QualimatCarrier> $carriers
            return $qb->getQuery()->getResult();
        }

        $limit  = $this->pagination->getLimit($operation, $context);
        $page   = max(1, $this->pagination->getPage($context));
        $offset = ($page - 1) * $limit;

        $qb->setFirstResult($offset)->setMaxResults($limit);

        // fetchJoinCollection: false — aucune jointure to-many (referentiel plat).
        return new Paginator(new DoctrinePaginator($qb->getQuery(), fetchJoinCollection: false));
    }
}
