<?php

declare(strict_types=1);

namespace Gls\GlsPoland\Message;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Gls\GlsPoland\Consignment\DTO\AddressDetails;
use Gls\GlsPoland\Consignment\DTO\Parcel;
use Gls\GlsPoland\Consignment\DTO\ServiceDetails;
use Gls\GlsPoland\Validator\CompatibleServices;
use Symfony\Component\Validator\Constraints as Assert;

class CreateConsignmentCommand
{
    /**
     * @var int
     *
     * @Assert\GreaterThan(0)
     */
    private $orderId;

    /**
     * @var string|null
     *
     * @Assert\Length(max="25")
     */
    private $references;

    /**
     * @var string|null
     *
     * @Assert\Length(max="80")
     */
    private $notes;

    /**
     * @var AddressDetails|null
     */
    private $senderDetails;

    /**
     * @var AddressDetails|null
     *
     * @Assert\NotNull()
     * @Assert\Valid()
     */
    private $recipientDetails;

    /**
     * @var ServiceDetails
     *
     * @CompatibleServices()
     */
    private $serviceDetails;

    private $shippingDate;

    /**
     * @var Collection<Parcel>
     *
     * @Assert\Count(min="1")
     */
    private $parcels;

    public function __construct(
        int $orderId,
        AddressDetails $recipientDetails,
        ?AddressDetails $senderDetails = null,
        ?ServiceDetails $serviceDetails = null,
        Parcel ...$parcels
    ) {
        $this->orderId = $orderId;
        $this->recipientDetails = $recipientDetails;
        $this->senderDetails = $senderDetails;
        $this->serviceDetails = $serviceDetails ?? new ServiceDetails();
        $this->parcels = new ArrayCollection($parcels);
    }

    public function getOrderId(): int
    {
        return $this->orderId;
    }

    public function getReferences(): ?string
    {
        return $this->references;
    }

    public function setReferences(?string $references): self
    {
        $this->references = $references;

        return $this;
    }

    public function getNotes(): ?string
    {
        return $this->notes;
    }

    public function setNotes(?string $notes): self
    {
        $this->notes = $notes;

        return $this;
    }

    public function getSenderDetails(): ?AddressDetails
    {
        return $this->senderDetails;
    }

    public function setSenderDetails(AddressDetails $senderDetails): self
    {
        $this->senderDetails = $senderDetails;

        return $this;
    }

    public function getRecipientDetails(): AddressDetails
    {
        return $this->recipientDetails;
    }

    public function setRecipientDetails(AddressDetails $recipientDetails): self
    {
        $this->recipientDetails = $recipientDetails;

        return $this;
    }

    public function getServiceDetails(): ServiceDetails
    {
        return $this->serviceDetails;
    }

    public function setServiceDetails(ServiceDetails $serviceDetails): self
    {
        $this->serviceDetails = $serviceDetails;

        return $this;
    }

    public function getShippingDate(): ?\DateTimeImmutable
    {
        return $this->shippingDate;
    }

    public function setShippingDate(?\DateTimeImmutable $shippingDate): self
    {
        $this->shippingDate = $shippingDate;

        return $this;
    }

    /**
     * @return Collection<Parcel>
     */
    public function getParcels(): Collection
    {
        return $this->parcels;
    }

    public function addParcel(Parcel $parcel): self
    {
        if (!$this->parcels->contains($parcel)) {
            $this->parcels->add($parcel);
        }

        return $this;
    }

    public function removeParcel(Parcel $parcel): self
    {
        if ($this->parcels->contains($parcel)) {
            $this->parcels->removeElement($parcel);
        }

        return $this;
    }
}
