<?php

declare(strict_types=1);

namespace App\Module\Transport\Infrastructure\Doctrine;

use App\Module\Transport\Domain\Entity\QualimatCarrier;
use App\Module\Transport\Domain\Repository\QualimatCarrierRepositoryInterface;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;

/**
 * @extends ServiceEntityRepository<QualimatCarrier>
 */
class DoctrineQualimatCarrierRepository extends ServiceEntityRepository implements QualimatCarrierRepositoryInterface
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, QualimatCarrier::class);
    }

    public function createSearchQueryBuilder(?string $search = null): QueryBuilder
    {
        // Saisie assistee (§ 4.7) : on ne propose QUE des transporteurs QUALIMAT
        // actifs (is_active = true), tries par nom. Le forcage de l'actif est une
        // regle serveur (pas un filtre client) — les lignes soft-deletees par la
        // synchro restent invisibles.
        $qb = $this->createQueryBuilder('q')
            ->andWhere('q.isActive = true')
            ->orderBy('q.name', 'ASC')
        ;

        $this->applySearch($qb, $search);

        return $qb;
    }

    /**
     * Recherche fuzzy insensible a la casse sur le nom (+ siret) du transporteur
     * QUALIMAT (§ 4.7 / RG-4.01). Metacaracteres LIKE (%, _, \) echappes pour
     * rester litteraux.
     */
    private function applySearch(QueryBuilder $qb, ?string $search): void
    {
        if (null === $search || '' === trim($search)) {
            return;
        }

        $escaped = str_replace(['\\', '%', '_'], ['\\\\', '\%', '\_'], trim($search));
        $pattern = '%'.mb_strtolower($escaped, 'UTF-8').'%';

        $qb->andWhere('LOWER(q.name) LIKE :search OR LOWER(q.siret) LIKE :search')
            ->setParameter('search', $pattern)
        ;
    }
}
