<?php

namespace App\Entity;

use App\Repository\ClientRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Ignore;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\SerializedName;

/**
 * @ORM\Entity(repositoryClass=ClientRepository::class)
 * @ORM\Table(schema="sav")
 */
class Client
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     * @Groups({"api", "site_list", "map", "planning"})
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity=EtatCivil::class, inversedBy="clients")
     * @ORM\JoinColumn(name="idetat_civil")
     * @Groups({"api", "map", "planning"})
     */
    private $etat_civil;

    /**
     * @ORM\Column(type="string", length=25, nullable=true)
     * @Groups({"api", "site_list", "map", "planning"})
     */
    private $nom;

    /**
     * @Groups({"api"})
     */
    private $motif_modif_client_nom;

    /**
     * @Groups({"api"})
     */
    private $motif_modif_client_nom_si_autre;

    /**
     * @ORM\Column(type="string", length=50, nullable=true)
     * @Groups({"api", "site_list", "map", "planning"})
     */
    private $prenom;

    /**
     * @Groups({"api"})
     */
    private $motif_modif_client_prenom;

    /**
     * @Groups({"api"})
     */
    private $motif_modif_client_prenom_si_autre;

    /**
     * @ORM\ManyToOne(targetEntity=TypeClient::class, inversedBy="clients")
     * @ORM\JoinColumn(name="idtype_client")
     * @Groups({"api", "map", "planning"})
     */
    private $type_client;

    /**
     * @Groups({"api"})
     */
    private $motif_modif_client_type;

    /**
     * @Groups({"api"})
     */
    private $motif_modif_client_type_si_autre;

    /**
     * @ORM\ManyToOne(targetEntity=CategoriePro::class, inversedBy="clients")
     * @ORM\JoinColumn(name="idcategorie_pro")
     * @Groups({"api", "map", "planning"})
     */
    private $categorie_pro;

    /**
     * @ORM\ManyToOne(targetEntity=CompteClientWeb::class, inversedBy="clients")
     * @ORM\JoinColumn(name="idcompte_client_web")
     * @Ignore()
     */
    private $compte_client_web;

    /**
     * @ORM\Column(type="string", length=100, nullable=true)
     * @Groups({"api", "site_list", "map", "planning"})
     */
    private $nom_entreprise;

    /**
     * @ORM\Column(type="string", length=50, nullable=true)
     * @Groups({"api", "site_list"})
     */
    private $num_siren;

    /**
     * @ORM\Column(type="string", length=50, nullable=true)
     * @Groups({"api", "site_list"})
     */
    private $num_siret;

    /**
     * @ORM\Column(type="string", length=50, nullable=true)
     * @Groups({"api", "site_list"})
     */
    private $num_tva_intra;

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

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

    /**
     * @ORM\OneToMany(targetEntity=ClientAdresse::class, mappedBy="client", orphanRemoval=true, cascade={"persist"})
     * @Ignore()
     */
    private $clientAdresses;

    /**
     * @ORM\OneToMany(targetEntity=ClientEmail::class, mappedBy="client", orphanRemoval=true,  cascade={"persist"})
     * @Groups({"api"})
     */
    private $clientEmails;

    /**
     * @ORM\OneToMany(targetEntity=ClientTel::class, mappedBy="client", orphanRemoval=true)
     * @Groups({"api"})
     */
    private $clientTels;

    /**
     * @ORM\OneToMany(targetEntity=Equipement::class, mappedBy="client_souscripteur", cascade={"persist"})
     * @Ignore()
     */
    private $equipements;

    /**
     * @ORM\OneToMany(targetEntity=Equipement::class, mappedBy="client_utilisateur")
     * @Ignore()
     */
    private $equipements_client_utilisateur;

    /**
     * @ORM\OneToMany(targetEntity=Contrat::class, mappedBy="client")
     * @Ignore()
     */
    private $contrats;

    /**
     * @ORM\OneToMany(targetEntity=ClientSite::class, mappedBy="client", orphanRemoval=true,  cascade={"persist"})
     * @Ignore()
     */
    private $clientSites;

    /**
     * @ORM\Column(type="string", length=9, nullable=true)
     * @Groups({"api", "site_list", "planning"})
     */
    private $numero_client;

    /**
     * * @ORM\ManyToOne(targetEntity=Client::class, inversedBy="clients")
     * * @ORM\JoinColumn(name="idclient_tutelle")
     * * @Groups({"api", "planning"})
    */
    private $client_tutelle;

    /**
     * @ORM\OneToMany(targetEntity=PorteOuverte::class, mappedBy="client")
     * @Ignore()
     */
    private $porteOuvertes;

    /**
     * @ORM\OneToMany(targetEntity=HistoriqueEquipementUtilisateur::class, mappedBy="utilisateur", orphanRemoval=true)
     * @Ignore()
     */
    private $historiqueEquipementUtilisateurs;

    public function __construct()
    {
        $this->clientAdresses = new ArrayCollection();
        $this->clientEmails = new ArrayCollection();
        $this->clientTels = new ArrayCollection();
        $this->equipements = new ArrayCollection();
        $this->equipements_client_utilisateur = new ArrayCollection();
        $this->contrats = new ArrayCollection();
        $this->clientSites = new ArrayCollection();
        $this->porteOuvertes = new ArrayCollection();
        $this->historiqueEquipementUtilisateurs = new ArrayCollection();
    }

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

    public function setId(?int $id): self
    {
        $this->id = $id;

        return $this;
    }

    public function getEtatCivil(): ?EtatCivil
    {
        return $this->etat_civil;
    }

    public function setEtatCivil(?EtatCivil $etat_civil): self
    {
        $this->etat_civil = $etat_civil;

        return $this;
    }

    public function getNom(): ?string
    {
        return $this->nom;
    }

    public function setNom(?string $nom): self
    {
        $this->nom = strtoupper($nom);

        return $this;
    }

    public function getPrenom(): ?string
    {
        return $this->prenom;
    }

    public function setPrenom(?string $prenom): self
    {
        $this->prenom = $prenom;

        return $this;
    }

    public function getIdentite(): ?string
    {
        if($this->getTypeClient()->getId() == TypeClient::ID_TYPE_PARTICULIER) {
            return $this->getEtatCivil()->getLibelleCourt() . ' ' . $this->getNom() . ' ' . $this->getPrenom();
        }elseif($this->getTypeClient()->getId() == TypeClient::ID_TYPE_PRO) {
            return $this->getCategoriePro()->getLibelle() . ' ' . $this->getNomEntreprise();
        }
    }

    /**
     * @Ignore()
     */
    public function getTypeClient(): ?TypeClient
    {
        return $this->type_client;
    }

    public function setTypeClient(?TypeClient $type_client): self
    {
        $this->type_client = $type_client;

        return $this;
    }
    /**
     * @Ignore()
     */
    public function getCategoriePro(): ?CategoriePro
    {
        return $this->categorie_pro;
    }

    public function setCategoriePro(?CategoriePro $categorie_pro): self
    {
        $this->categorie_pro = $categorie_pro;

        return $this;
    }
    /**
     * @Ignore()
     */
    public function getCompteClientWeb(): ?CompteClientWeb
    {
        return $this->compte_client_web;
    }

    public function setCompteClientWeb(?CompteClientWeb $compte_client_web): self
    {
        $this->compte_client_web = $compte_client_web;

        return $this;
    }

    public function getNomEntreprise(): ?string
    {
        return $this->nom_entreprise;
    }

    public function setNomEntreprise(?string $nom_entreprise): self
    {
        $this->nom_entreprise = $nom_entreprise;

        return $this;
    }

    public function getOptInEmail(): ?bool
    {
        return $this->opt_in_email;
    }

    public function setOptInEmail(?bool $opt_in_email): self
    {
        $this->opt_in_email = $opt_in_email;

        return $this;
    }

    public function getOptInSms(): ?bool
    {
        return $this->opt_in_sms;
    }

    public function setOptInSms(?bool $opt_in_sms): self
    {
        $this->opt_in_sms = $opt_in_sms;

        return $this;
    }

    /**
     * @Ignore()
     * @return Collection<int, ClientAdresse>
     */
    public function getClientAdresses(): Collection
    {
        return $this->clientAdresses;
    }

    /**
     * @SerializedName("adresse")
     */
    public function getAdresse() {
        foreach ($this->clientAdresses as $clientAdress) {
            if ($clientAdress->getActif()) return $clientAdress->getAdresse()->getLisibleAdresse();
        }
        return null;
    }

    public function getAdresseActive() {
        foreach ($this->clientAdresses as $clientAdress) {
            if ($clientAdress->getActif()) return $clientAdress->getAdresse();
        }
        return null;
    }

    public function addClientAdress(ClientAdresse $clientAdress): self
    {
        if (!$this->clientAdresses->contains($clientAdress)) {
            $this->clientAdresses[] = $clientAdress;
            $clientAdress->setClient($this);
        }

        return $this;
    }

    public function removeClientAdress(ClientAdresse $clientAdress): self
    {
        if ($this->clientAdresses->removeElement($clientAdress)) {
            // set the owning side to null (unless already changed)
            if ($clientAdress->getClient() === $this) {
                $clientAdress->setClient(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, ClientEmail>
     */
    public function getClientEmails(): Collection
    {
        return $this->clientEmails;
    }

    public function getArrayMails() {
        return  $this->clientEmails->map(function($clientEmails) {
            return (string)$clientEmails;
        })->toArray();
    }

    public function addClientEmail(ClientEmail $clientEmail): self
    {
        if (!$this->clientEmails->contains($clientEmail)) {
            $this->clientEmails[] = $clientEmail;
            $clientEmail->setClient($this);
        }

        return $this;
    }

    public function removeClientEmail(ClientEmail $clientEmail): self
    {
        if ($this->clientEmails->removeElement($clientEmail)) {
            // set the owning side to null (unless already changed)
            if ($clientEmail->getClient() === $this) {
                $clientEmail->setClient(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, ClientTel>
     */
    public function getClientTels(): Collection
    {
        return $this->clientTels;
    }

    public function getArrayTels() {
        return  $this->clientTels->map(function($clientTel) {
            return (string)$clientTel;
        })->toArray();
    }

    public function addClientTel(ClientTel $clientTel): self
    {
        if (!$this->clientTels->contains($clientTel)) {
            $this->clientTels[] = $clientTel;
            $clientTel->setClient($this);
        }

        return $this;
    }

    public function removeClientTel(ClientTel $clientTel): self
    {
        if ($this->clientTels->removeElement($clientTel)) {
            // set the owning side to null (unless already changed)
            if ($clientTel->getClient() === $this) {
                $clientTel->setClient(null);
            }
        }

        return $this;
    }

    /**
     * @Ignore()
     * @return Collection<int, Equipement>
     */
    public function getEquipementsActif()
    {
        $result = [];
        foreach ($this->equipements as $equipement) {
            if ($equipement->getActif()) $result[] = $equipement;
        }
        return $result;
    }

    /**
     * @Ignore()
     * @return Collection<int, Equipement>
     */
    public function getEquipementsInactif()
    {
        $result = [];
        foreach ($this->equipements as $equipement) {
            if (!$equipement->getActif()) $result[] = $equipement;
        }
        return $result;
    }

    /**
     * @Ignore()
     */
    public function getEquipementPrincipal()
    {
        if (!$this->getAdresse()) return null;
        foreach ($this->equipements as $equipement) {
            if ($equipement->getActif() && $equipement->getAdresse() == $this->clientAdresses->first()->getAdresse()) return $equipement;
        }
        return null;
    }


    /**
     * @Ignore()
     * @return Collection<int, Equipement>
     */
    public function getEquipements(): Collection
    {
        return $this->equipements;
    }

    public function addEquipement(Equipement $equipement): self
    {
        if (!$this->equipements->contains($equipement)) {
            $this->equipements[] = $equipement;
            $equipement->setClientSouscripteur($this);
        }

        return $this;
    }

    public function removeEquipement(Equipement $equipement): self
    {
        if ($this->equipements->removeElement($equipement)) {
            // set the owning side to null (unless already changed)
            if ($equipement->getClientSouscripteur() === $this) {
                $equipement->setClientSouscripteur(null);
            }
        }

        return $this;
    }

    /**
     * @Ignore()
     * @return Collection<int, Equipement>
     */
    public function getEquipementsClientUtilisateur(): Collection
    {
        return $this->equipements_client_utilisateur;
    }

    public function addEquipementsClientUtilisateur(Equipement $equipementsClientUtilisateur): self
    {
        if (!$this->equipements_client_utilisateur->contains($equipementsClientUtilisateur)) {
            $this->equipements_client_utilisateur[] = $equipementsClientUtilisateur;
            $equipementsClientUtilisateur->setClientUtilisateur($this);
        }

        return $this;
    }

    public function removeEquipementsClientUtilisateur(Equipement $equipementsClientUtilisateur): self
    {
        if ($this->equipements_client_utilisateur->removeElement($equipementsClientUtilisateur)) {
            // set the owning side to null (unless already changed)
            if ($equipementsClientUtilisateur->getClientUtilisateur() === $this) {
                $equipementsClientUtilisateur->setClientUtilisateur(null);
            }
        }

        return $this;
    }

    /**
     * @Ignore()
     * @return Collection<int, Contrat>
     */
    public function getContrats(): Collection
    {
        return $this->contrats;
    }

    public function addContrat(Contrat $contrat): self
    {
        if (!$this->contrats->contains($contrat)) {
            $this->contrats[] = $contrat;
            $contrat->setClient($this);
        }

        return $this;
    }

    public function removeContrat(Contrat $contrat): self
    {
        if ($this->contrats->removeElement($contrat)) {
            // set the owning side to null (unless already changed)
            if ($contrat->getClient() === $this) {
                $contrat->setClient(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, ClientSite>
     */
    public function getClientSites(): Collection
    {
        return $this->clientSites;
    }

    public function getArraySites() {
        return  $this->clientSites->map(function($clientSite) {
            return (string)$clientSite;
        })->toArray();
    }


    public function addClientSite(ClientSite $clientSite): self
    {
        if (!$this->clientSites->contains($clientSite)) {
            $this->clientSites[] = $clientSite;
            $clientSite->setClient($this);
        }

        return $this;
    }

    public function removeClientSite(ClientSite $clientSite): self
    {
        if ($this->clientSites->removeElement($clientSite)) {
            // set the owning side to null (unless already changed)
            if ($clientSite->getClient() === $this) {
                $clientSite->setClient(null);
            }
        }

        return $this;
    }

    public function getNumeroClient()
    {
        return $this->numero_client;
    }

    public function setNumeroClient(?string $numero_client)
    {
        $this->numero_client = $numero_client;

        return $this;
    }

    /**
     * @SerializedName("formatted_numero_client")
     * @Groups({"map"})
     */
    public function getFormattedNumeroClient() {
        $strNumClient = $this->numero_client;
        if ($strNumClient) $strNumClient = str_pad($strNumClient, 9, "0", STR_PAD_LEFT);
        return ($this->numero_client)
            ? substr($strNumClient,0,2) . ' ' . substr($strNumClient,2,2) . ' ' . substr($strNumClient,4,5)
            : '';
    }

    /**
     * @return Collection<int, PorteOuverte>
     */
    public function getPorteOuvertes(): Collection
    {
        return $this->porteOuvertes;
    }

    public function getLastPorteOuverte(): ?PorteOuverte
    {
        $last = null;
        foreach ($this->porteOuvertes as $porteOuverte) {
            if ($porteOuverte->getDernierePo()) return $porteOuverte;
        }
        return $last;
    }


    public function addPorteOuverte(PorteOuverte $porteOuverte): self
    {
        if (!$this->porteOuvertes->contains($porteOuverte)) {
            $this->porteOuvertes[] = $porteOuverte;
            $porteOuverte->setClient($this);
        }

        return $this;
    }

    public function removePorteOuverte(PorteOuverte $porteOuverte): self
    {
        if ($this->porteOuvertes->removeElement($porteOuverte)) {
            // set the owning side to null (unless already changed)
            if ($porteOuverte->getClient() === $this) {
                $porteOuverte->setClient(null);
            }
        }

        return $this;
    }

    public function getMotifModifClientNom()
    {
        return $this->motif_modif_client_nom;
    }

    public function setMotifModifClientNom($motif_modif_client_nom): self
    {
        $this->motif_modif_client_nom = $motif_modif_client_nom;

        return $this;
    }

    public function getMotifModifClientNomSiAutre()
    {
        return $this->motif_modif_client_nom_si_autre;
    }

    public function setMotifModifClientNomSiAutre($motif_modif_client_nom_si_autre): self
    {
        $this->motif_modif_client_nom_si_autre = $motif_modif_client_nom_si_autre;

        return $this;
    }

    public function getMotifModifClientPrenom()
    {
        return $this->motif_modif_client_prenom;
    }

    public function setMotifModifClientPrenom($motif_modif_client_prenom): self
    {
        $this->motif_modif_client_prenom = $motif_modif_client_prenom;

        return $this;
    }

    public function getMotifModifClientPrenomSiAutre()
    {
        return $this->motif_modif_client_prenom_si_autre;
    }

    public function setMotifModifClientPrenomSiAutre($motif_modif_client_prenom_si_autre): self
    {
        $this->motif_modif_client_prenom_si_autre = $motif_modif_client_prenom_si_autre;

        return $this;
    }

    public function getMotifModifClientType()
    {
        return $this->motif_modif_client_type;
    }

    public function setMotifModifClientType($motif_modif_client_type): self
    {
        $this->motif_modif_client_type = $motif_modif_client_type;

        return $this;
    }

    public function getMotifModifClientTypeSiAutre()
    {
        return $this->motif_modif_client_type_si_autre;
    }

    public function setMotifModifClientTypeSiAutre($motif_modif_client_type_si_autre): self
    {
        $this->motif_modif_client_type_si_autre = $motif_modif_client_type_si_autre;

        return $this;
    }

    public function __toString() {
        if ($this->getTypeClient()) {
            if ($this->getTypeClient()->isParticulier()) {
                return $this->getEtatCivil().'. ' . strtoupper($this->getNom()) . ' ' . $this->getPrenom();
            } else {
                return $this->getCategoriePro() . ' ' . $this->getNomEntreprise();
            }
        }
        return '';
    }

    /**
     * @return Collection<int, HistoriqueEquipementUtilisateur>
     */
    public function getHistoriqueEquipementUtilisateurs(): Collection
    {
        return $this->historiqueEquipementUtilisateurs;
    }

    public function addHistoriqueEquipementUtilisateur(HistoriqueEquipementUtilisateur $historiqueEquipementUtilisateur): self
    {
        if (!$this->historiqueEquipementUtilisateurs->contains($historiqueEquipementUtilisateur)) {
            $this->historiqueEquipementUtilisateurs[] = $historiqueEquipementUtilisateur;
            $historiqueEquipementUtilisateur->setUtilisateur($this);
        }

        return $this;
    }

    public function removeHistoriqueEquipementUtilisateur(HistoriqueEquipementUtilisateur $historiqueEquipementUtilisateur): self
    {
        if ($this->historiqueEquipementUtilisateurs->removeElement($historiqueEquipementUtilisateur)) {
            // set the owning side to null (unless already changed)
            if ($historiqueEquipementUtilisateur->getUtilisateur() === $this) {
                $historiqueEquipementUtilisateur->setUtilisateur(null);
            }
        }

        return $this;
    }

    public function getNumSiren(): ?string
    {
        return $this->num_siren;
    }

    public function setNumSiren(?string $num_siren): self
    {
        $this->num_siren = strtoupper($num_siren);

        return $this;
    }

    public function getNumSiret(): ?string
    {
        return $this->num_siret;
    }

    public function setNumSiret(?string $num_siret): self
    {
        $this->num_siret = strtoupper($num_siret);

        return $this;
    }
    public function getNumTvaIntra(): ?string
    {
        return $this->num_tva_intra;
    }

    public function setNumTvaIntra(?string $num_tva_intra): self
    {
        $this->num_tva_intra = strtoupper($num_tva_intra);

        return $this;
    }


    /**
     * @Ignore()
     */
    public function getClientTutelle(): ?Client
    {
        return $this->client_tutelle;
    }

    public function setClientTutelle(?Client $client_tutelle): self
    {
        $this->client_tutelle = $client_tutelle;

        return $this;
    }
}
