<?php

declare(strict_types=1);

namespace Gls\GlsPoland\Configuration\Orders;

use Gls\GlsPoland\AdePlus\Printout\LabelsPrintMode;
use Gls\GlsPoland\AdePlus\Printout\PickupReceiptPrintMode;
use Symfony\Component\Validator\Constraints as Assert;

final class InMemoryConfiguration implements ConfigurationInterface
{
    /**
     * @var LabelsPrintMode|null
     *
     * @Assert\NotNull()
     */
    private $labelPrintMode;

    /**
     * @var PickupReceiptPrintMode|null
     *
     * @Assert\NotNull()
     */
    private $pickupReceiptPrintMode;

    /**
     * @var bool|null
     *
     * @Assert\NotNull()
     */
    private $downloadLabelsAsSingleFile;

    /**
     * @var int|null
     */
    private $labelPrintedStatusId;

    /**
     * @var int|null
     */
    private $consignmentDeletedStatusId;

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

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

    /**
     * @var float|null
     *
     * @Assert\NotNull()
     * @Assert\GreaterThanOrEqual(0.01)
     */
    private $defaultParcelWeightKg;

    public function __construct(
        LabelsPrintMode $labelPrintMode = null,
        PickupReceiptPrintMode $pickupReceiptPrintMode = null,
        bool $downloadLabelsAsSingleFile = null,
        int $labelPrintedStatusId = null,
        int $consignmentDeletedStatusId = null,
        string $defaultReferences = null,
        string $defaultNotes = null,
        float $defaultParcelWeightKg = null
    ) {
        $this->labelPrintMode = $labelPrintMode;
        $this->pickupReceiptPrintMode = $pickupReceiptPrintMode;
        $this->downloadLabelsAsSingleFile = $downloadLabelsAsSingleFile;
        $this->labelPrintedStatusId = $labelPrintedStatusId;
        $this->consignmentDeletedStatusId = $consignmentDeletedStatusId;
        $this->defaultReferences = $defaultReferences;
        $this->defaultNotes = $defaultNotes;
        $this->defaultParcelWeightKg = $defaultParcelWeightKg;
    }

    public static function from(ConfigurationInterface $configuration): self
    {
        return new self(
            $configuration->getLabelsPrintMode(),
            $configuration->getPickupReceiptPrintMode(),
            $configuration->isDownloadLabelsAsSingleFile(),
            $configuration->getLabelPrintedOrderStatusId(),
            $configuration->getConsignmentDeletedOrderStatusId(),
            $configuration->getDefaultReferences(),
            $configuration->getDefaultNotes(),
            $configuration->getDefaultParcelWeightKg()
        );
    }

    public function getLabelsPrintMode(): LabelsPrintMode
    {
        return $this->labelPrintMode ?? LabelsPrintMode::from(current(LabelsPrintMode::PRINT_MODES));
    }

    public function setLabelsPrintMode(?LabelsPrintMode $printMode): self
    {
        $this->labelPrintMode = $printMode;

        return $this;
    }

    public function getPickupReceiptPrintMode(): PickupReceiptPrintMode
    {
        return $this->pickupReceiptPrintMode ?? PickupReceiptPrintMode::from(current(PickupReceiptPrintMode::PRINT_MODES));
    }

    public function setPickupReceiptPrintMode(?PickupReceiptPrintMode $printMode): self
    {
        $this->pickupReceiptPrintMode = $printMode;

        return $this;
    }

    public function isDownloadLabelsAsSingleFile(): bool
    {
        return $this->downloadLabelsAsSingleFile ?? false;
    }

    public function setDownloadLabelsAsSingleFile(?bool $downloadAsSingleFile): self
    {
        $this->downloadLabelsAsSingleFile = $downloadAsSingleFile;

        return $this;
    }

    public function getLabelPrintedOrderStatusId(): ?int
    {
        return $this->labelPrintedStatusId;
    }

    public function setLabelPrintedOrderStatusId(?int $statusId): self
    {
        $this->labelPrintedStatusId = $statusId;

        return $this;
    }

    public function getConsignmentDeletedOrderStatusId(): ?int
    {
        return $this->consignmentDeletedStatusId;
    }

    public function setConsignmentDeletedOrderStatusId(?int $statusId): self
    {
        $this->consignmentDeletedStatusId = $statusId;

        return $this;
    }

    public function getDefaultReferences(): ?string
    {
        return $this->defaultReferences;
    }

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

        return $this;
    }

    public function getDefaultNotes(): ?string
    {
        return $this->defaultNotes;
    }

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

        return $this;
    }

    public function getDefaultParcelWeightKg(): float
    {
        return $this->defaultParcelWeightKg ?? 0.3;
    }

    public function setDefaultParcelWeightKg(?float $weight): self
    {
        $this->defaultParcelWeightKg = $weight;

        return $this;
    }
}
