<?php

namespace App\Entity;

use App\Repository\GamemasterRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\DBAL\Types\Types;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Uid\Uuid;
use Misd\PhoneNumberBundle\Validator\Constraints as MisdAssert;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity(repositoryClass: GamemasterRepository::class)]
#[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_EMAIL', fields: ['email'])]
#[UniqueEntity(fields: ['email'], message: 'There is already an gamemaster with this email')]
class Gamemaster
{
    #[ORM\Id]
    #[ORM\Column(type: UuidType::NAME, unique: true)]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
    private ?Uuid $id = null;

    #[Assert\Email]
    #[ORM\Column(length: 180)]
    private ?string $email = null;   

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

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

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

    #[ORM\Column(type: Types::TEXT, nullable: true)]
    private ?string $description = null;

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

    /**
     * @var Collection<int, Game>
     */
    #[ORM\ManyToMany(targetEntity: Game::class, inversedBy: 'gamemasters')]
    #[JoinTable(name: 'mastery_gamemaster_game')]
    private Collection $gamesCanMaster;

    #[ORM\OneToOne(inversedBy: 'linkToGamemaster')]
    private ?User $linkToUser = null;

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

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

    /**
     * @var Collection<int, Event>
     */
    #[ORM\ManyToMany(targetEntity: Event::class, mappedBy: 'gamemastersAssigned')]
    private Collection $eventsAssignedTo;

    /**
     * @var Collection<int, Party>
     */
    #[ORM\OneToMany(targetEntity: Party::class, mappedBy: 'gamemaster')]
    private Collection $parties;

    /**
     * @var Collection<int, Availability>
     */
    #[ORM\OneToMany(targetEntity: Availability::class, mappedBy: 'gamemaster', orphanRemoval: true)]
    private Collection $availabilities;

    #[ORM\Column(nullable: true)]
    private ?bool $isAuthor = null;

    /**
     * @var Collection<int, Game>
     */
    #[ORM\ManyToMany(targetEntity: Game::class, inversedBy: 'authors')]
    #[ORM\JoinTable(name: 'author_game')]
    private Collection $authorOfGames;

    public function __construct()
    {
        $this->gamesCanMaster = new ArrayCollection();
        $this->eventsAssignedTo = new ArrayCollection();
        $this->parties = new ArrayCollection();
        $this->availabilities = new ArrayCollection();
        $this->authorOfGames = new ArrayCollection();
    }

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

    public function setId(Uuid $id): static
    {
        $this->id = $id;

        return $this;
    }

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

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

        return $this;
    }
    /**
     * Getter / Setter pour prénom
     */
    public function getFirstName(): ?string
    {
        return $this->firstName;
    }

    public function setFirstName(string $firstName): static
    {
        $this->firstName = $firstName;

        return $this;
    }

    /**
     * Getter / Setter pour nom
     */
    public function getLastName(): ?string
    {
        return $this->lastName;
    }

    public function setLastName(string $lastName): static
    {
        $this->lastName = $lastName;

        return $this;
    }

    public function getPreferedName(): ?string
    {
        return $this->preferedName;
    }

    public function setPreferedName(string $preferedName): static
    {
        $this->preferedName = $preferedName;

        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(?string $description): static
    {
        $this->description = $description;

        return $this;
    }

    public function getFullName(): ?string
    {
        $fullName = $this->firstName . " " . $this->lastName; 
        return $fullName;
    }

    /**
     * Getter / Setter pour numéro de téléphone
     */
    public function getPhone(): ?string
    {
        return $this->phone;
    }

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

        return $this;
    }


    /**
     * @return Collection<int, Game>
     */
    public function getGamesCanMaster(): Collection
    {
        return $this->gamesCanMaster;
    }

    public function addGamesCanMaster(Game $gamesCanMaster): static
    {
        if (!$this->gamesCanMaster->contains($gamesCanMaster)) {
            $this->gamesCanMaster->add($gamesCanMaster);
        }

        return $this;
    }

    public function removeGamesCanMaster(Game $gamesCanMaster): static
    {
        $this->gamesCanMaster->removeElement($gamesCanMaster);

        return $this;
    }

    public function getLinkToUser(): ?User
    {
        return $this->linkToUser;
    }

    public function setLinkToUser(?User $linkToUser): static
    {
        $this->linkToUser = $linkToUser;

        return $this;
    }

    public function getPicture(): ?string
    {
        return $this->picture;
    }

    public function setPicture(?string $picture): static
    {
        $this->picture = $picture;

        return $this;
    }

    public function getSlug(): ?string
    {
        return $this->slug;
    }

    public function setSlug(?string $slug): static
    {
        $this->slug = $slug;

        return $this;
    }

    /**
     * @return Collection<int, Event>
     */
    public function getEventsAssignedTo(): Collection
    {
        return $this->eventsAssignedTo;
    }

    public function addEventsAssignedTo(Event $eventsAssignedTo): static
    {
        if (!$this->eventsAssignedTo->contains($eventsAssignedTo)) {
            $this->eventsAssignedTo->add($eventsAssignedTo);
            $eventsAssignedTo->addGamemastersAssigned($this);
        }

        return $this;
    }

    public function removeEventsAssignedTo(Event $eventsAssignedTo): static
    {
        if ($this->eventsAssignedTo->removeElement($eventsAssignedTo)) {
            $eventsAssignedTo->removeGamemastersAssigned($this);
        }

        return $this;
    }

    /**
     * @return Collection<int, Party>
     */
    public function getParties(): Collection
    {
        return $this->parties;
    }

    public function addParty(Party $party): static
    {
        if (!$this->parties->contains($party)) {
            $this->parties->add($party);
            $party->setGamemaster($this);
        }

        return $this;
    }

    public function removeParty(Party $party): static
    {
        if ($this->parties->removeElement($party)) {
            // set the owning side to null (unless already changed)
            if ($party->getGamemaster() === $this) {
                $party->setGamemaster(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Availability>
     */
    public function getAvailabilities(): Collection
    {
        return $this->availabilities;
    }

    public function addAvailability(Availability $availability): static
    {
        if (!$this->availabilities->contains($availability)) {
            $this->availabilities->add($availability);
            $availability->setGamemaster($this);
        }

        return $this;
    }

    public function removeAvailability(Availability $availability): static
    {
        if ($this->availabilities->removeElement($availability)) {
            // set the owning side to null (unless already changed)
            if ($availability->getGamemaster() === $this) {
                $availability->setGamemaster(null);
            }
        }

        return $this;
    }

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

    public function setIsAuthor(?bool $isAuthor): static
    {
        $this->isAuthor = $isAuthor;

        return $this;
    }

    /**
     * @return Collection<int, Game>
     */
    public function getAuthorOfGames(): Collection
    {
        return $this->authorOfGames;
    }

    public function addAuthorOfGame(Game $authorOfGame): static
    {
        if (!$this->authorOfGames->contains($authorOfGame)) {
            $this->authorOfGames->add($authorOfGame);
        }

        return $this;
    }

    public function removeAuthorOfGame(Game $authorOfGame): static
    {
        $this->authorOfGames->removeElement($authorOfGame);

        return $this;
    }


}
