<?php

namespace Lc\ShopBundle\Model;

use App\Entity\OrderStatus;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;
use Lc\ShopBundle\Context\DocumentInterface;
use Lc\ShopBundle\Context\FilterMerchantInterface;

/**
 * @ORM\MappedSuperclass()
 */
abstract class OrderShop extends AbstractEntity implements FilterMerchantInterface
{
        /**
         * @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\MerchantInterface", inversedBy="productFamilies")
         * @ORM\JoinColumn(nullable=false)
         */
        protected $merchant;

        /**
         * @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\UserInterface", inversedBy="orders")
         */
        protected $user;

        /**
         * @ORM\ManyToOne(targetEntity="App\Entity\Visitor", inversedBy="orders")
         */
        protected $visitor;

        /**
         * @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\AddressInterface")
         */
        protected $invoiceAddress;

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

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

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

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

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

        /**
         * @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\OrderStatusHistoryInterface", mappedBy="orderShop", orphanRemoval=true)
         */
        protected $orderStatusHistories;

        /**
         * @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\OrderPaymentInterface", mappedBy="orderShop", orphanRemoval=true)
         */
        protected $orderPayments;

        /**
         * @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\OrderProductInterface", mappedBy="orderShop", cascade={"persist", "remove"}, orphanRemoval=true)
         */
        protected $orderProducts;

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

        /**
         * @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\OrderStatusInterface")
         * @ORM\JoinColumn(nullable=false)
         */
        protected $orderStatus;

        /**
         * @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\OrderReductionCartInterface", mappedBy="orderShop", orphanRemoval=true)
         */
        protected $orderReductionCarts;

        /**
         * @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\OrderReductionCreditInterface", mappedBy="orderShop", orphanRemoval=true)
         */
        protected $orderReductionCredits;

        /**
         * @ORM\ManyToMany(targetEntity="Lc\ShopBundle\Context\DocumentInterface", inversedBy="orderShops")
         */
        protected $documents;

        /**
         * @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\OneToMany(targetEntity="Lc\ShopBundle\Context\TicketInterface", mappedBy="orderShop")
         */
        protected $tickets;

        public function __construct()
        {
                $this->orderStatusHistories = new ArrayCollection();
                $this->orderPayments = new ArrayCollection();
                $this->orderProducts = new ArrayCollection();
                $this->creditHistories = new ArrayCollection();
                $this->orderReductionCarts = new ArrayCollection();
                $this->orderReductionCredits = new ArrayCollection();
                $this->documents = new ArrayCollection();
        }

        public function __toString()
        {
                if($this->getValidationDate()) {
                        return 'Commande du '.$this->getValidationDate()->format('d/m/Y') ;
                }
                else {
                        return 'Commande #'.$this->getId() ;
                }
        }

        public function getValidationDate(): ?\DateTimeInterface
        {
                return $this->validationDate;
        }

        public function setValidationDate(\DateTimeInterface $validationDate): self
        {
                $this->validationDate = $validationDate;

                return $this;
        }

        public function getDateCreated()
        {
                $orderStatusHistory = $this->getOrderStatusHistory('new');
                if ($orderStatusHistory) {
                        return $orderStatusHistory->getCreatedAt();
                }

                return null;
        }

        public function getOrderStatusHistory($status)
        {
                $orderStatusHistories = $this->getOrderStatusHistories();
                if (count($orderStatusHistories) > 0) {
                        foreach ($orderStatusHistories as $orderStatusHistory) {
                                if ($orderStatusHistory->getOrderStatus() == $status) {
                                        return $orderStatusHistory;
                                }
                        }
                }

                return null;
        }

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

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

                return $this;
        }

        public function getUser(): ?User
        {
                return $this->user;
        }

        public function setUser(?User $user): self
        {
                $this->user = $user;

                return $this;
        }

        public function getInvoiceAddress(): ?Address
        {
                return $this->invoiceAddress;
        }

        public function setInvoiceAddress(?Address $invoiceAddress): self
        {
                $this->invoiceAddress = $invoiceAddress;

                return $this;
        }

        public function getInvoiceAddressText(): ?string
        {
                return $this->invoiceAddressText;
        }

        public function setInvoiceAddressText(string $invoiceAddressText): self
        {
                $this->invoiceAddressText = $invoiceAddressText;

                return $this;
        }

        public function getComment(): ?string
        {
                return $this->comment;
        }

        public function setComment(?string $comment): self
        {
                $this->comment = $comment;

                return $this;
        }

        public function getAutoPayment(): ?bool
        {
                return $this->autoPayment;
        }

        public function setAutoPayment(bool $autoPayment): self
        {
                $this->autoPayment = $autoPayment;

                return $this;
        }

        public function getMeanPayment(): ?string
        {
                return $this->meanPayment;
        }

        public function setMeanPayment(string $meanPayment): self
        {
                $this->meanPayment = $meanPayment;

                return $this;
        }

        /**
         * @return Collection|OrderStatusHistory[]
         */
        public function getOrderStatusHistories(): Collection
        {
                return $this->orderStatusHistories;
        }

        public function addOrderStatusHistory(OrderStatusHistory $orderStatusHistory): self
        {
                if (!$this->orderStatusHistories->contains($orderStatusHistory)) {
                        $this->orderStatusHistories[] = $orderStatusHistory;
                        $orderStatusHistory->setOrderShop($this);
                }

                return $this;
        }

        public function removeOrderStatusHistory(OrderStatusHistory $orderStatusHistory): self
        {
                if ($this->orderStatusHistories->contains($orderStatusHistory)) {
                        $this->orderStatusHistories->removeElement($orderStatusHistory);
                        // set the owning side to null (unless already changed)
                        if ($orderStatusHistory->getOrderShop() === $this) {
                                $orderStatusHistory->setOrderShop(null);
                        }
                }

                return $this;
        }

        /**
         * @return Collection|OrderPayment[]
         */
        public function getOrderPayments(): Collection
        {
                return $this->orderPayments;
        }

        public function addOrderPayment(OrderPayment $orderPayment): self
        {
                if (!$this->orderPayments->contains($orderPayment)) {
                        $this->orderPayments[] = $orderPayment;
                        $orderPayment->setOrderShop($this);
                }

                return $this;
        }

        public function removeOrderPayment(OrderPayment $orderPayment): self
        {
                if ($this->orderPayments->contains($orderPayment)) {
                        $this->orderPayments->removeElement($orderPayment);
                        // set the owning side to null (unless already changed)
                        if ($orderPayment->getOrderShop() === $this) {
                                $orderPayment->setOrderShop(null);
                        }
                }

                return $this;
        }

        /**
         * @return Collection|OrderProduct[]
         */
        public function getOrderProducts(): Collection
        {
                return $this->orderProducts;
        }

        public function addOrderProduct(OrderProduct $orderProduct): self
        {
                if (!$this->orderProducts->contains($orderProduct)) {
                        $this->orderProducts[] = $orderProduct;
                        $orderProduct->setOrderShop($this);
                }

                return $this;
        }

        public function removeOrderProduct(OrderProduct $orderProduct): self
        {
                if ($this->orderProducts->contains($orderProduct)) {
                        $this->orderProducts->removeElement($orderProduct);
                        // set the owning side to null (unless already changed)
                        if ($orderProduct->getOrderShop() === $this) {
                                $orderProduct->setOrderShop(null);
                        }
                }

                return $this;
        }

        /**
         * @return Collection|CreditHistory[]
         */
        public function getCreditHistories(): Collection
        {
                return $this->creditHistories;
        }

        public function addCreditHistory(CreditHistory $creditHistory): self
        {
                if (!$this->creditHistories->contains($creditHistory)) {
                        $this->creditHistories[] = $creditHistory;
                        $creditHistory->setOrderShop($this);
                }

                return $this;
        }

        public function removeCreditHistory(CreditHistory $creditHistory): self
        {
                if ($this->creditHistories->contains($creditHistory)) {
                        $this->creditHistories->removeElement($creditHistory);
                        // set the owning side to null (unless already changed)
                        if ($creditHistory->getOrderShop() === $this) {
                                $creditHistory->setOrderShop(null);
                        }
                }

                return $this;
        }

        public function getVisitor(): ?Visitor
        {
                return $this->visitor;
        }

        public function setVisitor(?Visitor $visitor): self
        {
                $this->visitor = $visitor;

                return $this;
        }

        public function getDeliveryInfos(): ?string
        {
                return $this->deliveryInfos;
        }

        public function setDeliveryInfos(?string $deliveryInfos): self
        {
                $this->deliveryInfos = $deliveryInfos;

                return $this;
        }


        public function getOrderStatus(): ?OrderStatus
        {
                return $this->orderStatus;
        }

        public function setOrderStatusProtected(?OrderStatus $orderStatus): self
        {
                $this->orderStatus = $orderStatus;

                return $this;
        }


        /**
         * @return Collection|OrderReductionCart[]
         */
        public function getOrderReductionCarts(): Collection
        {
                return $this->orderReductionCarts;
        }

        public function addOrderReductionCart(OrderReductionCart $orderReductionCart): self
        {
                if (!$this->orderReductionCarts->contains($orderReductionCart)) {
                        $this->orderReductionCarts[] = $orderReductionCart;
                        $orderReductionCart->setOrderShop($this);
                }

                return $this;
        }

        public function removeOrderReductionCart(OrderReductionCart $orderReductionCart): self
        {
                if ($this->orderReductionCarts->contains($orderReductionCart)) {
                        $this->orderReductionCarts->removeElement($orderReductionCart);
                        // set the owning side to null (unless already changed)
                        if ($orderReductionCart->getOrderShop() === $this) {
                                $orderReductionCart->setOrderShop(null);
                        }
                }

                return $this;
        }

        /**
         * @return Collection|OrderReductionCart[]
         */
        public function getOrderReductionCredits(): Collection
        {
                return $this->orderReductionCredits;
        }

        public function addOrderReductionCredit(OrderReductionCredit $orderReductionCredit): self
        {
                if (!$this->orderReductionCredits->contains($orderReductionCredit)) {
                        $this->orderReductionCredits[] = $orderReductionCredit;
                        $orderReductionCredit->setOrderShop($this);
                }

                return $this;
        }

        public function removeOrderReductionCredit(OrderReductionCredit $orderReductionCredit): self
        {
                if ($this->orderReductionCredits->contains($orderReductionCredit)) {
                        $this->orderReductionCredits->removeElement($orderReductionCredit);
                        // set the owning side to null (unless already changed)
                        if ($orderReductionCredit->getOrderShop() === $this) {
                                $orderReductionCredit->setOrderShop(null);
                        }
                }

                return $this;
        }

        /**
         * @return Collection|Document[]
         */
        public function getDocuments(): Collection
        {
                return $this->documents;
        }

        public function addDocument(Document $document): self
        {
                if (!$this->documents->contains($document)) {
                        $this->documents[] = $document;
                }

                return $this;
        }

        public function removeDocument(Document $document): self
        {
                if ($this->documents->contains($document)) {
                        $this->documents->removeElement($document);
                }

                return $this;
        }


        /**
         * @return Collection|Ticket[]
         */
        public function getTickets(): Collection
        {
                return $this->tickets;
        }

        public function addTicket(Ticket $ticket): self
        {
                if (!$this->tickets->contains($ticket)) {
                        $this->tickets[] = $ticket;
                        $ticket->setOrderShop($this);
                }

                return $this;
        }

        public function removeTicket(Ticket $ticket): self
        {
                if ($this->tickets->contains($ticket)) {
                        $this->tickets->removeElement($ticket);
                        // set the owning side to null (unless already changed)
                        if ($ticket->getOrderShop() === $this) {
                                $ticket->setOrderShop(null);
                        }
                }

                return $this;
        }

        public function isValid() {
                if($this->getOrderStatus() && in_array($this->getOrderStatus()->getAlias(), OrderStatus::$statusAliasAsValid) > 0) {
                        return true ;
                }

                return false ;
        }

        public function isCart() {
                if($this->getOrderStatus() && in_array($this->getOrderStatus()->getAlias(), OrderStatus::$statusAliasAsCart) > 0) {
                        return true ;
                }

                return false ;
        }

}
