<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\JobBundle\Entity;

use Doctrine\Common\Collections\Order;
use Doctrine\ORM\Mapping as ORM;
use Chill\PersonBundle\Entity\Person;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * CV.
 */
#[ORM\Table(name: 'chill_job.cv')]
#[ORM\Entity(repositoryClass: \Chill\JobBundle\Repository\CVRepository::class)]
class CV implements \Stringable
{
    #[ORM\Column(name: 'id', type: \Doctrine\DBAL\Types\Types::INTEGER)]
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'AUTO')]
    private ?int $id = null;

    /**
     * @Assert\NotNull()
     */
    #[ORM\Column(name: 'reportDate', type: \Doctrine\DBAL\Types\Types::DATE_MUTABLE)]
    private ?\DateTimeInterface $reportDate = null;

    public const FORMATION_LEVEL = [
        'sans_diplome',
        'BEP_CAP',
        'BAC',
        'BAC+2',
        'BAC+3',
        'BAC+4',
        'BAC+5',
        'BAC+8',
    ];

    /**
     * @Assert\NotBlank()
     */
    #[ORM\Column(name: 'formationLevel', type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)]
    private ?string $formationLevel = null;

    public const FORMATION_TYPE = [
        'formation_initiale',
        'formation_continue',
    ];

    #[ORM\Column(name: 'formationType', type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)]
    private ?string $formationType = null;

    /**
     * @var string[]|null
     */
    #[ORM\Column(name: 'spokenLanguages', type: \Doctrine\DBAL\Types\Types::JSON, nullable: true)]
    private $spokenLanguages;

    #[ORM\Column(name: 'notes', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
    private ?string $notes = null;

    /**
     * @Assert\Valid(traverse=true)
     *
     * @var Collection<int, CV\Formation>
     */
    #[ORM\OneToMany(targetEntity: CV\Formation::class, mappedBy: 'CV', cascade: ['persist', 'remove', 'detach'], orphanRemoval: true)]
    //    #[ORM\OrderBy(['startDate' => Order::Descending, 'endDate' => 'DESC'])]
    private Collection $formations;

    /**
     * @Assert\Valid(traverse=true)
     *
     * @var Collection<int, CV\Experience>
     */
    #[ORM\OneToMany(targetEntity: CV\Experience::class, mappedBy: 'CV', cascade: ['persist', 'remove', 'detach'], orphanRemoval: true)]
    //    #[ORM\OrderBy(['startDate' => Order::Descending, 'endDate' => 'DESC'])]
    private Collection $experiences;

    #[ORM\ManyToOne(targetEntity: Person::class)]
    private ?Person $person = null;

    public function __construct()
    {
        $this->formations = new ArrayCollection();
        $this->experiences = new ArrayCollection();
        $this->reportDate = new \DateTime('now');
    }

    /**
     * Get id.
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set reportDate.
     */
    public function setReportDate(\DateTime $reportDate): self
    {
        $this->reportDate = $reportDate;

        return $this;
    }

    /**
     * Get reportDate.
     */
    public function getReportDate(): ?\DateTimeInterface
    {
        return $this->reportDate;
    }

    /**
     * Set formationLevel.
     */
    public function setFormationLevel(?string $formationLevel = null): self
    {
        $this->formationLevel = $formationLevel;

        return $this;
    }

    /**
     * Get formationLevel.
     *
     * @return string|null
     */
    public function getFormationLevel()
    {
        return $this->formationLevel;
    }

    /**
     * Set formationType.
     */
    public function setFormationType(string $formationType): self
    {
        $this->formationType = $formationType;

        return $this;
    }

    /**
     * Get formationType.
     */
    public function getFormationType(): ?string
    {
        return $this->formationType;
    }

    /**
     * Set spokenLanguages.
     *
     * @param mixed|null $spokenLanguages
     */
    public function setSpokenLanguages($spokenLanguages = null): self
    {
        $this->spokenLanguages = $spokenLanguages;

        return $this;
    }

    /**
     * Get spokenLanguages.
     */
    public function getSpokenLanguages(): array
    {
        return $this->spokenLanguages ?? [];
    }

    /**
     * Set notes.
     */
    public function setNotes(?string $notes = null): self
    {
        $this->notes = $notes;

        return $this;
    }

    /**
     * Get notes.
     */
    public function getNotes(): ?string
    {
        return $this->notes;
    }

    public function getFormations(): Collection
    {
        return $this->formations;
    }

    public function getExperiences(): Collection
    {
        return $this->experiences;
    }

    public function setFormations(Collection $formations): self
    {
        foreach ($formations as $formation) {
            /* @var CV\Formation $formation */
            $formation->setCV($this);
        }
        $this->formations = $formations;

        return $this;
    }

    public function addFormation(CV\Formation $formation): self
    {
        if ($this->formations->contains($formation)) {
            return $this;
        }

        $this->formations->add($formation);
        $formation->setCV($this);

        return $this;
    }

    public function removeFormation(CV\Formation $formation): self
    {
        if (false === $this->formations->contains($formation)) {
            return $this;
        }

        $formation->setCV(null);
        $this->formations->removeElement($formation);

        return $this;
    }

    public function setExperiences(Collection $experiences): self
    {
        foreach ($experiences as $experience) {
            /* @var CV\Experience $experience */
            $experience->setCV($this);
        }

        $this->experiences = $experiences;

        return $this;
    }

    public function addExperience(CV\Experience $experience): self
    {
        if ($this->experiences->contains($experience)) {
            return $this;
        }

        $experience->setCV($this);
        $this->experiences->add($experience);

        return $this;
    }

    public function removeExperience(CV\Experience $experience): self
    {
        if (false === $this->experiences->contains($experience)) {
            return $this;
        }

        $this->experiences->removeElement($experience);
        $experience->setCV(null);

        return $this;
    }

    public function getPerson(): Person
    {
        return $this->person;
    }

    public function setPerson(Person $person)
    {
        $this->person = $person;

        return $this;
    }

    public function __toString(): string
    {
        return 'CV de '.$this->getPerson().' daté du '.
            $this->getReportDate()->format('d-m-Y');
    }
}
