<?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\Normalizer;

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

use Paysera\Delivery\Entity\ShipmentRequest;
use Paysera\Delivery\Entity\ShipmentRequestGateway;
use Paysera\Delivery\Service\Logger;

class ShipmentRequestNormalizer
{
    /**
     * @var Logger
     */
    private $logger;
    public function __construct(Logger $logger)
    {
       $this->logger = $logger;
    }
    public function mapToEntity(array $data): ShipmentRequest
    {
        try {
            $this->validate($data);
        } catch (\InvalidArgumentException $exception) {
            $this->logger->error(sprintf('ShipmentRequestNormalizer: %s', $exception->getMessage()));
            throw $exception;
        }

        $shipmentRequest = new ShipmentRequest();

        $shipmentRequest->setOrderId((int) $data['order_id']);
        $shipmentRequest->setCarrierCode($data['carrier_code']);
        $shipmentRequest->setCarrierType($data['carrier_type']);
        $shipmentRequest->setStatus($data['status']);
        $shipmentRequest->setDeliveryOrderApiId($data['delivery_order_api_id'] ?? null);

        if (isset($data['id'])) {
            $shipmentRequest->setId((int) $data['id']);
        }

        $shipmentRequest->setDeliveryOrderApiId($data['delivery_order_api_id'] ?? null);

        $isoCode2 = $data['gateway_iso_code_2'] ?? null;
        $city = $data['gateway_city'] ?? null;
        $terminal = $data['gateway_terminal'] ?? null;

        if (is_string($isoCode2) || is_string($city) || is_string($terminal)) {
            $shipmentRequest->setShippingRequestGateway(
                new ShipmentRequestGateway(
                    $isoCode2,
                    $city,
                    $terminal
                )
            );
        }

        return $shipmentRequest;
    }

    private function validate(array $data): void
    {
        $requiredFields = ['order_id', 'carrier_code', 'carrier_type', 'status'];

        foreach ($requiredFields as $field) {
            if (!isset($data[$field])) {
                throw new \InvalidArgumentException(sprintf('Missing required field: %s', $field));
            }
        }

        if (isset($data['id']) && !is_int((int) $data['id'])) {
            throw new \InvalidArgumentException('Invalid type for field: id');
        }

        if (!is_int((int)$data['order_id'])) {
            throw new \InvalidArgumentException('Invalid type for field: order_id');
        }

        if (!is_string($data['carrier_code'])) {
            throw new \InvalidArgumentException('Invalid type for field: carrier_code');
        }

        if (!is_string($data['carrier_type'])) {
            throw new \InvalidArgumentException('Invalid type for field: carrier_type');
        }

        if (!is_string($data['status'])) {
            throw new \InvalidArgumentException('Invalid type for field: status');
        }
    }
}
