<?php

namespace App\Model\Entities\Localization;

use App\Model\Entities\BaseEntity;
use App\Model\Entities\Security\User;
use App\Model\Exceptions\Db\InvalidStateException;
use App\Model\Interfaces\ITranslation;
use DateTime;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="translation", uniqueConstraints={@ORM\UniqueConstraint(name="unique_translation", columns={"identifier", "language_id"})})
 * @ORM\InheritanceType(value="SINGLE_TABLE")
 */
class Translation extends BaseEntity implements ITranslation
{
    /**
     * @ORM\Column(type="string")
     */
    protected $state;

    /**
     * @ORM\Column(type="string")
     */
    protected $identifier;

    /**
     * @var Language
     * @ORM\ManyToOne(targetEntity="Language")
     */
    protected $language;

    /**
     * @ORM\Column(type="string", nullable=true)
     */
    protected $translation;

    /**
     * @var DateTime
     * @ORM\Column(type="datetime", nullable=true)
     */
    protected $editedAt;

    /**
     * @var User
     * @ORM\ManyToOne(targetEntity="App\Model\Entities\Security\User")
     * @ORM\JoinColumn(nullable=true)
     */
    protected $editedBy;

    public function __construct()
    {
        $this->setState(self::PENDING);
    }

    /**
     * @return string
     */
    public function getState() : string
    {
        return $this->state;
    }

    /**
     * @param string $state
     * @throws InvalidStateException
     */
    public function setState(string $state)
    {
        if (!$this->isValidState($state)) {
            throw new InvalidStateException();
        }

        $this->state = $state;
    }

    /**
     * @return mixed
     */
    public function getIdentifier()
    {
        return $this->identifier;
    }

    /**
     * @param mixed $identifier
     */
    public function setIdentifier($identifier)
    {
        $this->identifier = strtolower($identifier);
    }

    /**
     * @return Language
     */
    public function getLanguage() : Language
    {
        return $this->language;
    }

    /**
     * @param Language $language
     */
    public function setLanguage(Language $language)
    {
        $this->language = $language;
    }

    /**
     * @return mixed
     */
    public function getTranslation()
    {
        return $this->translation;
    }

    /**
     * @param mixed $translation
     */
    public function setTranslation($translation)
    {
        $this->translation = $translation;
    }

    /**
     * @return DateTime|null
     */
    public function getEditedAt()
    {
        return $this->editedAt;
    }

    /**
     * @return User|null
     */
    public function getEditedBy()
    {
        return $this->editedBy;
    }

    /**
     * @param User $editedBy
     */
    public function setEditedBy(User $editedBy)
    {
        $this->editedBy = $editedBy;

        $this->editedAt = new DateTime();
    }

    protected function isValidState(string $state) : bool
    {
        $validStates = [self::PENDING, self::BY_TRANSLATOR, self::TRANSLATED];

        return in_array($state, $validStates);
    }
}