<?php


namespace App\Model\Services;


use App\Model\Entities\Localization\GuiTranslation;
use App\Model\Entities\Localization\Language;
use App\Model\Entities\Security\User;
use App\Model\Interfaces\ITranslation;
use Doctrine\ORM\Query;
use Kdyby\Doctrine\EntityRepository;

class TranslationService extends BaseService
{
    /** @var  EntityRepository */
    protected $guiTranslations;

    protected function startup()
    {
        parent::startup();

        $this->guiTranslations = $this->getRepository(GuiTranslation::class);
    }

    public function createGuiTranslation($identifier, Language $language)
    {
        $translation = new GuiTranslation();
        $translation->setIdentifier($identifier);
        $translation->setLanguage($language);

        $this->persist($translation);
        return $translation;
    }

    public function translate(ITranslation $translation, $translationText, User $user = null)
    {
        $translation->setTranslation($translationText);
        if ($translationText) {
            $translation->setState(ITranslation::TRANSLATED);
        } else {
            $translation->setState(ITranslation::PENDING);
        }
        $translation->setEditedBy($user);

        return $translation;
    }


    public function findGuiTranslation(Language $language, $identifier)
    {
        $criteria = array('language' => $language, 'identifier' => strtolower($identifier));

        return $this->guiTranslations->findOneBy($criteria);
    }

    public function findGuiTranslationById($id)
    {
        return $this->guiTranslations->find($id);
    }

    /**
     * @param Language $language
     * @return GuiTranslation[]
     */
    public function getGuiTranslations(Language $language)
    {
        $criteria = array('language' => $language);

        return $this->guiTranslations->findBy($criteria);
    }

    public function getGuiTranslationAssoc(Language $language)
    {
        $criteria = array('language' => $language);

        return $this->guiTranslations->findAssoc($criteria, 'identifier');
    }

    public function getPendingTranslationsAssoc(Language $language)
    {
        $criteria = array('language' => $language, 'state' => GuiTranslation::PENDING);

        return $this->guiTranslations->findAssoc($criteria, 'identifier');
    }

    public function countGuiTranslations($criteria = array())
    {
        return $this->guiTranslations->countBy($criteria);
    }

    public function geTranslationsByIdentifiers(Language $language, array $identifiers)
    {
        $result = $this->guiTranslations->createQueryBuilder('t')
            ->select('t.translation')
            ->whereCriteria(['language' => $language, 'identifier' => $identifiers])
            ->getQuery()
            ->getScalarResult();

        if (!$result) {
            return [];
        }

        $transform = function($item) {
            return $item['translation'];
        };

        return array_map($transform, $result);
    }
}