<?php
/**
 * Copyright since 2025 InPost S.A.
 *
 * For the full license information, please view the LICENSE file bundled with the module.
 *
 * @author InPost S.A.
 * @copyright since 2025 InPost S.A.
 * @license MIT
 */

declare(strict_types=1);

namespace InPost\International\Shipment;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use InPost\International\Api\Shipment\ShipmentType;
use InPost\International\Entity\Shipment;
use InPost\International\Shipment\Doctrine\SandboxQueryFilter;

if (!defined('_PS_VERSION_')) {
    exit;
}

/**
 * @extends ServiceEntityRepository<Shipment>
 */
final class ShipmentRepository extends ServiceEntityRepository implements ShipmentRepositoryInterface
{
    private const SANDBOX_FILTER = 'inpost_intl_sandbox';

    /**
     * @var bool|null
     */
    private $sandboxFilter;

    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Shipment::class);
        $this->getEntityManager()->getConfiguration()->addFilter(self::SANDBOX_FILTER, SandboxQueryFilter::class);
    }

    public function add(Shipment $shipment, bool $flush = true): void
    {
        $entityManager = $this->getEntityManager();
        $entityManager->persist($shipment);
        if ($flush) {
            $entityManager->flush();
        }
    }

    public function getShipmentsWithoutPickupOrder(int ...$shipmentIds): array
    {
        return $this->findBy([
            'id' => $shipmentIds,
            'type' => [ShipmentType::AddressToAddress()->value, ShipmentType::AddressToPoint()->value],
            'pickupOrder' => null,
        ]);
    }

    /**
     * @internal
     *
     * @return bool|null the previous filter state
     */
    public function enableSandboxFilter(bool $sandbox): ?bool
    {
        $filter = $this->getEntityManager()->getFilters()->enable(self::SANDBOX_FILTER);

        try {
            return $this->sandboxFilter;
        } finally {
            $filter->setParameter('sandbox', $sandbox);
            $this->sandboxFilter = $sandbox;
        }
    }

    /**
     * @internal
     */
    public function disableSandboxFilter(): void
    {
        $this->getEntityManager()->getFilters()->disable(self::SANDBOX_FILTER);
        $this->sandboxFilter = null;
    }
}
