<?php

/*
 * @author TRYDEA - 2024
 */

namespace Webapp\Core\Entity;

use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\SoftDeleteable\Traits\SoftDeleteableEntity;
use Shared\Authentication\Entity\IdentifiedEntity;
use Shared\Utils\ArrayCollectionUtils;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Webapp\Core\Validator\UniqueAttributeInParent;

/**
 * @ApiResource(
 *     collectionOperations={
 *         "get"={}
 *     },
 *     itemOperations={
 *          "get"={},
 *          "patch"={"denormalization_context"={"groups"={"edit"}}}
 *     }
 * )
 *
 * @ApiFilter(SearchFilter::class, properties={"factor": "exact", "treatments": "exact"})
 *
 * @Gedmo\SoftDeleteable()
 *
 * @ORM\Entity
 *
 * @ORM\Table(name="modality", schema="webapp")
 */
class Modality extends IdentifiedEntity
{
    use OpenSilexEntity;
    use SoftDeleteableEntity;

    /**
     * @Assert\NotBlank
     *
     * @UniqueAttributeInParent(parentsAttributes={"factor.modalities"})
     *
     * @ORM\Column(type="string")
     *
     * @Groups({"factor_post", "design_explorer_view", "platform_full_view", "webapp_data_view", "edit", "protocol_synthesis", "protocol_full_view", "data_view_item"})
     */
    private string $value = '';

    /**
     * @ORM\Column(type="string", nullable=true)
     *
     * @Groups({"factor_post","design_explorer_view", "platform_full_view", "webapp_data_view", "edit", "protocol_synthesis", "protocol_full_view", "data_view_item"})
     */
    private ?string $shortName = null;

    /**
     * @ORM\Column(type="string", nullable=true)
     *
     * @Groups({"factor_post", "platform_full_view", "edit", "protocol_full_view"})
     */
    private ?string $identifier = null;

    /**
     * @ORM\ManyToOne(targetEntity="Webapp\Core\Entity\Factor", inversedBy="modalities")
     *
     * @ORM\JoinColumn(nullable=false)
     *
     * @Groups({"webapp_data_view", "data_view_item"})
     */
    private Factor $factor;

    /**
     * @var Collection<int, Treatment>
     *
     * @ORM\ManyToMany(targetEntity="Webapp\Core\Entity\Treatment", mappedBy="modalities", cascade={"remove"})
     *
     * @ORM\JoinTable(name="rel_treatment_modality", schema="webapp")
     */
    private Collection $treatments;

    public function __construct()
    {
        $this->openSilexInstance = null;
        $this->openSilexUri = null;
        $this->treatments = new ArrayCollection();
    }

    /**
     * @Groups({"platform_full_view"})
     *
     * @psalm-mutation-free
     */
    public function getId(): ?int
    {
        return parent::getId();
    }

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

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

        return $this;
    }

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

    /**
     * @return $this
     */
    public function setShortName(?string $shortName): self
    {
        $this->shortName = $shortName;

        return $this;
    }

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

    /**
     * @return $this
     */
    public function setIdentifier(?string $identifier): self
    {
        $this->identifier = $identifier;

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getFactor(): Factor
    {
        return $this->factor;
    }

    /**
     * @return $this
     */
    public function setFactor(Factor $factor): self
    {
        $this->factor = $factor;

        return $this;
    }

    /**
     * @return Collection<int,  Treatment>
     */
    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);

        return $this;
    }
}
