<?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
 */
namespace Paysera\Delivery\Model;

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

use Paysera\Delivery\Entity\ShipmentRequest;
use Paysera\Delivery\Normalizer\ShipmentRequestNormalizer;

class ShipmentRequestModel
{
    public const NON_PREFIXED_TABLE_NAME = 'paysera_delivery_shipping_request';
    public const PREFIXED_TABLE_NAME = _DB_PREFIX_ . self::NON_PREFIXED_TABLE_NAME;

    /**
     * @var \Db
     */
    private $db;
    /**
     * @var ShipmentRequestNormalizer
     */
    private $shipmentRequestNormalizer;

    public function __construct($db, ShipmentRequestNormalizer $shipmentRequestNormalizer)
    {
        $this->db = $db;
        $this->shipmentRequestNormalizer = $shipmentRequestNormalizer;
    }

    public function findOrCreate(int $order_id): ShipmentRequest
    {
        $shipmentRequest = $this->find($order_id);

        if ($shipmentRequest === null) {
            $shipmentRequest = new ShipmentRequest();
            $shipmentRequest->setOrderId($order_id);
            $shipmentRequest->setStatus(ShipmentRequest::STATUS_NEW);
        }

        return $shipmentRequest;
    }

    public function save(ShipmentRequest $shipmentRequest): ShipmentRequest
    {
        if ($shipmentRequest->getId() === null) {
            return $this->create($shipmentRequest);
        } else {
            return $this->update($shipmentRequest);
        }
    }

    public function find(int $order_id): ?ShipmentRequest
    {
        $row = $this->db->getRow(
            sprintf(
                'SELECT * 
                FROM `%s`
                WHERE `order_id` = %d',
                self::PREFIXED_TABLE_NAME,
                $order_id
            )
        );

        return is_array($row)
            ? $this->shipmentRequestNormalizer->mapToEntity($row)
            : null;
    }

    public function create(ShipmentRequest $shipmentRequest): ShipmentRequest
    {
        $gateway = $shipmentRequest->getShippingRequestGateway();

        $this->db->insert(
            self::NON_PREFIXED_TABLE_NAME,
            [
                'order_id' => $shipmentRequest->getOrderId(),
                'carrier_code' => $shipmentRequest->getCarrierCode(),
                'carrier_type' => $shipmentRequest->getCarrierType(),
                'status' => $shipmentRequest->getStatus(),
                'gateway_iso_code_2' => $gateway !== null ? $gateway->getIsoCode2() : null,
                'gateway_city' => $gateway !== null ? $gateway->getCity() : null,
                'gateway_terminal' => $gateway !== null ? $gateway->getTerminal() : null,
                'delivery_order_api_id' => $shipmentRequest->getDeliveryOrderApiId(),
            ]
        );

        return $this->find($shipmentRequest->getOrderId());
    }

    public function update(ShipmentRequest $shipmentRequest): ShipmentRequest
    {
        $gateway = $shipmentRequest->getShippingRequestGateway();

        $this->db->update(
            self::NON_PREFIXED_TABLE_NAME,
            [
                'carrier_code' => $shipmentRequest->getCarrierCode(),
                'carrier_type' => $shipmentRequest->getCarrierType(),
                'status' => $shipmentRequest->getStatus(),
                'gateway_iso_code_2' => $gateway !== null ? $gateway->getIsoCode2() : null,
                'gateway_city' => $gateway !== null ? $gateway->getCity() : null,
                'gateway_terminal' => $gateway !== null ? $gateway->getTerminal() : null,
                'delivery_order_api_id' => $shipmentRequest->getDeliveryOrderApiId(),
            ],
            sprintf('order_id = %s', $shipmentRequest->getOrderId())
        );

        return $shipmentRequest;
    }
}
