<?php

declare(strict_types=1);

namespace Gls\GlsPoland\PrestaShop\Order;

use Gls\GlsPoland\Configuration\Orders;
use Gls\GlsPoland\Configuration\SenderAddressConfigurationInterface;
use Gls\GlsPoland\Consignment\DTO\Parcel;
use Gls\GlsPoland\Message\CreateConsignmentCommand;
use Gls\GlsPoland\PrestaShop\ObjectModel\Repository\OrderRepository;

final class CreateConsignmentCommandFactory implements CreateConsignmentCommandFactoryInterface
{
    private $orderRepository;
    private $addressDetailsFactory;
    private $serviceDetailsFactory;
    private $ordersConfiguration;
    private $senderAddressConfiguration;

    public function __construct(OrderRepository $orderRepository, AddressDetailsFactoryInterface $addressDetailsFactory, ServiceDetailsFactory $serviceDetailsFactory, Orders\ConfigurationInterface $ordersConfiguration, SenderAddressConfigurationInterface $senderAddressConfiguration)
    {
        $this->orderRepository = $orderRepository;
        $this->addressDetailsFactory = $addressDetailsFactory;
        $this->serviceDetailsFactory = $serviceDetailsFactory;
        $this->ordersConfiguration = $ordersConfiguration;
        $this->senderAddressConfiguration = $senderAddressConfiguration;
    }

    public function create(int $orderId): CreateConsignmentCommand
    {
        if (null === $order = $this->orderRepository->find($orderId)) {
            throw new \RuntimeException('Order not found'); // TODO
        }

        $recipientDetails = $this->addressDetailsFactory->create((int) $order->id_address_delivery);
        $senderDetails = $this->senderAddressConfiguration->getSenderAddressDetails();
        $parcel = $this->createParcel($order);

        $command = new CreateConsignmentCommand(
            (int) $order->id,
            $recipientDetails,
            $senderDetails,
            $this->serviceDetailsFactory->create($order),
            $parcel
        );

        return $command
            ->setReferences($this->ordersConfiguration->getDefaultReferences())
            ->setNotes($this->ordersConfiguration->getDefaultNotes());
    }

    private function createParcel(\Order $order): Parcel
    {
        $weight = $order->getTotalWeight() ?: $this->ordersConfiguration->getDefaultParcelWeightKg();

        return (new Parcel())
            ->setWeightKg($weight)
            ->setReference($order->reference);
    }
}
