<?php

namespace Webapp\Core\Entity\DataView;

use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use Webapp\Core\Entity\Block;
use Webapp\Core\Entity\Experiment;
use Webapp\Core\Entity\FieldMeasure;
use Webapp\Core\Entity\GeneratorVariable;
use Webapp\Core\Entity\Individual;
use Webapp\Core\Entity\ProjectData;
use Webapp\Core\Entity\SemiAutomaticVariable;
use Webapp\Core\Entity\Session;
use Webapp\Core\Entity\SimpleVariable;
use Webapp\Core\Entity\SubBlock;
use Webapp\Core\Entity\SurfacicUnitPlot;
use Webapp\Core\Entity\UnitPlot;
use Webapp\Core\Enumeration\PathLevelEnum;

/**
 * @ApiResource(
 *      normalizationContext={"groups"={"data_view_item"}},
 *      collectionOperations={
 *          "get"={},
 *      },
 *      itemOperations={
 *          "get"={},
 *      },
 *  )
 *
 * @ApiFilter(SearchFilter::class, properties={
 *     "projectData": "exact",
 *     "session": "exact",
 * })
 *
 * @ORM\Entity(readOnly=true)
 *
 * @ORM\Table(name="view_data_item", schema="webapp")
 *
 * @psalm-immutable
 */
class DataViewItem
{
    /**
     * @ORM\Id()
     *
     * @Groups({"data_view_item"})
     *
     * @ORM\ManyToOne(targetEntity="Webapp\Core\Entity\FieldMeasure")
     */
    private ?FieldMeasure $fieldMeasure = null;

    /**
     * @Groups({"data_view_item"})
     *
     * @ORM\ManyToOne(targetEntity="Webapp\Core\Entity\ProjectData")
     */
    private ?ProjectData $projectData = null;

    /**
     * @Groups({"data_view_item"})
     *
     * @ORM\ManyToOne(targetEntity="Webapp\Core\Entity\Session")
     */
    private ?Session $session = null;

    /**
     * @ORM\ManyToOne(targetEntity="Webapp\Core\Entity\Experiment")
     */
    private ?Experiment $experimentTarget = null;

    /**
     * @ORM\ManyToOne(targetEntity="Webapp\Core\Entity\Block")
     */
    private ?Block $blockTarget = null;

    /**
     * @ORM\ManyToOne(targetEntity="Webapp\Core\Entity\SubBlock")
     */
    private ?SubBlock $subBlockTarget = null;

    /**
     * @ORM\ManyToOne(targetEntity="Webapp\Core\Entity\SurfacicUnitPlot")
     */
    private ?SurfacicUnitPlot $surfacicUnitPlotTarget = null;

    /**
     * @ORM\ManyToOne(targetEntity="Webapp\Core\Entity\UnitPlot")
     */
    private ?UnitPlot $unitPlotTarget = null;

    /**
     * @ORM\ManyToOne(targetEntity="Webapp\Core\Entity\Individual")
     */
    private ?Individual $individualTarget = null;

    /**
     * @ORM\ManyToOne(targetEntity="Webapp\Core\Entity\SimpleVariable")
     */
    private ?SimpleVariable $simpleVariable = null;

    /**
     * @ORM\ManyToOne(targetEntity="Webapp\Core\Entity\GeneratorVariable")
     */
    private ?GeneratorVariable $generatorVariable = null;

    /**
     * @ORM\ManyToOne(targetEntity="Webapp\Core\Entity\SemiAutomaticVariable")
     */
    private ?SemiAutomaticVariable $semiAutomaticVariable = null;

    /**
     * @Groups({"data_view_item"})
     *
     * @ORM\Column()
     */
    private int $repetition = 0;

    /**
     * @Groups({"data_view_item"})
     *
     * @ORM\Column()
     */
    private string $value = '';

    /**
     * @Groups({"data_view_item"})
     *
     * @ORM\Column()
     */
    private int $code = 0;

    /**
     * @Groups({"data_view_item"})
     *
     * @ORM\Column()
     */
    private \DateTime $timestamp;

    /**
     * @Groups({"data_view_item"})
     *
     * @ORM\Column()
     */
    private string $username = '';

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

    /**
     * @Groups({"data_view_item"})
     */
    public function getTargetType(): ?string
    {
        $target = $this->getTarget();
        if ($target instanceof Individual) {
            return PathLevelEnum::INDIVIDUAL;
        } elseif ($target instanceof SurfacicUnitPlot) {
            return PathLevelEnum::SURFACIC_UNIT_PLOT;
        } elseif ($target instanceof UnitPlot) {
            return PathLevelEnum::UNIT_PLOT;
        } elseif ($target instanceof SubBlock) {
            return PathLevelEnum::SUB_BLOCK;
        } elseif ($target instanceof Block) {
            return PathLevelEnum::BLOCK;
        } elseif ($target instanceof Experiment) {
            return PathLevelEnum::EXPERIMENT;
        } else {
            return null;
        }
    }

    /**
     * @Groups({"data_view_item"})
     *
     * @return Block|Experiment|Individual|SubBlock|SurfacicUnitPlot|UnitPlot|null
     */
    public function getTarget()
    {
        return $this->individualTarget ?? $this->surfacicUnitPlotTarget ?? $this->unitPlotTarget ?? $this->subBlockTarget ?? $this->blockTarget ?? $this->experimentTarget;
    }

    /**
     * @Groups({"data_view_item"})
     *
     * @return Block|Experiment|GeneratorVariable|SemiAutomaticVariable|SimpleVariable|SurfacicUnitPlot|null
     */
    public function getVariable()
    {
        return $this->generatorVariable ?? $this->semiAutomaticVariable ?? $this->simpleVariable ?? $this->blockTarget ?? $this->experimentTarget ?? $this->surfacicUnitPlotTarget;
    }

    public function getFieldMeasure(): ?FieldMeasure
    {
        return $this->fieldMeasure;
    }

    public function getProjectData(): ?ProjectData
    {
        return $this->projectData;
    }

    public function getSession(): ?Session
    {
        return $this->session;
    }

    public function getRepetition(): int
    {
        return $this->repetition;
    }

    public function getValue(): string
    {
        return $this->value;
    }

    public function getCode(): int
    {
        return $this->code;
    }

    public function getTimestamp(): \DateTime
    {
        return $this->timestamp;
    }

    public function getUsername(): string
    {
        return $this->username;
    }

    public function getDataViewBusinessObject(): DataViewBusinessObject
    {
        return $this->dataViewBusinessObject;
    }
}
