<?php

namespace Lc\CaracoleBundle\Model\Section;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Lc\CaracoleBundle\Doctrine\Extension\FilterMerchantInterface;
use Lc\CaracoleBundle\Model\Merchant\MerchantInterface;
use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
use Lc\CaracoleBundle\Model\PointSale\PointSaleSectionInterface;
use Lc\CaracoleBundle\Model\Product\ProductCategoryInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilySectionPropertyInterface;
use Lc\CaracoleBundle\Model\Setting\SectionSettingInterface;
use Lc\SovBundle\Model\Newsletter\NewsletterInterface;
use Lc\SovBundle\Model\Site\NewsInterface;
use Lc\SovBundle\Model\Site\PageInterface;
use Lc\SovBundle\Doctrine\Pattern\AbstractFullEntity;

/**
 * @ORM\MappedSuperclass()
 */
abstract class SectionModel extends AbstractFullEntity implements FilterMerchantInterface, SectionInterface
{
    const DEVALIAS_COMMON = 'common';

    /**
     * @ORM\Column(type="string", length=255)
     * @Gedmo\Slug(fields={"title"}, unique=false)
     */
    protected $slug;

    /**
     * @ORM\ManyToOne(targetEntity="Lc\CaracoleBundle\Model\Merchant\MerchantInterface", inversedBy="sections")
     * @ORM\JoinColumn(nullable=false)
     */
    protected $merchant;

    /**
     * @ORM\Column(type="string", length=32)
     */
    protected $cycleType;

    const CYCLE_TYPE_DAY = 'day';
    const CYCLE_TYPE_WEEK = 'week';
    const CYCLE_TYPE_MONTH = 'month';
    const CYCLE_TYPE_YEAR = 'year';

    /**
     * @ORM\Column(type="boolean", nullable=true)
     */
    protected $isDefault;

    /**
     * @ORM\Column(type="string", length=32)
     */
    protected $color;

    /**
     * @ORM\OneToMany(targetEntity="Lc\CaracoleBundle\Model\Order\OrderShopInterface", mappedBy="section")
     */
    protected $orderShops;

    /**
     * @ORM\OneToMany(targetEntity="Lc\CaracoleBundle\Model\Product\ProductCategoryInterface", mappedBy="section")
     */
    protected $productCategories;

    /**
     * @ORM\OneToMany(targetEntity="Lc\SovBundle\Model\Site\NewsInterface", mappedBy="section")
     */
    protected $news;

    /**
     * @ORM\OneToMany(targetEntity="Lc\SovBundle\Model\Newsletter\NewsletterInterface", mappedBy="section")
     */
    protected $newsletters;

    /**
     * @ORM\OneToMany(targetEntity="Lc\SovBundle\Model\Site\PageInterface", mappedBy="section")
     */
    protected $pages;

    /**
     * @ORM\OneToMany(targetEntity="Lc\CaracoleBundle\Model\Setting\SectionSettingInterface", mappedBy="section", orphanRemoval=true, cascade={"persist"}, fetch="EAGER")
     */
    protected $settings;

    /**
     * @ORM\OneToMany(targetEntity="Lc\CaracoleBundle\Model\Section\OpeningInterface", mappedBy="section", orphanRemoval=true)
     */
    protected $openings;

    /**
     * @ORM\OneToMany(targetEntity="Lc\CaracoleBundle\Model\Product\ProductFamilySectionPropertyInterface", mappedBy="section")
     */
    protected $productFamilySectionProperties;

    /**
     * @ORM\OneToMany(targetEntity="Lc\CaracoleBundle\Model\PointSale\PointSaleSectionInterface", mappedBy="section")
     */
    protected $pointSaleSections;

    /**
     * @ORM\Column(type="boolean", nullable=true)
     */
    protected $isOnlineFrontend;

    public function __construct()
    {
        $this->orderShops = new ArrayCollection();
        $this->productCategories = new ArrayCollection();
        $this->news = new ArrayCollection();
        $this->newsletters = new ArrayCollection();
        $this->pages = new ArrayCollection();
        $this->settings = new ArrayCollection();
        $this->openings = new ArrayCollection();
        $this->productFamilySectionProperties = new ArrayCollection();
    }

    public function __toString()
    {
        return $this->getTitle();
    }

    public function getMerchant(): ?MerchantInterface
    {
        return $this->merchant;
    }

    public function setMerchant(?MerchantInterface $merchant): self
    {
        $this->merchant = $merchant;

        return $this;
    }

    public function getColor(): ?string
    {
        return $this->color;
    }

    public function setColor(string $color): self
    {
        $this->color = $color;

        return $this;
    }

    public function getCycleType(): ?string
    {
        return $this->cycleType;
    }

    public function setCycleType(string $cycleType): self
    {
        $this->cycleType = $cycleType;

        return $this;
    }

    /**
     * @return Collection|OrderShopInterface[]
     */
    public function getOrderShops(): Collection
    {
        return $this->orderShops;
    }

    public function addOrderShop(OrderShopInterface $orderShop): self
    {
        if (!$this->orderShops->contains($orderShop)) {
            $this->orderShops[] = $orderShop;
            $orderShop->setSection($this);
        }

        return $this;
    }

    public function removeOrderShop(OrderShopInterface $orderShop): self
    {
        if ($this->orderShops->contains($orderShop)) {
            $this->orderShops->removeElement($orderShop);
            // set the owning side to null (unless already changed)
            if ($orderShop->getSection() === $this) {
                $orderShop->setSection(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|ProductCategoryInterface[]
     */
    public function getProductCategories(): Collection
    {
        return $this->productCategories;
    }

    public function addProductCategory(ProductCategoryInterface $productCategory): self
    {
        if (!$this->productCategories->contains($productCategory)) {
            $this->productCategories[] = $productCategory;
            $productCategory->setSection($this);
        }

        return $this;
    }

    public function removeProductCategory(ProductCategoryInterface $productCategory): self
    {
        if ($this->productCategories->contains($productCategory)) {
            $this->productCategories->removeElement($productCategory);
            // set the owning side to null (unless already changed)
            if ($productCategory->getSection() === $this) {
                $productCategory->setSection(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|PageInterface[]
     */
    public function getPages(): Collection
    {
        return $this->pages;
    }

    public function addPage(PageInterface $page): self
    {
        if (!$this->pages->contains($page)) {
            $this->pages[] = $page;
            $page->setSection($this);
        }

        return $this;
    }

    public function removePage(PageInterface $page): self
    {
        if ($this->pages->removeElement($page)) {
            // set the owning side to null (unless already changed)
            if ($page->getSection() === $this) {
                $page->setSection(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|NewsInterface[]
     */
    public function getNews(): Collection
    {
        return $this->news;
    }

    public function addNews(NewsInterface $news): self
    {
        if (!$this->news->contains($news)) {
            $this->news[] = $news;
            $news->setSection($this);
        }

        return $this;
    }

    public function removeNews(NewsInterface $news): self
    {
        if ($this->news->contains($news)) {
            $this->news->removeElement($news);
            // set the owning side to null (unless already changed)
            if ($news->getSection() === $this) {
                $news->setSection(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|NewsletterInterface[]
     */
    public function getNewsletters(): Collection
    {
        return $this->newsletters;
    }

    public function addNewsletter(NewsletterInterface $newsletter): self
    {
        if (!$this->newsletters->contains($newsletter)) {
            $this->newsletters[] = $newsletter;
            $newsletter->setSection($this);
        }

        return $this;
    }

    public function removeNewsletter(NewsletterInterface $newsletter): self
    {
        if ($this->newsletters->contains($newsletter)) {
            $this->newsletters->removeElement($newsletter);
            // set the owning side to null (unless already changed)
            if ($newsletter->getSection() === $this) {
                $newsletter->setSection(null);
            }
        }

        return $this;
    }

    public function getIsDefault(): ?bool
    {
        return $this->isDefault;
    }

    public function setIsDefault(?bool $isDefault): self
    {
        $this->isDefault = $isDefault;

        return $this;
    }

    /**
     * @return Collection|SectionSettingInterface[]
     */
    public function getSettings(): Collection
    {
        return $this->settings;
    }

    public function addSetting(SectionSettingInterface $sectionSetting): self
    {
        if (!$this->settings->contains($sectionSetting)) {
            $this->settings[] = $sectionSetting;
            $sectionSetting->setSection($this);
        }

        return $this;
    }

    public function removeSetting(SectionSettingInterface $sectionSetting): self
    {
        if ($this->settings->contains($sectionSetting)) {
            $this->settings->removeElement($sectionSetting);
            // set the owning side to null (unless already changed)
            if ($sectionSetting->getSection() === $this) {
                $sectionSetting->setSection(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|OpeningInterface[]
     */
    public function getOpenings(): Collection
    {
        return $this->openings;
    }

    public function addOpening(OpeningInterface $opening): self
    {
        if (!$this->openings->contains($opening)) {
            $this->openings[] = $opening;
            $opening->setSection($this);
        }

        return $this;
    }

    public function removeOpening(OpeningInterface $opening): self
    {
        if ($this->openings->removeElement($opening)) {
            // set the owning side to null (unless already changed)
            if ($opening->getSection() === $this) {
                $opening->setSection(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|ProductFamilySectionPropertyInterface[]
     */
    public function getProductFamilySectionProperties(): Collection
    {
        return $this->productFamilySectionProperties;
    }

    public function addProductFamilySectionProperty(ProductFamilySectionPropertyInterface $productFamilySectionProperty): self
    {
        if (!$this->productFamilySectionProperties->contains($productFamilySectionProperty)) {
            $this->productFamilySectionProperties[] = $productFamilySectionProperty;
            $productFamilySectionProperty->setSection($this);
        }

        return $this;
    }

    public function removeProductFamilySectionProperty(ProductFamilySectionPropertyInterface $productFamilySectionProperty): self
    {
        if ($this->productFamilySectionProperties->removeElement($productFamilySectionProperty)) {
            // set the owning side to null (unless already changed)
            if ($productFamilySectionProperty->getSection() === $this) {
                $productFamilySectionProperty->setSection(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|PointSaleSectionInterface[]
     */
    public function getPointSaleSections(): Collection
    {
        return $this->pointSaleSections;
    }

    public function addPointSaleSection(PointSaleSectionInterface $pointSaleSection): self
    {
        if (!$this->pointSaleSections->contains($pointSaleSection)) {
            $this->pointSaleSections[] = $pointSaleSection;
            $pointSaleSection->setSection($this);
        }

        return $this;
    }

    public function removePointSaleSection(PointSaleSectionInterface $pointSaleSection): self
    {
        if ($this->pointSaleSections->removeElement($pointSaleSection)) {
            // set the owning side to null (unless already changed)
            if ($pointSaleSection->getSection() === $this) {
                $pointSaleSection->setSection(null);
            }
        }

        return $this;
    }

    public function getIsOnlineFrontend(): ?bool
    {
        return $this->isOnlineFrontend;
    }

    public function setIsOnlineFrontend(?bool $isOnlineFrontend): self
    {
        $this->isOnlineFrontend = $isOnlineFrontend;

        return $this;
    }
}