<?php

declare(strict_types=1);

/*
 * @author TRYDEA - 2024
 */

namespace Mobile\Measure\Entity;

use Doctrine\ORM\Mapping as ORM;
use Mobile\Measure\Entity\Variable\StateCode;
use Mobile\Project\Entity\ProjectObject;

/**
 * @ORM\Entity()
 *
 * @ORM\Table(name="measure", schema="adonis")
 */
class Measure extends ProjectObject
{
    /**
     * @ORM\ManyToOne(targetEntity="Mobile\Measure\Entity\FormField", inversedBy="measures")
     *
     * @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
     */
    private FormField $formField;

    /**
     * @ORM\Column(type="text", nullable=true)
     */
    private ?string $value;

    /**
     * Define the repetition number of the variable.
     *
     * @ORM\Column(type="integer", nullable=false)
     */
    private int $repetition;

    /**
     * @ORM\Column(type="datetime", nullable=false)
     */
    private \DateTime $timestamp;

    /**
     * @ORM\ManyToOne(targetEntity="Mobile\Measure\Entity\Variable\StateCode")
     *
     * @ORM\JoinColumn(nullable=true)
     */
    private ?StateCode $state;

    /**
     * Generate measure with value.
     *
     * @param int|string|null $value
     */
    public static function buildValue(\DateTime $date, $value): self
    {
        return new self($date, $value);
    }

    /**
     * Build measure with repetition.
     *
     * @param int|string|null $value
     * @param positive-int    $repetition
     */
    public static function buildRepetition(\DateTime $date, $value, int $repetition): self
    {
        return new self($date, $value, $repetition);
    }

    /**
     * Build measure with state code.
     */
    public static function buildStateCode(\DateTime $date, StateCode $stateCodes): self
    {
        return new self($date, null, 1, $stateCodes);
    }

    /**
     * @param int|string|null $value
     *
     * @internal use {@see self::buildValue()}, {@see self::buildRepetition()} or {@see self::buildStateCode()}
     */
    public function __construct(?\DateTime $date = null, $value = null, int $repetition = 1, ?StateCode $stateCode = null)
    {
        parent::__construct();
        $this->timestamp = $date ?? new \DateTime();
        $this->value = null !== $value ? (string) $value : null;
        $this->repetition = $repetition;
        $this->state = $stateCode;
    }

    /**
     * @psalm-mutation-free
     */
    public function getFormField(): FormField
    {
        return $this->formField;
    }

    /**
     * @return $this
     */
    public function setFormField(FormField $formField): self
    {
        $this->formField = $formField;

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getValue(): ?string
    {
        return $this->value;
    }

    /**
     * @return $this
     */
    public function setValue(?string $value): self
    {
        $this->value = $value;

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getRepetition(): int
    {
        return $this->repetition;
    }

    /**
     * @return $this
     */
    public function setRepetition(int $repetition): self
    {
        $this->repetition = $repetition;

        return $this;
    }

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

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

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getState(): ?StateCode
    {
        return $this->state;
    }

    /**
     * @return $this
     */
    public function setState(?StateCode $state): self
    {
        $this->state = $state;

        return $this;
    }
}
