<?php

namespace App\Entity;

use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;

#[ORM\Entity(repositoryClass: UserRepository::class)]
#[ORM\Table(name: '`user`')]
class User implements UserInterface, PasswordAuthenticatedUserInterface
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 180, unique: true)]
    private ?string $email = null;

    #[ORM\Column]
    private array $roles = [];

    /**
     * @var string The hashed password
     */
    #[ORM\Column]
    private ?string $password = null;

    #[ORM\Column(length: 255)]
    private ?string $firstname = null;

    #[ORM\Column(length: 255)]
    private ?string $lastname = null;

    #[ORM\Column(type: Types::SMALLINT)]
    private ?int $gender = null;

    #[ORM\Column(length: 255, nullable: true)]
    private ?string $pseudo = null;

    #[ORM\Column(type: Types::DATE_MUTABLE)]
    private ?\DateTimeInterface $birthdate = null;

    #[ORM\Column(length: 255)]
    private ?string $phoneNumber = null;

    #[ORM\Column(type: Types::DATETIME_MUTABLE)]
    private ?\DateTimeInterface $lastLogin = null;

    #[ORM\Column(type: Types::DATETIME_MUTABLE)]
    private ?\DateTimeInterface $dateAdd = null;

    #[ORM\Column]
    private ?int $frais = 0;
    
    #[ORM\Column]
    private ?bool $isDeleted = false;

    #[ORM\OneToMany(mappedBy: 'create_by', targetEntity: Position::class)]
    private Collection $positions;

    #[ORM\OneToMany(mappedBy: 'create_by', targetEntity: Ligne::class)]
    private Collection $lignes;

    #[ORM\Column(length: 255)]
    private ?string $country = null;

    #[ORM\Column]
    private ?int $zip = null;

    #[ORM\Column(length: 350)]
    private ?string $adresse = null;

    #[ORM\Column(type: Types::DATETIME_MUTABLE)]
    private ?\DateTimeInterface $LastChangePassword = null;

    #[ORM\OneToMany(mappedBy: 'origine', targetEntity: Parrainage::class)]
    private Collection $parrainages;

    #[ORM\OneToMany(mappedBy: 'profile', targetEntity: Newslettre::class)]
    private Collection $newslettres;

    #[ORM\OneToMany(mappedBy: 'create_by', targetEntity: Article::class)]
    private Collection $articles;

    #[ORM\OneToMany(mappedBy: 'create_by', targetEntity: Service::class)]
    private Collection $services;

    #[ORM\OneToMany(mappedBy: 'createBy', targetEntity: ServiceRdv::class)]
    private Collection $serviceRdvs;

    #[ORM\OneToMany(mappedBy: 'client', targetEntity: ReservationArticle::class)]
    private Collection $reservationArticles;

    #[ORM\OneToMany(mappedBy: 'client', targetEntity: ReservationService::class)]
    private Collection $reservationServices;

    #[ORM\OneToMany(mappedBy: 'partenaire', targetEntity: Partenaire::class)]
    private Collection $partenaires;

    #[ORM\OneToMany(mappedBy: 'client', targetEntity: CommentArticle::class)]
    private Collection $commentArticles;

    #[ORM\OneToMany(mappedBy: 'client', targetEntity: CommentService::class)]
    private Collection $commentServices;

    #[ORM\OneToMany(mappedBy: 'client', targetEntity: CommentAnnonce::class)]
    private Collection $commentAnnonces;


    public function __construct()
    {
        $this->isDeleted = false;
        $this->dateAdd = new \DateTime();
        $this->lastLogin = new \DateTime();
        $this->LastChangePassword = new \DateTime();
        $this->positions = new ArrayCollection();
        $this->lignes = new ArrayCollection();
        $this->parrainages = new ArrayCollection();
        $this->newslettres = new ArrayCollection();
        $this->articles = new ArrayCollection();
        $this->services = new ArrayCollection();
        $this->serviceRdvs = new ArrayCollection();
        $this->reservationArticles = new ArrayCollection();
        $this->reservationServices = new ArrayCollection();
        $this->partenaires = new ArrayCollection();
        $this->commentArticles = new ArrayCollection();
        $this->commentServices = new ArrayCollection();
        $this->commentAnnonces = new ArrayCollection();
    }


    public function getId(): ?int
    {
        return $this->id;
    }

    public function getEmail(): ?string
    {
        return $this->email;
    }

    public function setEmail(string $email): self
    {
        $this->email = $email;

        return $this;
    }

    /**
     * A visual identifier that represents this user.
     *
     * @see UserInterface
     */
    public function getUserIdentifier(): string
    {
        return (string) $this->email;
    }

    /**
     * @see UserInterface
     */
    public function getRoles(): array
    {
        $roles = $this->roles;
        // guarantee every user at least has ROLE_USER
        $roles[] = 'ROLE_USER';

        return array_unique($roles);
    }

    public function setRoles(array $roles): self
    {
        $this->roles = $roles;

        return $this;
    }

    public function hasRole(string $role): ?bool
    {
        $Indice = array_search($role, $this->roles);
        if(is_numeric($Indice)){
            return true;
        }else{
            return false;
        }
    }
    
    public function addRole(string $role): ?bool
    {
        if(!$this->hasRole($role)){
            $this->roles[] = $role;
            return true;
        }
        return false;
    }

    /**
     * @see PasswordAuthenticatedUserInterface
     */
    public function getPassword(): string
    {
        return $this->password;
    }

    public function setPassword(string $password): self
    {
        $this->password = $password;

        return $this;
    }

    /**
     * @see UserInterface
     */
    public function eraseCredentials(): void
    {
        
    }

    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 getFullName(): ?string
    {
        return $this->firstname." ".$this->lastname;
    }


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

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

        return $this;
    }

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

    public function setPseudo(?string $pseudo): self
    {
        $this->pseudo = $pseudo;

        return $this;
    }

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

    public function setBirthdate(\DateTimeInterface $birthdate): self
    {
        $this->birthdate = $birthdate;

        return $this;
    }

    public function getPhoneNumber(): ?string
    {
        return $this->phoneNumber;
    }

    public function setPhoneNumber(string $phoneNumber): self
    {
        $this->phoneNumber = $phoneNumber;

        return $this;
    }

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

    public function setLastLogin(\DateTimeInterface $lastLogin): self
    {
        $this->lastLogin = $lastLogin;

        return $this;
    }

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

    public function setDateAdd(\DateTimeInterface $dateAdd): self
    {
        $this->dateAdd = $dateAdd;

        return $this;
    }

    public function getIsDeleted(): ?bool
    {
        return $this->isDeleted;
    }

    public function setIsDeleted(bool $isDeleted): self
    {
        $this->isDeleted = $isDeleted;

        return $this;
    }

    /**
     * @return Collection<int, Position>
     */
    public function getPositions(): Collection
    {
        return $this->positions;
    }

    public function addPosition(Position $position): static
    {
        if (!$this->positions->contains($position)) {
            $this->positions->add($position);
            $position->setCreateBy($this);
        }

        return $this;
    }

    public function removePosition(Position $position): static
    {
        if ($this->positions->removeElement($position)) {
            // set the owning side to null (unless already changed)
            if ($position->getCreateBy() === $this) {
                $position->setCreateBy(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Ligne>
     */
    public function getLignes(): Collection
    {
        return $this->lignes;
    }

    public function addLigne(Ligne $ligne): static
    {
        if (!$this->lignes->contains($ligne)) {
            $this->lignes->add($ligne);
            $ligne->setCreateBy($this);
        }

        return $this;
    }

    public function removeLigne(Ligne $ligne): static
    {
        if ($this->lignes->removeElement($ligne)) {
            // set the owning side to null (unless already changed)
            if ($ligne->getCreateBy() === $this) {
                $ligne->setCreateBy(null);
            }
        }

        return $this;
    }

    public function getCountry(): ?string
    {
        return $this->country;
    }

    public function setCountry(string $country): static
    {
        $this->country = $country;

        return $this;
    }

    public function getZip(): ?int
    {
        return $this->zip;
    }

    public function setZip(int $zip): static
    {
        $this->zip = $zip;

        return $this;
    }

    public function getAdresse(): ?string
    {
        return $this->adresse;
    }

    public function setAdresse(string $adresse): static
    {
        $this->adresse = $adresse;

        return $this;
    }

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

    public function setLastChangePassword(\DateTimeInterface $LastChangePassword): static
    {
        $this->LastChangePassword = $LastChangePassword;

        return $this;
    }

    /**
     * @return Collection<int, Parrainage>
     */
    public function getParrainages(): Collection
    {
        return $this->parrainages;
    }

    public function addParrainage(Parrainage $parrainage): static
    {
        if (!$this->parrainages->contains($parrainage)) {
            $this->parrainages->add($parrainage);
            $parrainage->setOrigine($this);
        }

        return $this;
    }

    public function removeParrainage(Parrainage $parrainage): static
    {
        if ($this->parrainages->removeElement($parrainage)) {
            // set the owning side to null (unless already changed)
            if ($parrainage->getOrigine() === $this) {
                $parrainage->setOrigine(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Newslettre>
     */
    public function getNewslettres(): Collection
    {
        return $this->newslettres;
    }

    public function addNewslettre(Newslettre $newslettre): static
    {
        if (!$this->newslettres->contains($newslettre)) {
            $this->newslettres->add($newslettre);
            $newslettre->setProfile($this);
        }

        return $this;
    }

    public function removeNewslettre(Newslettre $newslettre): static
    {
        if ($this->newslettres->removeElement($newslettre)) {
            // set the owning side to null (unless already changed)
            if ($newslettre->getProfile() === $this) {
                $newslettre->setProfile(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Article>
     */
    public function getArticles(): Collection
    {
        return $this->articles;
    }

    public function addArticle(Article $article): static
    {
        if (!$this->articles->contains($article)) {
            $this->articles->add($article);
            $article->setCreateBy($this);
        }

        return $this;
    }

    public function removeArticle(Article $article): static
    {
        if ($this->articles->removeElement($article)) {
            // set the owning side to null (unless already changed)
            if ($article->getCreateBy() === $this) {
                $article->setCreateBy(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Service>
     */
    public function getServices(): Collection
    {
        return $this->services;
    }

    public function addService(Service $service): static
    {
        if (!$this->services->contains($service)) {
            $this->services->add($service);
            $service->setCreateBy($this);
        }

        return $this;
    }

    public function removeService(Service $service): static
    {
        if ($this->services->removeElement($service)) {
            // set the owning side to null (unless already changed)
            if ($service->getCreateBy() === $this) {
                $service->setCreateBy(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, ServiceRdv>
     */
    public function getServiceRdvs(): Collection
    {
        return $this->serviceRdvs;
    }

    public function addServiceRdv(ServiceRdv $serviceRdv): static
    {
        if (!$this->serviceRdvs->contains($serviceRdv)) {
            $this->serviceRdvs->add($serviceRdv);
            $serviceRdv->setCreateBy($this);
        }

        return $this;
    }

    public function removeServiceRdv(ServiceRdv $serviceRdv): static
    {
        if ($this->serviceRdvs->removeElement($serviceRdv)) {
            // set the owning side to null (unless already changed)
            if ($serviceRdv->getCreateBy() === $this) {
                $serviceRdv->setCreateBy(null);
            }
        }

        return $this;
    }

    public function getFrais(): ?int
    {
        return $this->frais;
    }

    public function setFrais(int $frais): static
    {
        $this->frais = $frais;

        return $this;
    }

    
    public function getPanier($request, $detail = false): ?array
    {
        $session = $request->getSession();

        $nameSession = 'Panier-'.$this->id;

        $data = $session->get($nameSession);

        $paniers = ($data)? $data : [];

        if($detail)
        {
            $total = $nbr = 0;

            foreach($paniers as $panier){
                $total += $panier['avance'];
                $nbr++;
            }

            return ['paniers'=>$paniers, 'total'=> $total, 'nbr'=>$nbr];
        }
        
        return $paniers;
    }

    public function setPanier($request, $data): ?array
    {
        $session = $request->getSession();

        $nameSession = 'Panier-'.$this->id;

        $paniers = $session->get($nameSession);
        
        $paniers[] = $data;

        $session->set($nameSession, $paniers);

        return $session->get($nameSession);
    }

    /**
     * @return Collection<int, ReservationArticle>
     */
    public function getReservationArticles(): Collection
    {
        return $this->reservationArticles;
    }

    public function addReservationArticle(ReservationArticle $reservationArticle): static
    {
        if (!$this->reservationArticles->contains($reservationArticle)) {
            $this->reservationArticles->add($reservationArticle);
            $reservationArticle->setClient($this);
        }

        return $this;
    }

    public function removeReservationArticle(ReservationArticle $reservationArticle): static
    {
        if ($this->reservationArticles->removeElement($reservationArticle)) {
            // set the owning side to null (unless already changed)
            if ($reservationArticle->getClient() === $this) {
                $reservationArticle->setClient(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, ReservationService>
     */
    public function getReservationServices(): Collection
    {
        return $this->reservationServices;
    }

    public function addReservationService(ReservationService $reservationService): static
    {
        if (!$this->reservationServices->contains($reservationService)) {
            $this->reservationServices->add($reservationService);
            $reservationService->setClient($this);
        }

        return $this;
    }

    public function removeReservationService(ReservationService $reservationService): static
    {
        if ($this->reservationServices->removeElement($reservationService)) {
            // set the owning side to null (unless already changed)
            if ($reservationService->getClient() === $this) {
                $reservationService->setClient(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Partenaire>
     */
    public function getPartenaires(): Collection
    {
        return $this->partenaires;
    }


    public function getPartenairesActive()
    {
        $arrPartenaires = [];
        foreach($this->partenaires as $partenaire){
            if($partenaire->isActive() && $partenaire->getSociete()->isActive()){
                $arrPartenaires[] = $partenaire;
            }
        }
        
        return $arrPartenaires;
    }

    public function addPartenaire(Partenaire $partenaire): static
    {
        if (!$this->partenaires->contains($partenaire)) {
            $this->partenaires->add($partenaire);
            $partenaire->setPartenaire($this);
        }

        return $this;
    }

    public function removePartenaire(Partenaire $partenaire): static
    {
        if ($this->partenaires->removeElement($partenaire)) {
            // set the owning side to null (unless already changed)
            if ($partenaire->getPartenaire() === $this) {
                $partenaire->setPartenaire(null);
            }
        }

        return $this;
    }

    public function isActiveRolePartner(): bool
    {
        if($this->getIsDeleted()){ return false;}

        foreach($this->partenaires as $partner){
            if($partner->isActive()){
                return true;
            }
        }
        
        return false;
    }


    public function getSelectPartner(){
        foreach($this->partenaires as $partner){
            if($partner->isActive() && $partner->isSelected()){
                return $partner;
            }
        }
    }

    /**
     * @return Collection<int, CommentArticle>
     */
    public function getCommentArticles(): Collection
    {
        return $this->commentArticles;
    }

    public function addCommentArticle(CommentArticle $commentArticle): static
    {
        if (!$this->commentArticles->contains($commentArticle)) {
            $this->commentArticles->add($commentArticle);
            $commentArticle->setClient($this);
        }

        return $this;
    }

    public function removeCommentArticle(CommentArticle $commentArticle): static
    {
        if ($this->commentArticles->removeElement($commentArticle)) {
            // set the owning side to null (unless already changed)
            if ($commentArticle->getClient() === $this) {
                $commentArticle->setClient(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, CommentService>
     */
    public function getCommentServices(): Collection
    {
        return $this->commentServices;
    }

    public function addCommentService(CommentService $commentService): static
    {
        if (!$this->commentServices->contains($commentService)) {
            $this->commentServices->add($commentService);
            $commentService->setClient($this);
        }

        return $this;
    }

    public function removeCommentService(CommentService $commentService): static
    {
        if ($this->commentServices->removeElement($commentService)) {
            // set the owning side to null (unless already changed)
            if ($commentService->getClient() === $this) {
                $commentService->setClient(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, CommentAnnonce>
     */
    public function getCommentAnnonces(): Collection
    {
        return $this->commentAnnonces;
    }

    public function addCommentAnnonce(CommentAnnonce $commentAnnonce): static
    {
        if (!$this->commentAnnonces->contains($commentAnnonce)) {
            $this->commentAnnonces->add($commentAnnonce);
            $commentAnnonce->setClient($this);
        }

        return $this;
    }

    public function removeCommentAnnonce(CommentAnnonce $commentAnnonce): static
    {
        if ($this->commentAnnonces->removeElement($commentAnnonce)) {
            // set the owning side to null (unless already changed)
            if ($commentAnnonce->getClient() === $this) {
                $commentAnnonce->setClient(null);
            }
        }

        return $this;
    }


}
