<?php

declare(strict_types=1);

namespace Gls\GlsPoland\MessageHandler\Consignment;

use Gls\GlsPoland\AdePlus\PreparingBox\ClientInterface;
use Gls\GlsPoland\Consignment\Exception\ConsignmentAlreadyPickedUpException;
use Gls\GlsPoland\Consignment\Exception\ConsignmentNotFoundException;
use Gls\GlsPoland\EventDispatcher\EventDispatcherInterface;
use Gls\GlsPoland\Message\DeleteConsignmentCommand;
use Gls\GlsPoland\Repository\ConsignmentRepository;

final class DeleteConsignmentHandler implements DeleteConsignmentHandlerInterface
{
    private $repository;
    private $client;
    private $dispatcher;

    public function __construct(ConsignmentRepository $repository, ClientInterface $client, EventDispatcherInterface $dispatcher)
    {
        $this->repository = $repository;
        $this->client = $client;
        $this->dispatcher = $dispatcher;
    }

    public function handle(DeleteConsignmentCommand $command): void
    {
        if (null === $consignment = $this->repository->find($command->getConsignmentId())) {
            throw ConsignmentNotFoundException::create($command->getConsignmentId());
        }

        if (null !== $consignment->getPickupId()) {
            throw ConsignmentAlreadyPickedUpException::create($consignment->getId(), $consignment->getPickupId());
        }

        $this->client->deleteConsignment($consignment->getPreparingBoxId());
        $this->repository->remove($consignment);

        $this->dispatcher->dispatch(new ConsignmentEvent($consignment), ConsignmentEvent::DELETED);
    }
}
