<?php
/**
 * 2018 Paysera
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@prestashop.com so we can send you a copy immediately.
 *
 * @author Paysera <plugins@paysera.com>
 * @copyright 2018 Paysera
 * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
 * International Registered Trademark & Property of Paysera
 */
declare(strict_types=1);

namespace Paysera\Delivery\HookHandler\OrderHandler;

use PayseraDelivery;
use Paysera\Delivery\Entity\ShipmentRequest;
use Paysera\Delivery\Service\DeliveryApiClient;
use Paysera\Delivery\Service\Logger;
use Address;
use Customer;
use Paysera\Delivery\PayseraDeliveryConfiguration;
use Paysera\Delivery\PayseraDeliveryCarriers;
use Paysera\Delivery\Service\DeliveryOrderMessageGenerator;
use Paysera\Delivery\Exception\ShipmentRequestGatewayNotFoundException;
use Order;
use Paysera\DeliveryApi\MerchantClient\Entity\Order as DeliveryOrder;

abstract class AbstractOrderCreateHandler
{
    /**
     * @var Logger
     */
    protected $logger;
    /**
     * @var PayseraDeliveryConfiguration
     */
    protected $configuration;
    /**
     * @var DeliveryApiClient
     */
    protected $deliveryApiClient;
    /**
     * @var PayseraDeliveryCarriers
     */
    protected $payseraDeliveryCarriers;

    public function __construct(
        Logger $logger,
        PayseraDeliveryConfiguration $configuration,
        DeliveryApiClient $deliveryApiClient,
        PayseraDeliveryCarriers $payseraDeliveryCarriers
    ) {
        $this->logger = $logger;
        $this->configuration = $configuration;
        $this->deliveryApiClient = $deliveryApiClient;
        $this->payseraDeliveryCarriers = $payseraDeliveryCarriers;
    }

    protected function handleDeliveryOrderCreation(
        PayseraDelivery $module,
        Order $order,
        ShipmentRequest $shipmentRequest
    ): ?DeliveryOrder {
        $context = $module->getContext();

        if ($shipmentRequest->getStatus() !== ShipmentRequest::STATUS_NEW) {
            $this->logger->info(
                sprintf(
                    'Delivery order for order %d already created',
                    $order->id
                )
            );

            return null;
        }

        $address = new Address((int) $order->id_address_delivery);

        $carrierInfo = $this->payseraDeliveryCarriers->getCarrierById((int) $order->id_carrier);

        if ($carrierInfo !== null) {
            try {
                $createdDeliveryOrder = $this->deliveryApiClient
                    ->setOrderNotificationUrl(
                        $context->link->getModuleLink($module->getName(), 'callback', ['id_order' => $order->id])
                    )
                    ->createOrder(
                        (int) $order->id,
                        $carrierInfo,
                        $address,
                        new Customer((int) $address->id_customer),
                        $order->getProducts(),
                        $shipmentRequest
                    )
                ;
            } catch (ShipmentRequestGatewayNotFoundException $exception) {
                $this->logger->info('Shipment request gateway not found');
            }
        }

        $deliveryOrderMessageGenerator = new DeliveryOrderMessageGenerator(
            (int) $context->shop->id,
            (int) $context->language->id,
            (int) $order->id,
            (int) $order->id_customer,
            [$module, 'l']
        );

        if ($createdDeliveryOrder === null) {
            $deliveryOrderMessageGenerator->generateOrderNotCreatedMessage();

            return null;
        }

        $deliveryOrderMessageGenerator->generateOrderCreatedMessage($createdDeliveryOrder->getNumber());

        if (isset($carrierInfo['type']) && $carrierInfo['type'] === PayseraDeliveryConfiguration::TYPE_PARCEL_MACHINE) {
            $deliveryOrderReceiver = $createdDeliveryOrder->getReceiver();
            $parcelMachine = null;

            if ($deliveryOrderReceiver !== null) {
                $parcelMachine = $deliveryOrderReceiver->getParcelMachine();
            }

            $deliveryOrderMessageGenerator->generateTerminalDeliveryOrderMessage(
                $createdDeliveryOrder->getNumber(),
                $createdDeliveryOrder->getShipmentGateway()->getDescription(),
                $createdDeliveryOrder->getShipmentMethod()->getDescription(),
                $parcelMachine !== null ? $parcelMachine->getAddress()->getStreet() ?? '' : '',
                $parcelMachine !== null ? $parcelMachine->getLocationName() ?? '' : ''
            );
        }

        return $createdDeliveryOrder;
    }
}
