<?php

declare(strict_types=1);

namespace Gls\GlsPoland\PrestaShop\ObjectModel\Repository;

use Doctrine\DBAL\Connection;
use Gls\GlsPoland\PrestaShop\ObjectModel\HydratorInterface;

/**
 * @extends AbstractObjectModelRepository<\Zone>
 */
final class ZoneRepository extends AbstractObjectModelRepository
{
    private $zonesByIsoCode = [];

    public function __construct(Connection $connection, string $dbPrefix, ?HydratorInterface $hydrator = null)
    {
        parent::__construct(\Zone::class, $connection, $dbPrefix, $hydrator);
    }

    public function findOneByCountryIsoCode(string $isoCode): ?\Zone
    {
        if (array_key_exists($isoCode, $this->zonesByIsoCode)) {
            return $this->zonesByIsoCode[$isoCode];
        }

        $statement = $this
            ->createQueryBuilder('z')
            ->innerJoin('z', 'country', 'c', 'c.id_zone = z.id_zone')
            ->andWhere('c.iso_code = :isoCode')
            ->setParameter('isoCode', $isoCode)
            ->execute();

        $data = $this->fetchAllAssociative($statement);

        if (null === $zone = $this->hydrate($data)) {
            return $this->zonesByIsoCode[$isoCode] = $zone;
        }

        if (isset($this->objectsById[$zone->id])) {
            $zone = $this->objectsById[$zone->id];
        } else {
            $this->objectsById[$zone->id] = $zone;
        }

        return $this->zonesByIsoCode[$isoCode] = $zone;
    }
}
