<?php
/**
 * @author Colinet Julien
 */

namespace CpCreation\VitiCore\Product\Model;

use CpCreation\VitiCore\Behavior\HasTimestamp;
use CpCreation\VitiCore\Behavior\HasTranslatable;
use CpCreation\VitiCore\Behavior\Impl\Timestamp;
use CpCreation\VitiCore\Behavior\Impl\Translatable;
use CpCreation\VitiCore\Shop\Model\ShippingZone;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Sortable\Sortable;
use Knp\DoctrineBehaviors\Contract\Entity\TranslationInterface;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * Class ProductType
 *
 * @ORM\Entity(repositoryClass="CpCreation\VitiCore\Product\Repository\ProductTypeRepository")
 * @ORM\Table(name="product_type")
 * @ORM\HasLifecycleCallbacks()
 */
class ProductType implements HasTimestamp, Sortable, HasTranslatable
{
    use Timestamp, Translatable;

    /**
     * @Assert\Valid
     * @AcmeAssert\Translation()
     * @ORM\OneToMany(targetEntity="CpCreation\VitiCore\Product\Model\Translation\ProductTypeTranslation", mappedBy="translatable", cascade={"persist","remove","merge"}, indexBy="locale", orphanRemoval="true")
     *
     * @var TranslationInterface[]|Collection
     */
    protected $translations;

    /**
     * @ORM\Id()
     * @ORM\Column(type="uuid")
     * @ORM\GeneratedValue(strategy="NONE")
     *
     * @var UuidInterface
     */
    private $id;

    /**
     * @var integer
     *
     * @ORM\Column(type="integer")
     * @Gedmo\SortablePosition()
     */
    private $position;

    /**
     * @ORM\Column(type="decimal", precision=5, scale=2, nullable=true)
     *
     * @var float
     */
    private $volume;

    /**
     * @ORM\Column(type="string", nullable=true)
     *
     * @var string
     */
    private $unity;

    /**
     * @ORM\Column(type="integer", nullable=true)
     *
     * @var integer
     */
    private $maximumQuantityCart = null;

    /**
     * @ORM\Column(type="integer")
     * @Assert\NotBlank()
     *
     * @var integer
     */
    private $multipleQuantityCart;

    /**
     * @ORM\Column(type="integer")
     *
     * @var integer
     */
    private $multipleQuantityDepot;

    /**
     * @ORM\Column(type="decimal", precision=4, scale=2)
     * @Assert\NotBlank()
     *
     * @var float
     */
    private $equivalencyManu;

    /**
     * @ORM\Column(type="decimal", precision=4, scale=2)
     * @Assert\NotBlank()
     *
     * @var float
     */
    private $equivalency;

    /**
     * @ORM\Column(type="decimal", precision=4, scale=2, options={"default" : 1})
     * @Assert\NotBlank()
     *
     * @var float
     */
    private $equivalencyDegressive;

    /**
     * @ORM\Column(type="decimal", precision=4, scale=2)
     * @Assert\NotBlank()
     *
     * @var float
     */
    private $equivalencyFreeShipping;

    /**
     * @ORM\Column(type="boolean")
     *
     * @var boolean
     */
    private $equivalencyDefault;

    /**
     * @ORM\Column(type="boolean")
     *
     * @var boolean
     */
    private $equivalencyOnShipping;

    /**
     * @ORM\Column(type="boolean")
     *
     * @var boolean
     */
    private $equivalencyDefaultQuantity;

    /**
     * @ORM\Column(type="boolean")
     *
     * @var boolean
     */
    private $equivalencyOnFreeShipping;

    /**
     * @ORM\Column(type="boolean")
     *
     * @var boolean
     */
    private $disabledShippingManu;

    /**
     * @ORM\Column(type="boolean")
     *
     * @var boolean
     */
    private $disabledShippingAuto;

    /**
     * @ORM\Column(type="boolean")
     *
     * @var boolean
     */
    private $freeShippingWithBottle;

    /**
     * @ORM\Column(type="integer", nullable=true)
     *
     * @var integer|null
     */
    private $minFreeShippingWithBottle;

    /**
     * @ORM\Column(type="boolean", options={"default" : 0})
     *
     * @var boolean
     */
    private $accessory;

    /**
     * @ORM\Column(type="integer", nullable=true)
     *
     * @var integer|null
     */
    private $orderWithaMinimumEquivalency;

    /**
     * @ORM\ManyToMany(targetEntity="CpCreation\VitiCore\Shop\Model\ShippingZone")
     *
     * @var Collection | ShippingZone[]
     */
    private $zonesFreeShipping;

    /**
     * @ORM\Column(type="boolean",options={"default" : 0})
     *
     * @var bool
     */
    private bool $gift;

    /**
     * @ORM\OneToMany(targetEntity="ProductTypeOption",mappedBy="productType", cascade={"all"})
     * @var Collection<ProductTypeOption>
     */
    private $options;

    public function __construct()
    {
        $this->id                         = Uuid::uuid4();
        $this->equivalencyOnShipping      = 0;
        $this->equivalencyOnFreeShipping  = 0;
        $this->equivalencyDefault         = 0;
        $this->equivalencyDefaultQuantity = 0;
        $this->freeShippingWithBottle     = 0;
        $this->disabledShippingManu       = false;
        $this->disabledShippingAuto       = false;
        $this->accessory                  = false;
        $this->gift                       = false;
        $this->zonesFreeShipping          = new ArrayCollection();
        $this->options                    = new ArrayCollection();
    }

    /**
     * @return UuidInterface
     */
    public function getId(): UuidInterface
    {
        return $this->id;
    }

    /**
     * @return int
     */
    public function getPosition(): ?int
    {
        return $this->position;
    }

    /**
     * @param int $position
     */
    public function setPosition(int $position): void
    {
        $this->position = $position;
    }

    /**
     * @return float
     */
    public function getVolume(): ?float
    {
        return $this->volume;
    }

    /**
     * @param float $volume
     */
    public function setVolume(float $volume = null): void
    {
        $this->volume = $volume;
    }

    /**
     * @return string
     */
    public function getUnity(): ?string
    {
        return $this->unity;
    }

    /**
     * @param string $unity
     */
    public function setUnity(string $unity = null): void
    {
        $this->unity = $unity;
    }

    /**
     * @return int
     */
    public function getMaximumQuantityCart(): ?int
    {
        return $this->maximumQuantityCart;
    }

    /**
     * @param int $maximumQuantityCart
     */
    public function setMaximumQuantityCart(?int $maximumQuantityCart): void
    {
        $this->maximumQuantityCart = $maximumQuantityCart;
    }

    /**
     * @return float
     */
    public function getEquivalencyManu(): ?float
    {
        return $this->equivalencyManu;
    }

    /**
     * @param float $equivalencyManu
     */
    public function setEquivalencyManu(float $equivalencyManu = null): void
    {
        $this->equivalencyManu = $equivalencyManu;
    }

    /**
     * @return float
     */
    public function getEquivalency(): ?float
    {
        return $this->equivalency;
    }

    /**
     * @param float $equivalency
     */
    public function setEquivalency(float $equivalency = null): void
    {
        $this->equivalency = $equivalency;
    }

    /**
     * @return float
     */
    public function getEquivalencyDegressive(): ?float
    {
        return $this->equivalencyDegressive;
    }

    /**
     * @param float $equivalencyDegressive
     */
    public function setEquivalencyDegressive(?float $equivalencyDegressive): void
    {
        $this->equivalencyDegressive = $equivalencyDegressive;
    }


    /**
     * @return float
     */
    public function getEquivalencyFreeShipping(): ?float
    {
        return $this->equivalencyFreeShipping;
    }

    /**
     * @param float $equivalencyFreeShipping
     */
    public function setEquivalencyFreeShipping(float $equivalencyFreeShipping = null): void
    {
        $this->equivalencyFreeShipping = $equivalencyFreeShipping;
    }


    /**
     * @return bool
     */
    public function isEquivalencyDefault(): bool
    {
        return $this->equivalencyDefault;
    }

    /**
     * @param bool $equivalencyDefault
     */
    public function setEquivalencyDefault(bool $equivalencyDefault): void
    {
        $this->equivalencyDefault = $equivalencyDefault;
    }

    /**
     * @return bool
     */
    public function isEquivalencyOnShipping(): bool
    {
        return $this->equivalencyOnShipping;
    }

    /**
     * @param bool $equivalencyOnShipping
     */
    public function setEquivalencyOnShipping(bool $equivalencyOnShipping): void
    {
        $this->equivalencyOnShipping = $equivalencyOnShipping;
    }

    /**
     * @return bool
     */
    public function isEquivalencyOnFreeShipping(): bool
    {
        return $this->equivalencyOnFreeShipping;
    }

    /**
     * @param bool $equivalencyOnFreeShipping
     */
    public function setEquivalencyOnFreeShipping(bool $equivalencyOnFreeShipping): void
    {
        $this->equivalencyOnFreeShipping = $equivalencyOnFreeShipping;
    }

    /**
     * @return bool
     */
    public function isEquivalencyDefaultQuantity(): bool
    {
        return $this->equivalencyDefaultQuantity;
    }

    /**
     * @param bool $equivalencyDefaultQuantity
     */
    public function setEquivalencyDefaultQuantity(bool $equivalencyDefaultQuantity)
    {
        $this->equivalencyDefaultQuantity = $equivalencyDefaultQuantity;
    }

    /**
     * @return int
     */
    public function getMultipleQuantityCart(): ?int
    {
        return $this->multipleQuantityCart;
    }

    /**
     * @param int $multipleQuantityCart
     */
    public function setMultipleQuantityCart(int $multipleQuantityCart = null): void
    {
        $this->multipleQuantityCart = $multipleQuantityCart;
    }

    /**
     * @return int
     */
    public function getMultipleQuantityDepot(): ?int
    {
        return $this->multipleQuantityDepot;
    }

    /**
     * @param int $multipleQuantityDepot
     */
    public function setMultipleQuantityDepot(int $multipleQuantityDepot): void
    {
        $this->multipleQuantityDepot = $multipleQuantityDepot;
    }

    /**
     * @return bool
     */
    public function isFreeShippingWithBottle(): bool
    {
        return $this->freeShippingWithBottle;
    }

    /**
     * @param bool $freeShippingWithBottle
     */
    public function setFreeShippingWithBottle(bool $freeShippingWithBottle): void
    {
        $this->freeShippingWithBottle = $freeShippingWithBottle;
    }

    /**
     * @return bool
     */
    public function isDisabledShippingManu(): bool
    {
        return $this->disabledShippingManu;
    }

    /**
     * @param bool $disabledShippingManu
     */
    public function setDisabledShippingManu(bool $disabledShippingManu): void
    {
        $this->disabledShippingManu = $disabledShippingManu;
    }

    /**
     * @return bool
     */
    public function isDisabledShippingAuto(): bool
    {
        return $this->disabledShippingAuto;
    }

    /**
     * @param bool $disabledShippingAuto
     */
    public function setDisabledShippingAuto(bool $disabledShippingAuto): void
    {
        $this->disabledShippingAuto = $disabledShippingAuto;
    }

    /**
     * @return bool
     */
    public function isAccessory(): bool
    {
        return $this->accessory;
    }

    /**
     * @param bool $accessory
     */
    public function setAccessory(bool $accessory): void
    {
        $this->accessory = $accessory;
    }

    /**
     * @return int|null
     */
    public function getOrderWithaMinimumEquivalency(): ?int
    {
        return $this->orderWithaMinimumEquivalency;
    }

    /**
     * @param int|null $orderWithaMinimumEquivalency
     */
    public function setOrderWithaMinimumEquivalency(?int $orderWithaMinimumEquivalency): void
    {
        $this->orderWithaMinimumEquivalency = $orderWithaMinimumEquivalency;
    }

    /**
     * @return int|null
     */
    public function getMinFreeShippingWithBottle(): ?int
    {
        return $this->minFreeShippingWithBottle;
    }

    /**
     * @param int|null $minFreeShippingWithBottle
     */
    public function setMinFreeShippingWithBottle(?int $minFreeShippingWithBottle): void
    {
        $this->minFreeShippingWithBottle = $minFreeShippingWithBottle;
    }


    /**
     * @param ShippingZone $zone
     * @return $this
     */
    public function addZonesFreeShipping(ShippingZone $zone)
    {
        $this->zonesFreeShipping[] = $zone;

        return $this;
    }

    /**
     * @param ShippingZone $zone
     */
    public function removeZonesFreeShipping(ShippingZone $zone)
    {
        $this->zonesFreeShipping->removeElement($zone);
    }

    /**
     * @return Collection | ShippingZone[]
     */
    public function getZonesFreeShipping(): Collection
    {
        return $this->zonesFreeShipping;
    }

    /**
     * @return bool
     */
    public function isGift(): bool
    {
        return $this->gift;
    }

    /**
     * @param bool $gift
     */
    public function setGift(bool $gift): void
    {
        $this->gift = $gift;
    }


    public function getZonesFreeShippingId(): array
    {
        $id = [];
        foreach ($this->zonesFreeShipping as $zone) {
            $id[] = $zone->getId()->toString();
        }

        return $id;
    }
}
