<?php

declare(strict_types=1);

/*
 * @author TRYDEA - 2024
 */

namespace Mobile\Measure\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Shared\Authentication\Entity\IdentifiedEntity;
use Shared\Utils\ArrayCollectionUtils;
use Symfony\Component\Serializer\Annotation\Groups;

/**
 * @ORM\Entity()
 *
 * @ORM\Table(name="session_data", schema="adonis")
 */
class Session extends IdentifiedEntity
{
    /**
     * @ORM\ManyToOne(targetEntity="Mobile\Measure\Entity\DataEntry", inversedBy="sessions")
     *
     * @ORM\JoinColumn(name="data_entry_id", referencedColumnName="id", nullable=false)
     */
    private DataEntry $dataEntry;

    /**
     * @Groups({"status_project_webapp_return_data"})
     *
     * @ORM\Column(type="datetime", nullable=false)
     */
    private \DateTime $startedAt;

    /**
     * @Groups({"status_project_webapp_return_data"})
     *
     * @ORM\Column(type="datetime", nullable=false)
     */
    private \DateTime $endedAt;

    /**
     * @var Collection<int, FormField>
     *
     * @ORM\OneToMany(targetEntity="Mobile\Measure\Entity\FormField", mappedBy="session", cascade={"persist", "remove", "detach"})
     */
    private Collection $formFields;

    public static function build(\DateTime $startedAt, \DateTime $endedAt): self
    {
        return new self($startedAt, $endedAt);
    }

    /**
     * @internal
     *
     * @see Session::build()
     */
    public function __construct(?\DateTime $startedAt = null, ?\DateTime $endedAt = null)
    {
        $this->formFields = new ArrayCollection();
        $this->startedAt = $startedAt ?? new \DateTime();
        $this->endedAt = $endedAt ?? new \DateTime();
    }

    /**
     * @psalm-mutation-free
     */
    public function getDataEntry(): DataEntry
    {
        return $this->dataEntry;
    }

    /**
     * @return $this
     */
    public function setDataEntry(DataEntry $dataEntry): self
    {
        $this->dataEntry = $dataEntry;

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getStartedAt(): \DateTime
    {
        return $this->startedAt;
    }

    /**
     * @return $this
     */
    public function setStartedAt(\DateTime $startedAt): self
    {
        $this->startedAt = $startedAt;

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getEndedAt(): \DateTime
    {
        return $this->endedAt;
    }

    /**
     * @return $this
     */
    public function setEndedAt(\DateTime $endedAt): self
    {
        $this->endedAt = $endedAt;

        return $this;
    }

    /**
     * @return Collection<int,  FormField>
     *
     * @psalm-mutation-free
     */
    public function getFormFields(): Collection
    {
        return $this->formFields;
    }

    /**
     * @param iterable<int, FormField> $formFields
     *
     * @return $this
     */
    public function setFormFields(iterable $formFields): self
    {
        ArrayCollectionUtils::update($this->formFields, $formFields, function (FormField $formField) {
            $formField->setSession($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addFormField(FormField $formField): self
    {
        if (!$this->formFields->contains($formField)) {
            $this->formFields->add($formField);
            $formField->setSession($this);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removeFormField(FormField $formField): self
    {
        if ($this->formFields->contains($formField)) {
            $this->formFields->removeElement($formField);
            $formField->setSession(null);
        }

        return $this;
    }
}
