<?php

declare(strict_types=1);

namespace FiloBlu\Rma\Model;

use function is_array;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\ResourceConnection;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\Sales\Api\OrderRepositoryInterface;

use RuntimeException;

/**
 *
 */
class OrderLocator
{
    /**
     * @var \Magento\Sales\Api\Data\OrderInterface
     */
    private $currentOrder;
    /**
     * @var \Magento\Sales\Api\OrderRepositoryInterface
     */
    private $orderRepository;
    /**
     * @var \Magento\Framework\App\RequestInterface
     */
    private $request;
    /**
     * @var \Magento\Framework\App\ResourceConnection
     */
    private $resourceConnection;

    /**
     * @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
     * @param \Magento\Framework\App\RequestInterface $request
     * @param \Magento\Framework\App\ResourceConnection $resourceConnection
     */
    public function __construct(
        OrderRepositoryInterface $orderRepository,
        RequestInterface $request,
        ResourceConnection $resourceConnection
    ) {
        $this->orderRepository = $orderRepository;
        $this->request = $request;
        $this->resourceConnection = $resourceConnection;
    }

    /**
     * @return \Magento\Sales\Api\Data\OrderInterface
     */
    public function getCurrentOrder()
    {
        return $this->currentOrder;
    }

    /**
     * @param \Magento\Sales\Api\Data\OrderInterface $order
     * @return void
     */
    public function setCurrentOrder(OrderInterface $order)
    {
        $this->currentOrder = $order;
    }

    /**
     * @return bool
     */
    public function hasOrder()
    {
        return $this->currentOrder !== null;
    }

    /**
     * @return void
     */
    public function reset()
    {
        $this->currentOrder = null;
    }

    /**
     *
     * @return \Magento\Sales\Api\Data\OrderInterface|null
     * @throws \Magento\Framework\Exception\InputException
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function load($data = null)
    {
        if (is_array($data) && isset($data['order_id']) && (int)$data['order_id'] > 0) {
            $this->currentOrder = $this->orderRepository->get($data['order_id']);
            return $this->currentOrder;
        }

        if (is_array(
            $data
        ) && isset($data['items'][0]['order_item_id']) && (int)$data['items'][0]['order_item_id'] > 0) {
            $this->currentOrder = $this->getOrderByItemId($data['items'][0]['order_item_id']);
            return $this->currentOrder;
        }
        $orderId = $this->request->getParam('order_id');

        if ($orderId && (int)$orderId > 0) {
            $this->currentOrder = $this->orderRepository->get($orderId);
            return $this->currentOrder;
        }

        $orderItemId = $this->request->getParam('order_item_id');

        if ($orderItemId && (int)$orderItemId > 0) {
            $this->currentOrder = $this->getOrderByItemId($orderItemId);
            return $this->currentOrder;
        }

        throw new RuntimeException('Could not find order by order_id or order_item_id');
    }

    /**
     * @param $orderItemId
     * @return \Magento\Sales\Api\Data\OrderInterface
     * @throws \Magento\Framework\Exception\InputException
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     * @noinspection PhpDocRedundantThrowsInspection
     */
    public function getOrderByItemId($orderItemId): OrderInterface
    {
        $connection = $this->resourceConnection->getConnection();
        $orderId = $connection->fetchOne(
            $connection->select()->from($connection->getTableName('sales_order_item'), ['order_id'])->where(
                'item_id = ? ',
                $orderItemId
            )
        );

        return $this->orderRepository->get($orderId);
    }
}
