<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use App\Entity\EntityTrait\ContactEmailTelTrait;
use App\Entity\EntityTrait\EnablableEntityTrait;
use App\Entity\EntityTrait\GeolocEntityTrait;
use App\Entity\EntityTrait\NameSlugContentEntityTrait;
use App\Enum\GroupePrestaEnum;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Timestampable\Traits\TimestampableEntity;
use Ramsey\Uuid\Doctrine\UuidGenerator;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ApiResource(
 *     attributes={"security"="is_granted('ROLE_ADMIN_PRESTATAIRE_GERER_VIEW') or is_granted('ROLE_API')"},
 *     collectionOperations={
 *         "get"={"security"="is_granted('ROLE_ADMIN_PRESTATAIRE_GERER_LIST') or is_granted('ROLE_API')"},
 *         "post"={"security"="is_granted('ROLE_ADMIN_PRESTATAIRE_GERER_EDIT')"}
 *     },
 *     itemOperations={
 *         "get"={"security"="is_granted('ROLE_ADMIN_PRESTATAIRE_GERER_VIEW') or is_granted('ROLE_API')"},
 *         "put"={"security"="is_granted('ROLE_ADMIN_PRESTATAIRE_GERER_EDIT')"},
 *     },
 *     normalizationContext={"groups"={"read"}},
 *     denormalizationContext={"groups"={"write"}}
 * )
 * @ORM\Entity(repositoryClass="App\Repository\GroupeprestataireRepository")
 * @UniqueEntity(
 *     fields={"name", "type"},
 *     errorPath="name",
 *     message="Le groupe avec ce nom existe déjà pour ce type de groupe."
 * )
 * @ORM\Table(name="groupeprestaire")
 */
class Groupeprestataire
{
    use NameSlugContentEntityTrait;
    use TimestampableEntity;
    use GeolocEntityTrait;
    use ContactEmailTelTrait;
    use EnablableEntityTrait;

    /**
     * @var \Ramsey\Uuid\UuidInterface
     *
     * @ORM\Id
     * @ORM\Column(type="uuid", unique=true)
     * @ORM\GeneratedValue(strategy="CUSTOM")
     * @ORM\CustomIdGenerator(class=UuidGenerator::class)
     */
    protected $id;

    /**
     * @var string
     *
     * @ORM\Column(name="idmlc", type="string", length=100, nullable=true)
     * @Groups({"read", "write"})
     */
    protected $idmlc;

    /**
     * @var string|null
     *
     * @ORM\Column(length=50)
     * @Assert\NotBlank
     * @Assert\Length(max=50)
     */
    protected $type;

    /**
     * @var ArrayCollection|Prestataire[]
     *
     * @ORM\ManyToMany(targetEntity="Prestataire", inversedBy="groupeprestataires", cascade={"persist"})
     */
    protected $prestataires;

    /**
     * @var Groupe
     *
     * @ORM\ManyToOne(targetEntity="Groupe", inversedBy="groupeprestataires")
     */
    private $groupe;

    /**
     * @var string|null (champ libre)
     *
     * @ORM\Column(name="horaires", type="text", nullable=true)
     */
    private $horaires;

    /**
     * @var \Application\Sonata\MediaBundle\Entity\Media
     * @ORM\ManyToOne(targetEntity="App\Application\Sonata\MediaBundle\Entity\Media", cascade={"persist"}, fetch="LAZY")
     * @ORM\JoinColumn(name="media_id", referencedColumnName="id")
     */
    protected $image;

    public function __construct()
    {
        $this->prestataires = new ArrayCollection();
    }

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

    /**
     * Get idmlc.
     *
     * @return
     */
    public function getIdmlc(): ?string
    {
        return $this->idmlc;
    }

    /**
     * Set idmlc.
     *
     * @return $this
     */
    public function setIdmlc(string $idmlc): self
    {
        $this->idmlc = $idmlc;

        return $this;
    }

    /**
     * Get type.
     *
     * @return string
     */
    public function getType()
    {
        return $this->type;
    }

    /**
     * Set type.
     *
     * @return $this
     */
    public function setType($type)
    {
        if (!in_array($type, GroupePrestaEnum::getAvailableTypes())) {
            throw new \InvalidArgumentException('Type de groupe invalide [amap, marche] !');
        }
        $this->type = $type;

        return $this;
    }

    /**
     * Get horaires.
     *
     * @return string Horaires
     */
    public function getHoraires(): ?string
    {
        return $this->horaires;
    }

    /**
     * Set horaires.
     *
     * @return $this
     */
    public function setHoraires(?string $horaires): self
    {
        $this->horaires = $horaires;

        return $this;
    }

    /**
     * @return Prestataire[]|ArrayCollection
     */
    public function getPrestataires()
    {
        return $this->prestataires;
    }

    /**
     * @param Prestataire $prestataire
     *
     * @return $this
     */
    public function addPrestataire(Prestataire $prestataire): self
    {
        if (!$this->prestataires->contains($prestataire)) {
            $this->prestataires[] = $prestataire;
            $prestataire->addGroupeprestataire($this);
        }

        return $this;
    }

    /**
     * @param Prestataire $prestataire
     *
     * @return $this
     */
    public function removePrestataire(Prestataire $prestataire): self
    {
        if ($this->prestataires->contains($prestataire)) {
            $this->prestataires->removeElement($prestataire);
            $prestataire->removeGroupeprestataire($this);
        }

        return $this;
    }

    /**
     * @param Groupe|null $groupes
     *
     * @return $this
     */
    public function setGroupe(?Groupe $groupe)
    {
        $this->groupe = $groupe;

        return $this;
    }

    /**
     * @return Groupe|null
     */
    public function getGroupe(): ?Groupe
    {
        return $this->groupe;
    }

    /**
     * Get image.
     *
     * @return image|null
     */
    public function getImage()
    {
        return $this->image;
    }

    /**
     * Set image.
     *
     * @return $this
     */
    public function setImage($image)
    {
        $this->image = $image;

        return $this;
    }

    public function getPrestatairesCount()
    {
        return $this->getPrestataires()->count();
    }

    public function __toString(): string
    {
        $return = $this->getName() ? $this->getName() : 'GroupePrestataire';
        if (null != $this->type) {
            $return .= ' (' . strtoupper($this->type) . ')';
        }

        return $return;
    }
}
