<?php
/**
 * Copyright Â© Resurs Bank AB. All rights reserved.
 * See LICENSE for license details.
 */
/* @noinspection PhpCastIsUnnecessaryInspection */

declare(strict_types=1);

namespace Resursbank\MerchantApi\Repository;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\Exception\ORMException;
use Doctrine\Persistence\ObjectRepository;
use InvalidArgumentException;
use Order as CoreOrder;
use PrestaShop\PrestaShop\Core\Domain\Shop\Exception\ShopException;
use PrestaShop\PrestaShop\Core\Domain\Shop\ValueObject\ShopConstraint;
use Resursbank\Ecom\Lib\Api\Environment;
use Resursbank\MerchantApi\Entity\ResursbankOrder as OrderEntity;
use Resursbank\MerchantApi\Config\Config;

/**
 * Implement methods to handle order data.
 */
class ResursbankOrder
{
    /**
     * @param Config $config
     * @param EntityManager $entityManager
     */
    public function __construct(
        private readonly Config $config,
        private readonly EntityManager $entityManager
    ) {
    }

    /**
     * @throws OptimisticLockException
     * @throws ORMException
     * @throws ShopException
     */
    public function create(
        CoreOrder $order
    ): void {
        $entity = new OrderEntity();

        if ((int) $order->id === 0) {
            throw new InvalidArgumentException('None existing order.');
        }

        $entity->setOrderId((int) $order->id)
            ->setTest(
                $this->config->getEnvironment(
                    ShopConstraint::shop((int) $order->id_shop)
                ) === Environment::TEST
            )
            ->setReadyForCallback(false);

        $this->entityManager->persist($entity);
        $this->entityManager->flush();
    }

    /**
     * @param int $orderId
     *
     * @return null|OrderEntity
     */
    public function find(
        int $orderId
    ): ?OrderEntity {
        $order = $this->getRepository()->findOneBy(['orderId' => $orderId]);
        return ($order instanceof OrderEntity) ? $order : null;
    }

    /**
     * Resolve order from mapi_id value.
     *
     * @param string $mapiId
     * @return OrderEntity
     */
    public function findByMapiId(
        string $mapiId
    ): OrderEntity {
        $order = $this->getRepository()->findOneBy(['mapiId' => $mapiId]);
        return ($order instanceof OrderEntity) ? $order : new OrderEntity();
    }

    /**
     * @return ObjectRepository
     */
    private function getRepository(): ObjectRepository
    {
        return $this->entityManager->getRepository(OrderEntity::class);
    }
}
