<?php
/**
 * @author Colinet Julien
 */

namespace CpCreation\VitiCore\Shop\Repository;

use CpCreation\VitiCore\Repository\BaseRepository;
use CpCreation\VitiCore\Shop\Model\ShippingCounty;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;

class ShippingCountyRepository extends BaseRepository
{
    /**
     * @var array<string, ?ShippingCounty>
     */
    private array $departmentByCountryCache = [];

    /**
     * @throws \ReflectionException
     */
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, ShippingCounty::class);
    }

    /**
     * @throws NonUniqueResultException
     */
    public function findDepartmentByCountry(string $department, string $country): ?ShippingCounty
    {
        $cacheKey = $department.'|'.$country;

        if (\array_key_exists($cacheKey, $this->departmentByCountryCache)) {
            return $this->departmentByCountryCache[$cacheKey];
        }

        return $this->departmentByCountryCache[$cacheKey] = $this->createQueryBuilder('s')
            ->innerJoin('s.zone', 'z')
            ->innerJoin('z.countries', 'c', Join::WITH, 'c.code = :country')
            ->andWhere('s.code = :department')
            ->setParameter('department', $department)
            ->setParameter('country', $country)
            ->getQuery()
            ->getOneOrNullResult();
    }

    public function findWithZoneNotNullQuery(): QueryBuilder
    {
        return $this->createQueryBuilder('s')
            ->andWhere('s.zone IS NOT NULL')
            ->orderBy('s.code', 'ASC');
    }
}
