<?php

namespace Lc\ShopBundle\Model;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Lc\ShopBundle\Context\OrderProductInterface;
use Lc\ShopBundle\Context\PriceInterface;
use Lc\ShopBundle\Context\ProductInterface;
use Lc\ShopBundle\Context\ProductPropertyInterface;
use Lc\ShopBundle\Context\SortableInterface;
use Lc\ShopBundle\Services\Price;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * @ORM\MappedSuperclass()
 */
abstract class Product extends AbstractEntity implements SortableInterface, ProductPropertyInterface, PriceInterface
{
        use SortableTrait;
        use ProductPropertyTrait;
        use StatusTrait;

        /**
         * @Gedmo\Blameable(on="create")
         * @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\UserInterface")
         * @ORM\JoinColumn(nullable=true)
         */
        protected $createdBy;

        /**
         * @Gedmo\Blameable(on="update")
         * @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\UserInterface")
         * @ORM\JoinColumn(nullable=true)
         */
        protected $updatedBy;

        /**
         * @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\ProductFamilyInterface", inversedBy="products",  cascade={"persist"})
         * @ORM\JoinColumn(nullable=false)
         */
        protected $productFamily;

        /**
         * @ORM\Column(type="string", length=255, nullable=true)
         */
        protected $title;


        public function __construct()
        {
                $this->orderProducts = new ArrayCollection();
                $this->status = 1;
        }

        public function __toString()
        {
                $title = $this->getProductFamily()->getTitle() ;

                if($this->getTitle() && strlen($this->getTitle())) {
                        $title .= ' - '. $this->getTitle() ;
                }

                return $title ;
        }

        public function getBuyingPriceInherited()
        {
                if ($this->getBuyingPrice()) {
                        return $this->getBuyingPrice();
                } else {
                        return $this->getProductFamily()->getBuyingPrice();
                }
        }

        public function getBuyingPriceByRefUnitInherited()
        {
                if ($this->getBuyingPriceByRefUnit()) {
                        return $this->getBuyingPriceByRefUnit();
                } else {
                        return $this->getProductFamily()->getBuyingPriceByRefUnit();
                }
        }

        public function getPriceInherited()
        {
                if ($this->getPrice()) {
                        return $this->getPrice();
                } else {
                        return $this->getProductFamily()->getPrice();
                }
        }

        public function getPriceByRefUnitInherited()
        {
                if ($this->getPriceByRefUnit()) {
                        return $this->getPriceByRefUnit();
                } else {
                        return $this->getProductFamily()->getPriceByRefUnit();
                }
        }

        public function getBehaviorPriceInherited()
        {
                return $this->getProductFamily()->getBehaviorPrice();
        }

        public function getReductionCatalogInherited()
        {
                return $this->getProductFamily()->getReductionCatalog();
        }

        public function getUnitInherited()
        {
                if ($this->getUnit()) {
                        return $this->getUnit();
                } else {
                        return $this->getProductFamily()->getUnit();
                }
        }

        public function getTitleInherited()
        {
                if ($this->getTitle()) {
                        return $this->getTitle();
                } else {
                        return $this->getProductFamily()->getTitle();
                }
        }

        public function getQuantityInherited()
        {
                if ($this->getQuantity()) {
                        return $this->getQuantity();
                }
                else {
                        return $this->getProductFamily()->getQuantity();
                }
        }

        public function getQuantityLabelInherited()
        {
                $quantity = $this->getQuantityInherited();
                $unit = $this->getUnitInherited();
                return $quantity . $unit->getWordingShort();
        }

        public function getQuantityTitle($productFamily)
        {
                $title = $this->getQuantityLabelInherited();
                if ($productFamily->hasProductsWithVariousWeight()) {
                        $title .= ', ' . $this->getTitleInherited();
                }
                return $title;
        }

        public function getAvailableQuantityInherited()
        {
                switch ($this->getProductFamily()->getBehaviorCountStock()) {
                        case ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY :
                        case ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE :
                                return $this->getProductFamily()->getAvailableQuantity();
                                break;
                        case ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT :
                                return $this->getAvailableQuantity();
                                break;
                        case ProductFamily::BEHAVIOR_COUNT_STOCK_UNLIMITED :
                                return false;
                                break;
                }
        }

        public function getTaxRateInherited()
        {
                return $this->getProductFamily()->getTaxRateInherited();
        }

        public function getProductFamily(): ?ProductFamily
        {
                return $this->productFamily;
        }

        public function setProductFamily(?ProductFamily $productFamily): self
        {
                $this->productFamily = $productFamily;

                return $this;
        }

        public function getTitle(): ?string
        {
                return $this->title;
        }

        public function setTitle(?string $title): self
        {
                $this->title = $title;

                return $this;
        }
}
