<?php

namespace Mobile\Device\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Mobile\Project\Entity\DesktopUser;
use Shared\Authentication\Entity\IdentifiedEntity;
use Shared\Utils\ArrayCollectionUtils;

/**
 * @ORM\Entity(repositoryClass="Mobile\Device\Repository\ProtocolRepository")
 *
 * @ORM\Table(name="protocol", schema="adonis")
 */
class Protocol extends IdentifiedEntity
{
    public const DEFAULT_PREFIX_FROM_CSV = 'p-';
    public const DEFAULT_AIM_FROM_CSV = '';
    public const DEFAULT_ALGORITHM_FROM_CSV = 'Sans Tirage';

    /**
     * @ORM\OneToOne(targetEntity="Mobile\Device\Entity\Device", inversedBy="protocol")
     *
     * @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
     */
    private Device $device;

    /**
     * @ORM\Column(type="string", nullable=false)
     */
    private string $name = '';

    /**
     * @ORM\Column(type="string", nullable=false)
     */
    private string $aim = '';

    /**
     * @ORM\Column(type="string", nullable=false)
     */
    private string $algorithm = '';

    /**
     * @var Collection<int, Factor>
     *
     * @ORM\OneToMany(targetEntity="Mobile\Device\Entity\Factor", mappedBy="protocol", cascade={"persist", "remove", "detach"})
     */
    private Collection $factors;

    /**
     * @var Collection<int, Treatment>
     *
     * @ORM\OneToMany(targetEntity="Mobile\Device\Entity\Treatment", mappedBy="protocol", cascade={"persist", "remove", "detach"})
     */
    private Collection $treatments;

    /**
     * @ORM\Column(type="datetime", nullable=false)
     */
    private \DateTime $creationDate;

    /**
     * @ORM\Column(type="integer", nullable=true, options={"default": null})
     */
    private ?int $nbIndividualsPerParcel = null;

    /**
     * @ORM\ManyToOne(targetEntity="Mobile\Project\Entity\DesktopUser")
     *
     * @ORM\JoinColumn(nullable=true)
     */
    private ?DesktopUser $creator = null;

    public function __construct()
    {
        $this->factors = new ArrayCollection();
        $this->treatments = new ArrayCollection();
        $this->creationDate = new \DateTime();
    }

    /**
     * @psalm-mutation-free
     */
    public function getDevice(): Device
    {
        return $this->device;
    }

    /**
     * @return $this
     */
    public function setDevice(Device $device): self
    {
        $this->device = $device;

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * @return $this
     */
    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getAim(): string
    {
        return $this->aim;
    }

    /**
     * @return $this
     */
    public function setAim(string $aim): self
    {
        $this->aim = $aim;

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getAlgorithm(): string
    {
        return $this->algorithm;
    }

    /**
     * @return $this
     */
    public function setAlgorithm(string $algorithm): self
    {
        $this->algorithm = $algorithm;

        return $this;
    }

    /**
     * @return Collection<int,  Factor>
     *
     * @psalm-mutation-free
     */
    public function getFactors(): Collection
    {
        return $this->factors;
    }

    /**
     * @param iterable<int, Factor> $factors
     *
     * @return $this
     */
    public function setFactors(iterable $factors): self
    {
        ArrayCollectionUtils::update($this->factors, $factors, function (Factor $factor) {
            $factor->setProtocol($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addFactor(Factor $factor): self
    {
        if (!$this->factors->contains($factor)) {
            $factor->setProtocol($this);
            $this->factors->add($factor);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removeFactor(Factor $factor): self
    {
        if ($this->factors->contains($factor)) {
            $this->factors->removeElement($factor);
        }

        return $this;
    }

    /**
     * @return Collection<int,  Treatment>
     *
     * @psalm-mutation-free
     */
    public function getTreatments(): Collection
    {
        return $this->treatments;
    }

    /**
     * @param iterable<int, Treatment> $treatments
     *
     * @return $this
     */
    public function setTreatments(iterable $treatments): self
    {
        ArrayCollectionUtils::update($this->treatments, $treatments, function (Treatment $treatment) {
            $treatment->setProtocol($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addTreatment(Treatment $treatment): self
    {
        if (!$this->treatments->contains($treatment)) {
            $treatment->setProtocol($this);
            $this->treatments->add($treatment);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removeTreatment(Treatment $treatment): self
    {
        if ($this->treatments->contains($treatment)) {
            $this->treatments->removeElement($treatment);
        }

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getCreationDate(): \DateTime
    {
        return $this->creationDate;
    }

    /**
     * @return $this
     */
    public function setCreationDate(\DateTime $creationDate): self
    {
        $this->creationDate = $creationDate;

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getNbIndividualsPerParcel(): ?int
    {
        return $this->nbIndividualsPerParcel;
    }

    /**
     * @return $this
     */
    public function setNbIndividualsPerParcel(?int $nbIndividualsPerParcel): self
    {
        $this->nbIndividualsPerParcel = $nbIndividualsPerParcel;

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getCreator(): ?DesktopUser
    {
        return $this->creator;
    }

    /**
     * @return $this
     */
    public function setCreator(?DesktopUser $creator): self
    {
        $this->creator = $creator;

        return $this;
    }
}
