<?php

namespace Lc\ShopBundle\Model;

use App\Entity\Newsletter;
use App\Entity\Ticket;
use App\Entity\UserPointSale;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use FOS\UserBundle\Model\User as UserModelFOS;
use Lc\ShopBundle\Context\MerchantInterface;
use Lc\ShopBundle\Context\TicketInterface;

/**
 * @ORM\MappedSuperclass()
 *
 */
abstract class User extends UserModelFOS
{
        /**
         * @ORM\Column(type="string", length=20, nullable=true)
         */
        protected $phone;

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

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

        /**
         * @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\AddressInterface", mappedBy="user", cascade={"persist"})
         */
        protected $addresses;

        /**
         * @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\OrderShopInterface", mappedBy="user")
         */
        protected $orders;


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

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

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

        /**
         * @ORM\ManyToMany(targetEntity="Lc\ShopBundle\Context\NewsletterInterface", inversedBy="users")
         */
        protected $newsletters;

        /**
         * @ORM\ManyToMany(targetEntity="Lc\ShopBundle\Context\GroupUserInterface", inversedBy="users")
         */
        protected $groupUsers;

        /**
         * @ORM\ManyToMany(targetEntity="Lc\ShopBundle\Context\ProductFamilyInterface")
         */
        protected $favoriteProductFamilies;

        /**
         * @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\UserPointSaleInterface", mappedBy="user", orphanRemoval=true)
         */
        protected $userPointSales;

        /**
         * @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\UserMerchantInterface", mappedBy="user", orphanRemoval=true)
         */
        protected $userMerchants;

        /**
         * @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\TicketInterface", mappedBy="user")
         */
        protected $tickets;

        /**
         * @ORM\Column(type="datetime")
         * @Gedmo\Timestampable(on="create")
         */
        protected $createdAt;

        /**
         * @ORM\Column(type="datetime")
         * @Gedmo\Timestampable(on="update")
         */
        protected $updatedAt;

        public function __construct()
        {
                parent::__construct();
                $this->addresses = new ArrayCollection();
                $this->orders = new ArrayCollection();
                $this->groupUsers = new ArrayCollection();
                $this->newsletters = new ArrayCollection();
                $this->favoriteProductFamilies = new ArrayCollection();
                $this->userPointSales = new ArrayCollection();
                $this->userMerchants = new ArrayCollection();
        }

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

        public function getSummary()
        {
                return '#'.$this->getId().' '.strtoupper($this->getLastname()).' '.$this->getFirstname(). ' ('.$this->getEmail().')';
        }

        public function getName()
        {
                return (string) ucfirst(strtolower($this->getFirstname())). ' '.strtoupper($this->getLastname());
        }

        public function setEmail($email)
        {
                $this->setUsername($email);
                return parent::setEmail($email);
        }

        public function getPhone(): ?string
        {
                return $this->phone;
        }

        public function setPhone(?string $phone): self
        {
                $this->phone = $phone;

                return $this;
        }

        public function getBehaviorDisplayPrice(): ?string
        {
                return $this->behaviorDisplayPrice;
        }

        public function setBehaviorDisplayPrice(?string $behaviorDisplayPrice): self
        {
                $this->behaviorDisplayPrice = $behaviorDisplayPrice;

                return $this;
        }

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

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

                return $this;
        }

        /**
         * @return Collection|Address[]
         */
        public function getAddresses(): Collection
        {
                return $this->addresses;
        }

        public function addAddress(Address $address): self
        {
                if (!$this->addresses->contains($address)) {
                        $this->addresses[] = $address;
                        $address->setUser($this);
                }

                return $this;
        }

        public function removeAddress(Address $address): self
        {
                if ($this->addresses->contains($address)) {
                        $this->addresses->removeElement($address);
                        // set the owning side to null (unless already changed)
                        if ($address->getUser() === $this) {
                                $address->setUser(null);
                        }
                }

                return $this;
        }

        /**
         * @return Collection|OrderShop[]
         */
        public function getOrders(): Collection
        {
                return $this->orders;
        }

        public function addOrder(OrderShop $order): self
        {
                if (!$this->orders->contains($order)) {
                        $this->orders[] = $order;
                        $order->setUser($this);
                }

                return $this;
        }

        public function removeOrder(OrderShop $order): self
        {
                if ($this->orders->contains($order)) {
                        $this->orders->removeElement($order);
                        // set the owning side to null (unless already changed)
                        if ($order->getUser() === $this) {
                                $order->setUser(null);
                        }
                }

                return $this;
        }

        public function getFirstname(): ?string
        {
                return $this->firstname;
        }

        public function setFirstname(?string $firstname): self
        {
                $this->firstname = $firstname;

                return $this;
        }

        public function getLastname(): ?string
        {
                return $this->lastname;
        }

        public function setLastname(?string $lastname): self
        {
                $this->lastname = $lastname;

                return $this;
        }

        public function getGender(): ?bool
        {
                return $this->gender;
        }

        public function setGender(?bool $gender): self
        {
                $this->gender = $gender;

                return $this;
        }

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

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

                return $this;
        }

        public function removeNewsletter(Newsletter $newsletter): self
        {
                if ($this->newsletters->contains($newsletter)) {
                        $this->newsletters->removeElement($newsletter);
                }

                return $this;
        }

        /**
         * @return Collection|GroupUser[]
         */
        public function getGroupUsers(): Collection
        {
                return $this->groupUsers;
        }

        public function addGroupUser(GroupUser $groupUser): self
        {
                if (!$this->groupUsers->contains($groupUser)) {
                        $this->groupUsers[] = $groupUser;
                        $groupUser->addUser($this);
                }

                return $this;
        }

        public function removeGroupUser(GroupUser $groupUser): self
        {
                if ($this->groupUsers->contains($groupUser)) {
                        $this->groupUsers->removeElement($groupUser);
                        $groupUser->removeUser($this);
                }

                return $this;
        }

        /**
         * @return Collection|ProductFamily[]
         */
        public function getFavoriteProductFamilies(): Collection
        {
                return $this->favoriteProductFamilies;
        }

        public function addFavoriteProductFamily(ProductFamily $favoriteProductFamily): self
        {
                if (!$this->favoriteProductFamilies->contains($favoriteProductFamily)) {
                        $this->favoriteProductFamilies[] = $favoriteProductFamily;
                }

                return $this;
        }

        public function removeFavoriteProductFamily(ProductFamily $favoriteProductFamily): self
        {
                if ($this->favoriteProductFamilies->contains($favoriteProductFamily)) {
                        $this->favoriteProductFamilies->removeElement($favoriteProductFamily);
                }

                return $this;
        }

        /**
         * @return Collection|UserPointSale[]
         */
        public function getUserPointSales(): Collection
        {
                return $this->userPointSales;
        }

        public function addUserPointSale(UserPointSale $userPointSale): self
        {
                if (!$this->userPointSales->contains($userPointSale)) {
                        $this->userPointSales[] = $userPointSale;
                        $userPointSale->setUser($this);
                }

                return $this;
        }

        public function removeUserPointSale(UserPointSale $userPointSale): self
        {
                if ($this->userPointSales->contains($userPointSale)) {
                        $this->userPointSales->removeElement($userPointSale);
                        // set the owning side to null (unless already changed)
                        if ($userPointSale->getUser() === $this) {
                                $userPointSale->setUser(null);
                        }
                }

                return $this;
        }

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

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

                return $this;
        }

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

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

        public function setCreatedAt(\DateTimeInterface $createdAt): self
        {
                $this->createdAt = $createdAt;

                return $this;
        }

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

        public function setUpdatedAt(\DateTimeInterface $updatedAt): self
        {
                $this->updatedAt = $updatedAt;

                return $this;
        }
}