<?php

declare(strict_types=1);

namespace App\Entity\Education;

use ApiPlatform\Metadata\ApiResource;
use App\Entity\AccessWish\EducationStudentWish;
use App\Entity\Booking\Course;
use App\Entity\Booking\Examen;
use App\Entity\Product\Intangible;
use App\Repository\Education\EducationCurriculumRepository;
// use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * Curriculum éducatif; composé d'un cycle, d'une année et d'un niveau.
 */
#[ApiResource(operations: [])]
// #[Auditable]
#[ORM\Entity(repositoryClass: EducationCurriculumRepository::class)]
class EducationCurriculum
{
    #[ORM\Id]
    #[ORM\Column]
    #[ORM\GeneratedValue]
    private ?int $id = null;

    #[ORM\ManyToOne(targetEntity: EducationNotationConfig::class, inversedBy: 'educationCurriculums')]
    #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
    private ?EducationNotationConfig $educationNotationConfig;

    #[ORM\ManyToOne(targetEntity: Education::class, inversedBy: 'educationCurriculums')]
    private ?Education $education = null;

    #[ORM\ManyToOne(targetEntity: Cycle::class, inversedBy: 'educationCurriculums')]
    private ?Cycle $cycle = null;

    /** @var Collection<int, EducationStudent> */
    #[ORM\OneToMany(targetEntity: EducationStudent::class, mappedBy: 'educationCurriculum', cascade: ['persist'])]
    private Collection $educationStudent;

    /** @var Collection<int, EducationTiming> */
    #[ORM\ManyToMany(targetEntity: EducationTiming::class, inversedBy: 'educationCurriculums')]
    #[ORM\JoinColumn(name: 'educationCurriculum_id', referencedColumnName: 'id')]
    #[ORM\InverseJoinColumn(name: 'educationTiming_id', referencedColumnName: 'id')]
    private Collection $educationTimings;

    /** @var Collection<int, EducationStudentWish> */
    #[ORM\OneToMany(targetEntity: EducationStudentWish::class, mappedBy: 'educationCurriculum', cascade: [], orphanRemoval: false)]
    protected Collection $educationStudentWish;

    /** @var Collection<int, Course> */
    #[ORM\ManyToMany(targetEntity: Course::class, mappedBy: 'educationCurriculum', cascade: ['persist'])]
    protected Collection $courses;

    /** @var Collection<int, Examen> */
    #[ORM\ManyToMany(targetEntity: Examen::class, mappedBy: 'educationCurriculum', cascade: ['persist'])]
    protected Collection $examens;

    /** @var Collection<int, Intangible> */
    #[ORM\ManyToMany(targetEntity: Intangible::class, mappedBy: 'educationCurriculums', cascade: ['persist'], orphanRemoval: false)]
    protected Collection $intangibles;

    /** @var Collection<int, EducationCurriculumPack> */
    #[ORM\ManyToMany(
        targetEntity: EducationCurriculumPack::class,
        mappedBy: 'requiredEducationCurriculums',
        cascade: [],
        orphanRemoval: true,
    )]
    protected Collection $requiredEducationCurriculumPacks;

    /** @var Collection<int, RequiredChoicesBlock> */
    #[ORM\ManyToMany(
        targetEntity: RequiredChoicesBlock::class,
        mappedBy: 'requiredChoicesEducationCurriculums',
        cascade: [],
        orphanRemoval: true,
    )]
    protected Collection $requiredChoicesEducationCurriculumPacks;

    /** @var Collection<int, EducationCurriculumPack> */
    #[ORM\ManyToMany(
        targetEntity: EducationCurriculumPack::class,
        mappedBy: 'optionnalEducationCurriculums',
        cascade: [],
        orphanRemoval: true,
    )]
    protected Collection $optionnalEducationCurriculumPacks;

    public function __construct()
    {
        $this->educationStudent = new ArrayCollection();
        $this->educationTimings = new ArrayCollection();
        $this->educationStudentWish = new ArrayCollection();
        $this->courses = new ArrayCollection();
        $this->examens = new ArrayCollection();
        $this->intangibles = new ArrayCollection();
        $this->requiredEducationCurriculumPacks = new ArrayCollection();
        $this->requiredChoicesEducationCurriculumPacks = new ArrayCollection();
        $this->optionnalEducationCurriculumPacks = new ArrayCollection();
    }

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

    public function setEducationNotationConfig(?EducationNotationConfig $educationNotationConfig): self
    {
        $this->educationNotationConfig = $educationNotationConfig;

        return $this;
    }

    public function getEducationNotationConfig(): ?EducationNotationConfig
    {
        return $this->educationNotationConfig;
    }

    public function getEducation(): ?Education
    {
        return $this->education;
    }

    public function setEducation(?Education $education): self
    {
        $this->education = $education;

        return $this;
    }

    public function getCycle(): ?Cycle
    {
        return $this->cycle;
    }

    public function setCycle(?Cycle $cycle): self
    {
        $this->cycle = $cycle;

        return $this;
    }

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

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

        return $this;
    }

    public function removeEducationStudent(EducationStudent $educationStudent): self
    {
        if ($this->educationStudent->removeElement($educationStudent)) {
            // set the owning side to null (unless already changed)
            if ($educationStudent->getEducationCurriculum() === $this) {
                $educationStudent->setEducationCurriculum(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, EducationTiming>
     */
    public function getEducationTimings(): Collection
    {
        return $this->educationTimings;
    }

    public function addEducationTiming(EducationTiming $educationTiming): self
    {
        if (!$this->educationTimings->contains($educationTiming)) {
            $this->educationTimings[] = $educationTiming;
        }

        return $this;
    }

    public function removeEducationTiming(EducationTiming $educationTiming): self
    {
        $this->educationTimings->removeElement($educationTiming);

        return $this;
    }

    public function getEducationStudentWish(): Collection
    {
        return $this->educationStudentWish;
    }

    public function addEducationStudentWish(EducationStudentWish $educationStudentWish): self
    {
        if (!$this->educationStudentWish->contains($educationStudentWish)) {
            $this->educationStudentWish[] = $educationStudentWish;
            $educationStudentWish->setEducationCurriculum($this);
        }

        return $this;
    }

    public function removeEducationStudentWish(EducationStudentWish $educationStudentWish): self
    {
        if ($this->educationStudentWish->removeElement($educationStudentWish)) {
            $educationStudentWish->setEducationCurriculum(null);
        }

        return $this;
    }

    public function getCourses(): Collection
    {
        return $this->courses;
    }

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

        return $this;
    }

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

        return $this;
    }

    public function getExamens(): Collection
    {
        return $this->examens;
    }

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

        return $this;
    }

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

        return $this;
    }

    public function getIntangibles(): Collection
    {
        return $this->intangibles;
    }

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

        return $this;
    }

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

        return $this;
    }

    public function getRequiredEducationCurriculumPacks(): Collection
    {
        return $this->requiredEducationCurriculumPacks;
    }

    public function addRequiredEducationCurriculumPack(EducationCurriculumPack $requiredEducationCurriculumPack): self
    {
        if (!$this->requiredEducationCurriculumPacks->contains($requiredEducationCurriculumPack)) {
            $this->requiredEducationCurriculumPacks[] = $requiredEducationCurriculumPack;
            $requiredEducationCurriculumPack->addRequiredEducationCurriculum($this);
        }

        return $this;
    }

    public function removeRequiredEducationCurriculumPack(EducationCurriculumPack $requiredEducationCurriculumPack): self
    {
        if ($this->requiredEducationCurriculumPacks->removeElement($requiredEducationCurriculumPack)) {
            $requiredEducationCurriculumPack->removeRequiredEducationCurriculum($this);
        }

        return $this;
    }

    public function getRequiredChoicesEducationCurriculumPacks(): Collection
    {
        return $this->requiredChoicesEducationCurriculumPacks;
    }

    public function addRequiredChoicesEducationCurriculumPack(
        RequiredChoicesBlock $requiredChoicesEducationCurriculumPack,
    ): self {
        if (!$this->requiredChoicesEducationCurriculumPacks->contains($requiredChoicesEducationCurriculumPack)) {
            $this->requiredChoicesEducationCurriculumPacks[] = $requiredChoicesEducationCurriculumPack;
            $requiredChoicesEducationCurriculumPack->addRequiredChoicesEducationCurriculum($this);
        }

        return $this;
    }

    public function removeRequiredChoicesEducationCurriculumPack(
        RequiredChoicesBlock $requiredChoicesEducationCurriculumPack,
    ): self {
        if ($this->requiredChoicesEducationCurriculumPacks->removeElement($requiredChoicesEducationCurriculumPack)) {
            $requiredChoicesEducationCurriculumPack->removeRequiredChoicesEducationCurriculum($this);
        }

        return $this;
    }

    public function getOptionnalEducationCurriculumPacks(): Collection
    {
        return $this->optionnalEducationCurriculumPacks;
    }

    public function addOptionnalEducationCurriculumPack(EducationCurriculumPack $optionnalEducationCurriculumPack): self
    {
        if (!$this->optionnalEducationCurriculumPacks->contains($optionnalEducationCurriculumPack)) {
            $this->optionnalEducationCurriculumPacks[] = $optionnalEducationCurriculumPack;
            $optionnalEducationCurriculumPack->addOptionnalEducationCurriculum($this);
        }

        return $this;
    }

    public function removeOptionnalEducationCurriculumPack(EducationCurriculumPack $optionnalEducationCurriculumPack): self
    {
        if ($this->optionnalEducationCurriculumPacks->removeElement($optionnalEducationCurriculumPack)) {
            $optionnalEducationCurriculumPack->removeOptionnalEducationCurriculum($this);
        }

        return $this;
    }
}
