<?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 Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\Mapping as ORM;
use Chill\PersonBundle\Entity\HasPerson;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;

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

    /**
     * @Assert\NotNull()
     *
     * @Assert\GreaterThan("5 years ago",
     *  message="La date du rapport ne peut pas être plus de cinq ans dans le passé"
     * )
     */
    #[ORM\Column(name: 'reportDate', type: \Doctrine\DBAL\Types\Types::DATE_MUTABLE)]
    private ?\DateTimeInterface $reportDate = null;

    public const FREINS_PERSO = [
        'situation_administrative',
        'situation_personnelle_et_familiale',
        'comportement',
        'etat_de_sante',
        'precarite_situation_materielle',
        'condition_ou_absence_logement',
        'autres',
    ];

    /**
     * @var string[]
     */
    #[ORM\Column(name: 'freinsPerso', type: \Doctrine\DBAL\Types\Types::JSON)]
    private $freinsPerso = [];

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

    public const FREINS_EMPLOI = [
        'garde_d_enfants',
        'sante',
        'famille',
        'finances',
        'maitrise_de_la_langue',
        'autres',
    ];

    /**
     * @var string[]
     */
    #[ORM\Column(name: 'freinsEmploi', type: \Doctrine\DBAL\Types\Types::JSON)]
    private $freinsEmploi = [];

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

    /**
     * @Assert\NotNull()
     */
    #[ORM\ManyToOne(targetEntity: Person::class)]
    private Person $person;

    public function __construct()
    {
        $this->reportDate = new \DateTime('today');
    }

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

    public function setReportDate(?\DateTimeInterface $reportDate): self
    {
        $this->reportDate = $reportDate;

        return $this;
    }

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

    public function setFreinsPerso(array $freinsPerso = []): self
    {
        $this->freinsPerso = $freinsPerso;

        return $this;
    }

    public function getFreinsPerso(): array
    {
        return $this->freinsPerso;
    }

    public function setNotesPerso(?string $notesPerso = null): self
    {
        $this->notesPerso = (string) $notesPerso;

        return $this;
    }

    public function getNotesPerso(): ?string
    {
        return $this->notesPerso;
    }

    public function setFreinsEmploi(array $freinsEmploi = []): self
    {
        $this->freinsEmploi = $freinsEmploi;

        return $this;
    }

    public function getFreinsEmploi(): array
    {
        return $this->freinsEmploi;
    }

    public function setNotesEmploi(?string $notesEmploi = null): self
    {
        $this->notesEmploi = (string) $notesEmploi;

        return $this;
    }

    public function getNotesEmploi(): ?string
    {
        return $this->notesEmploi;
    }

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

    public function setPerson(?Person $person = null): HasPerson
    {
        $this->person = $person;

        return $this;
    }

    /**
     * @Assert\Callback()
     */
    public function validateFreinsCount(ExecutionContextInterface $context, $payload): void
    {
        $nb = count($this->getFreinsEmploi()) + count($this->getFreinsPerso());

        if (0 === $nb) {
            $msg = 'Indiquez au moins un frein parmi les freins '
                ."liés à l'emploi et les freins liés à la situation personnelle.";
            $context->buildViolation($msg)
                ->atPath('freinsEmploi')
                ->addViolation();

            $context->buildViolation($msg)
                ->atPath('freinsPerso')
                ->addViolation();
        }
    }

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