<?php
declare (strict_types=1);

namespace App\Entity\Core;

use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\ApiResource;
use App\Entity\Access\Access;
use App\Entity\AccessWish\AccessWish;
use App\Entity\Billing\AbstractBillingIntangible;
use App\Entity\Billing\BillAccounting;
use App\Entity\Billing\BillPayment;
use App\Entity\Booking\Course;
use App\Entity\Booking\EducationalProject;
use App\Entity\Booking\Event;
use App\Entity\Booking\Examen;
use App\Entity\Education\Education;
use App\Entity\Education\EducationNotation;
use App\Entity\Education\EducationStudent;
use App\Entity\Message\Email;
use App\Entity\Message\Mail;
use App\Entity\Message\Sms;
use App\Entity\Organization\Activity;
use App\Entity\Organization\Jury;
use App\Entity\Organization\Organization;
use App\Entity\Person\Commission;
use App\Entity\Place\Place;
use App\Entity\Place\PlaceControl;
use App\Entity\Place\PlaceRepair;
use App\Entity\Product\Equipment;
use App\Entity\Product\EquipmentControl;
use App\Entity\Product\EquipmentLoan;
use App\Entity\Product\EquipmentRepair;
use App\Entity\Product\Intangible;

//use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * Classe ... qui ...
 */
#[ApiResource(
    operations: [
        new Get(
            security: 'is_granted(\'ROLE_ADMIN\') and object.getOrganization().getId() == user.getOrganization().getId()'
        )
    ]
)]
//#[Auditable]
#[ORM\Entity]
class Tagg
{
    #[ORM\Id]
    #[ORM\Column]
    #[ORM\GeneratedValue]
    private ?int $id = null;

    #[ORM\ManyToOne]
    #[ORM\JoinColumn(nullable: false)]
    private Organization $organization;

    #[ORM\ManyToMany(targetEntity: Access::class, mappedBy: 'tags')]
    protected Collection $accesses;

    #[ORM\ManyToMany(targetEntity: Organization::class, mappedBy: 'tags')]
    protected Collection $organizations;

    #[ORM\ManyToMany(targetEntity: BillAccounting::class, mappedBy: 'tags')]
    protected Collection $billAccountings;

    #[ORM\ManyToMany(targetEntity: Equipment::class, mappedBy: 'tags')]
    protected Collection $equipments;

    #[ORM\ManyToMany(targetEntity: Intangible::class, mappedBy: 'tags')]
    protected Collection $intangibles;

    #[ORM\ManyToMany(targetEntity: Course::class, mappedBy: 'tags')]
    protected Collection $courses;

    #[ORM\ManyToMany(targetEntity: Event::class, mappedBy: 'tags')]
    protected Collection $events;

    #[ORM\ManyToMany(targetEntity: EducationalProject::class, mappedBy: 'tags')]
    protected Collection $educationalProjects;

    #[ORM\ManyToMany(targetEntity: Examen::class, mappedBy: 'tags')]
    protected Collection $examens;

    #[ORM\ManyToMany(targetEntity: Activity::class, mappedBy: 'tags')]
    protected Collection $activities;

    #[ORM\ManyToMany(targetEntity: BillPayment::class, mappedBy: 'tags')]
    protected Collection $payments;

    #[ORM\ManyToMany(targetEntity: Commission::class, mappedBy: 'tags')]
    protected Collection $commissions;

    #[ORM\ManyToMany(targetEntity: Education::class, mappedBy: 'tags')]
    protected Collection $educations;

    #[ORM\ManyToMany(targetEntity: EducationNotation::class, mappedBy: 'tags')]
    protected Collection $educationNotations;

    #[ORM\ManyToMany(targetEntity: EducationStudent::class, mappedBy: 'tags')]
    protected Collection $educationStudents;

    #[ORM\ManyToMany(targetEntity: Jury::class, mappedBy: 'tags')]
    protected Collection $juries;

    #[ORM\ManyToMany(targetEntity: PlaceRepair::class, mappedBy: 'tags')]
    protected Collection $placeRepairs;

    #[ORM\ManyToMany(targetEntity: EquipmentRepair::class, mappedBy: 'tags')]
    protected Collection $equipmentRepairs;

    #[ORM\ManyToMany(targetEntity: PlaceControl::class, mappedBy: 'tags')]
    protected Collection $placeControls;

    #[ORM\ManyToMany(targetEntity: EquipmentControl::class, mappedBy: 'tags')]
    protected Collection $equipmentControls;

    #[ORM\ManyToMany(targetEntity: AccessWish::class, mappedBy: 'tags')]
    protected Collection $accessWishes;

    #[ORM\ManyToMany(targetEntity: AbstractBillingIntangible::class, mappedBy: 'tags')]
    protected Collection $billingIntangibles;

    #[ORM\ManyToMany(targetEntity: EquipmentLoan::class, mappedBy: 'tags')]
    protected Collection $equipmentLoans;

    #[ORM\ManyToMany(targetEntity: Place::class, mappedBy: 'tags')]
    protected Collection $places;

    #[ORM\ManyToMany(targetEntity: Email::class, mappedBy: 'tags')]
    protected Collection $emails;

    #[ORM\ManyToMany(targetEntity: Mail::class, mappedBy: 'tags')]
    protected Collection $mails;

    #[ORM\ManyToMany(targetEntity: Sms::class, mappedBy: 'tags')]
    protected Collection $sms;

    public function __construct()
    {
        $this->accesses = new ArrayCollection();
        $this->organizations = new ArrayCollection();
        $this->billAccountings = new ArrayCollection();
        $this->equipments = new ArrayCollection();
        $this->intangibles = new ArrayCollection();
        $this->courses = new ArrayCollection();
        $this->events = new ArrayCollection();
        $this->educationalProjects = new ArrayCollection();
        $this->examens = new ArrayCollection();
        $this->activities = new ArrayCollection();
        $this->payments = new ArrayCollection();
        $this->commissions = new ArrayCollection();
        $this->educations = new ArrayCollection();
        $this->educationNotations = new ArrayCollection();
        $this->educationStudents = new ArrayCollection();
        $this->juries = new ArrayCollection();
        $this->placeRepairs = new ArrayCollection();
        $this->equipmentRepairs = new ArrayCollection();
        $this->placeControls = new ArrayCollection();
        $this->equipmentControls = new ArrayCollection();
        $this->accessWishes = new ArrayCollection();
        $this->billingIntangibles = new ArrayCollection();
        $this->equipmentLoans = new ArrayCollection();
        $this->places = new ArrayCollection();
        $this->emails = new ArrayCollection();
        $this->mails = new ArrayCollection();
        $this->sms = new ArrayCollection();
    }

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

    public function getOrganization(): ?Organization
    {
        return $this->organization;
    }

    public function setOrganization(?Organization $organization): self
    {
        $this->organization = $organization;
        return $this;
    }

    /**
     * @return Collection<int, Access>
     */
    public function getAccesses(): Collection
    {
        return $this->accesses;
    }

    public function addAccess(Access $access): self
    {
        if (!$this->accesses->contains($access)) {
            $this->accesses[] = $access;
            $access->addTag($this);
        }
        return $this;
    }

    public function removeAccess(Access $access): self
    {
        if ($this->accesses->removeElement($access)) {
            $access->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, Organization>
     */
    public function getOrganizations(): Collection
    {
        return $this->organizations;
    }

    public function addOrganization(Organization $organization): self
    {
        if (!$this->organizations->contains($organization)) {
            $this->organizations[] = $organization;
            $organization->addTag($this);
        }
        return $this;
    }

    public function removeOrganization(Organization $organization): self
    {
        if ($this->organizations->removeElement($organization)) {
            $organization->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, BillAccounting>
     */
    public function getBillAccountings(): Collection
    {
        return $this->billAccountings;
    }

    public function addBillAccounting(BillAccounting $billAccounting): self
    {
        if (!$this->billAccountings->contains($billAccounting)) {
            $this->billAccountings[] = $billAccounting;
            $billAccounting->addTag($this);
        }
        return $this;
    }

    public function removeBillAccounting(BillAccounting $billAccounting): self
    {
        if ($this->billAccountings->removeElement($billAccounting)) {
            $billAccounting->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, Equipment>
     */
    public function getEquipments(): Collection
    {
        return $this->equipments;
    }

    public function addEquipment(Equipment $equipment): self
    {
        if (!$this->equipments->contains($equipment)) {
            $this->equipments[] = $equipment;
            $equipment->addTag($this);
        }
        return $this;
    }

    public function removeEquipment(Equipment $equipment): self
    {
        if ($this->equipments->removeElement($equipment)) {
            $equipment->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, Intangible>
     */
    public function getIntangibles(): Collection
    {
        return $this->intangibles;
    }

    public function addIntangible(Intangible $intangible): self
    {
        if (!$this->intangibles->contains($intangible)) {
            $this->intangibles[] = $intangible;
            $intangible->addTag($this);
        }
        return $this;
    }

    public function removeIntangible(Intangible $intangible): self
    {
        if ($this->intangibles->removeElement($intangible)) {
            $intangible->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, Course>
     */
    public function getCourses(): Collection
    {
        return $this->courses;
    }

    public function addCourse(Course $course): self
    {
        if (!$this->courses->contains($course)) {
            $this->courses[] = $course;
            $course->addTag($this);
        }
        return $this;
    }

    public function removeCourse(Course $course): self
    {
        if ($this->courses->removeElement($course)) {
            $course->removeTag($this);
        }
        return $this;
    }

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

    public function addEvent(Event $event): self
    {
        if (!$this->events->contains($event)) {
            $this->events[] = $event;
            $event->addTag($this);
        }
        return $this;
    }

    public function removeEvent(Event $event): self
    {
        if ($this->events->removeElement($event)) {
            $event->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, EducationalProject>
     */
    public function getEducationalProjects(): Collection
    {
        return $this->educationalProjects;
    }

    public function addEducationalProject(EducationalProject $educationalProject): self
    {
        if (!$this->educationalProjects->contains($educationalProject)) {
            $this->educationalProjects[] = $educationalProject;
            $educationalProject->addTag($this);
        }
        return $this;
    }

    public function removeEducationalProject(EducationalProject $educationalProject): self
    {
        if ($this->educationalProjects->removeElement($educationalProject)) {
            $educationalProject->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, Examen>
     */
    public function getExamens(): Collection
    {
        return $this->examens;
    }

    public function addExamen(Examen $examen): self
    {
        if (!$this->examens->contains($examen)) {
            $this->examens[] = $examen;
            $examen->addTag($this);
        }
        return $this;
    }

    public function removeExamen(Examen $examen): self
    {
        if ($this->examens->removeElement($examen)) {
            $examen->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, Activity>
     */
    public function getActivities(): Collection
    {
        return $this->activities;
    }

    public function addActivity(Activity $activity): self
    {
        if (!$this->activities->contains($activity)) {
            $this->activities[] = $activity;
            $activity->addTag($this);
        }
        return $this;
    }

    public function removeActivity(Activity $activity): self
    {
        if ($this->activities->removeElement($activity)) {
            $activity->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, BillPayment>
     */
    public function getPayments(): Collection
    {
        return $this->payments;
    }

    public function addPayment(BillPayment $payment): self
    {
        if (!$this->payments->contains($payment)) {
            $this->payments[] = $payment;
            $payment->addTag($this);
        }
        return $this;
    }

    public function removePayment(BillPayment $payment): self
    {
        if ($this->payments->removeElement($payment)) {
            $payment->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, Commission>
     */
    public function getCommissions(): Collection
    {
        return $this->commissions;
    }

    public function addCommission(Commission $commission): self
    {
        if (!$this->commissions->contains($commission)) {
            $this->commissions[] = $commission;
            $commission->addTag($this);
        }
        return $this;
    }

    public function removeCommission(Commission $commission): self
    {
        if ($this->commissions->removeElement($commission)) {
            $commission->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, Education>
     */
    public function getEducations(): Collection
    {
        return $this->educations;
    }

    public function addEducation(Education $education): self
    {
        if (!$this->educations->contains($education)) {
            $this->educations[] = $education;
            $education->addTag($this);
        }
        return $this;
    }

    public function removeEducation(Education $education): self
    {
        if ($this->educations->removeElement($education)) {
            $education->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, EducationNotation>
     */
    public function getEducationNotations(): Collection
    {
        return $this->educationNotations;
    }

    public function addEducationNotation(EducationNotation $educationNotation): self
    {
        if (!$this->educationNotations->contains($educationNotation)) {
            $this->educationNotations[] = $educationNotation;
            $educationNotation->addTag($this);
        }
        return $this;
    }

    public function removeEducationNotation(EducationNotation $educationNotation): self
    {
        if ($this->educationNotations->removeElement($educationNotation)) {
            $educationNotation->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, EducationStudent>
     */
    public function getEducationStudents(): Collection
    {
        return $this->educationStudents;
    }

    public function addEducationStudent(EducationStudent $educationStudent): self
    {
        if (!$this->educationStudents->contains($educationStudent)) {
            $this->educationStudents[] = $educationStudent;
            $educationStudent->addTag($this);
        }
        return $this;
    }

    public function removeEducationStudent(EducationStudent $educationStudent): self
    {
        if ($this->educationStudents->removeElement($educationStudent)) {
            $educationStudent->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, Jury>
     */
    public function getJuries(): Collection
    {
        return $this->juries;
    }

    public function addJury(Jury $jury): self
    {
        if (!$this->juries->contains($jury)) {
            $this->juries[] = $jury;
            $jury->addTag($this);
        }
        return $this;
    }

    public function removeJury(Jury $jury): self
    {
        if ($this->juries->removeElement($jury)) {
            $jury->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, PlaceRepair>
     */
    public function getPlaceRepairs(): Collection
    {
        return $this->placeRepairs;
    }

    public function addPlaceRepair(PlaceRepair $placeRepair): self
    {
        if (!$this->placeRepairs->contains($placeRepair)) {
            $this->placeRepairs[] = $placeRepair;
            $placeRepair->addTag($this);
        }
        return $this;
    }

    public function removePlaceRepair(PlaceRepair $placeRepair): self
    {
        if ($this->placeRepairs->removeElement($placeRepair)) {
            $placeRepair->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, EquipmentRepair>
     */
    public function getEquipmentRepairs(): Collection
    {
        return $this->equipmentRepairs;
    }

    public function addEquipmentRepair(EquipmentRepair $equipmentRepair): self
    {
        if (!$this->equipmentRepairs->contains($equipmentRepair)) {
            $this->equipmentRepairs[] = $equipmentRepair;
            $equipmentRepair->addTag($this);
        }
        return $this;
    }

    public function removeEquipmentRepair(EquipmentRepair $equipmentRepair): self
    {
        if ($this->equipmentRepairs->removeElement($equipmentRepair)) {
            $equipmentRepair->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, PlaceControl>
     */
    public function getPlaceControls(): Collection
    {
        return $this->placeControls;
    }

    public function addPlaceControl(PlaceControl $placeControl): self
    {
        if (!$this->placeControls->contains($placeControl)) {
            $this->placeControls[] = $placeControl;
            $placeControl->addTag($this);
        }
        return $this;
    }

    public function removePlaceControl(PlaceControl $placeControl): self
    {
        if ($this->placeControls->removeElement($placeControl)) {
            $placeControl->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, EquipmentControl>
     */
    public function getEquipmentControls(): Collection
    {
        return $this->equipmentControls;
    }

    public function addEquipmentControl(EquipmentControl $equipmentControl): self
    {
        if (!$this->equipmentControls->contains($equipmentControl)) {
            $this->equipmentControls[] = $equipmentControl;
            $equipmentControl->addTag($this);
        }
        return $this;
    }

    public function removeEquipmentControl(EquipmentControl $equipmentControl): self
    {
        if ($this->equipmentControls->removeElement($equipmentControl)) {
            $equipmentControl->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, AccessWish>
     */
    public function getAccessWishes(): Collection
    {
        return $this->accessWishes;
    }

    public function addAccessWish(AccessWish $accessWish): self
    {
        if (!$this->accessWishes->contains($accessWish)) {
            $this->accessWishes[] = $accessWish;
            $accessWish->addTag($this);
        }
        return $this;
    }

    public function removeAccessWish(AccessWish $accessWish): self
    {
        if ($this->accessWishes->removeElement($accessWish)) {
            $accessWish->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, AbstractBillingIntangible>
     */
    public function getBillingIntangibles(): Collection
    {
        return $this->billingIntangibles;
    }

    public function addBillingIntangible(AbstractBillingIntangible $billingIntangible): self
    {
        if (!$this->billingIntangibles->contains($billingIntangible)) {
            $this->billingIntangibles[] = $billingIntangible;
            $billingIntangible->addTag($this);
        }
        return $this;
    }

    public function removeBillingIntangible(AbstractBillingIntangible $billingIntangible): self
    {
        if ($this->billingIntangibles->removeElement($billingIntangible)) {
            $billingIntangible->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, EquipmentLoan>
     */
    public function getEquipmentLoans(): Collection
    {
        return $this->equipmentLoans;
    }

    public function addEquipmentLoan(EquipmentLoan $equipmentLoan): self
    {
        if (!$this->equipmentLoans->contains($equipmentLoan)) {
            $this->equipmentLoans[] = $equipmentLoan;
            $equipmentLoan->addTag($this);
        }
        return $this;
    }

    public function removeEquipmentLoan(EquipmentLoan $equipmentLoan): self
    {
        if ($this->equipmentLoans->removeElement($equipmentLoan)) {
            $equipmentLoan->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, Place>
     */
    public function getPlaces(): Collection
    {
        return $this->places;
    }

    public function addPlace(Place $place): self
    {
        if (!$this->places->contains($place)) {
            $this->places[] = $place;
            $place->addTag($this);
        }
        return $this;
    }

    public function removePlace(Place $place): self
    {
        if ($this->places->removeElement($place)) {
            $place->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, Email>
     */
    public function getEmails(): Collection
    {
        return $this->emails;
    }

    public function addEmail(Email $email): self
    {
        if (!$this->emails->contains($email)) {
            $this->emails[] = $email;
            $email->addTag($this);
        }
        return $this;
    }

    public function removeEmail(Email $email): self
    {
        if ($this->emails->removeElement($email)) {
            $email->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, Mail>
     */
    public function getMails(): Collection
    {
        return $this->mails;
    }

    public function addMail(Mail $mail): self
    {
        if (!$this->mails->contains($mail)) {
            $this->mails[] = $mail;
            $mail->addTag($this);
        }
        return $this;
    }

    public function removeMail(Mail $mail): self
    {
        if ($this->mails->removeElement($mail)) {
            $mail->removeTag($this);
        }
        return $this;
    }

    /**
     * @return Collection<int, Sms>
     */
    public function getSms(): Collection
    {
        return $this->sms;
    }

    public function addSms(Sms $sms): self
    {
        if (!$this->sms->contains($sms)) {
            $this->sms[] = $sms;
            $sms->addTag($this);
        }
        return $this;
    }

    public function removeSms(Sms $sms): self
    {
        if ($this->sms->removeElement($sms)) {
            $sms->removeTag($this);
        }
        return $this;
    }
}