<?php

/**
 * Copyright © Resurs Bank AB. All rights reserved.
 * See LICENSE for license details.
 */

namespace Resursbank\MerchantApi\Traits;

use Currency;
use JsonException;
use Order;
use PrestaShopDatabaseException;
use PrestaShopException;
use ReflectionException;
use Resursbank\Ecom\Exception\ApiException;
use Resursbank\Ecom\Exception\AttributeCombinationException;
use Resursbank\Ecom\Exception\AuthException;
use Resursbank\Ecom\Exception\ConfigException;
use Resursbank\Ecom\Exception\CurlException;
use Resursbank\Ecom\Exception\Validation\EmptyValueException;
use Resursbank\Ecom\Exception\Validation\IllegalTypeException;
use Resursbank\Ecom\Exception\Validation\IllegalValueException;
use Resursbank\Ecom\Exception\Validation\NotJsonEncodedException;
use Resursbank\Ecom\Exception\ValidationException;
use Resursbank\Ecom\Lib\Model\Payment;
use Resursbank\Ecom\Module\Payment\Repository;
use Resursbank\MerchantApi\Repository\ResursbankOrder;
use Resursbank\MerchantApi\Exception\HookException;
use Validate;

trait AdminOrderHook
{
    /**
     * Resolve order id from anonymous parameter list.
     *
     * @param array $parameters
     * @return int
     * @throws HookException
     */
    public function getOrderId(array $parameters): int
    {
        $id = (int) $parameters['id_order'];

        if ($id === 0) {
            throw new HookException('Invalid order id');
        }

        return $id;
    }

    /**
     * Resolve Order currently being viewed.
     *
     * @param int $orderId
     * @return Order
     * @throws HookException
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    public function getOrder(
        int $orderId
    ): Order {
        $order = new Order($orderId);

        if (!Validate::isLoadedObject($order)) {
            throw new HookException("Order not found on id $orderId");
        }

        return $order;
    }

    /**
     * Resolve currency associated with current order.
     *
     * @param Order $order
     * @return Currency
     * @throws HookException
     */
    public function getCurrency(Order $order): Currency
    {
        $currency = new Currency($order->id_currency);

        if (!Validate::isLoadedObject($currency)) {
            throw new HookException("Currency not found for order $order->id");
        }

        return $currency;
    }

    /**
     * Fetch MAPI payment.
     *
     * @param int $orderId
     * @param ResursbankOrder $repository
     * @return Payment
     * @throws ApiException
     * @throws AttributeCombinationException
     * @throws AuthException
     * @throws ConfigException
     * @throws CurlException
     * @throws EmptyValueException
     * @throws HookException
     * @throws IllegalTypeException
     * @throws IllegalValueException
     * @throws JsonException
     * @throws NotJsonEncodedException
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     * @throws ReflectionException
     * @throws ValidationException
     */
    public function getMapiPayment(
        int $orderId,
        ResursbankOrder $repository
    ): Payment {
        $order = $this->getOrder(orderId: $orderId);
        $resursbankOrder = $repository->find(orderId: $order->id);

        if ($resursbankOrder === null) {
            throw new HookException('Resurs Bank order not found.');
        }

        return Repository::get(paymentId: $resursbankOrder->getMapiId());
    }
}
