<?php


namespace App\Model\Facades\Writers;


use App\Model\Exceptions\Db\RecordNotFoundException;
use App\Model\Exceptions\Translator\UnsupportedLanguageException;
use App\Model\Entities\Localization\Language;
use App\Model\Facades\Readers\LanguageReader;
use App\Model\Facades\Readers\TranslationReader;
use App\Model\Services\LanguageService;
use Exception;
use Throwable;

class LanguageWriter extends BaseWriter
{
    /** @var LanguageService */
    protected $languageService;
    /** @var LanguageReader */
    protected $languageReader;
    /** @var  TranslationReader */
    protected $translationReader;
    /** @var  TranslationWriter */
    protected $translationWriter;

    public function inject(LanguageService $languageService, LanguageReader $languageReader, TranslationReader $translationReader,TranslationWriter $translationWriter)
    {
        $this->languageService = $languageService;
        $this->languageReader = $languageReader;
        $this->translationReader = $translationReader;
        $this->translationWriter = $translationWriter;
    }

    /**
     * @param $identifier
     * @param $name
     * @return Language
     * @throws Throwable
     */
    public function registerNewLanguage($identifier, $name)
    {
        try {
            $this->beginTransaction();
            $language = $this->languageService->createLanguage($this->getLoggedInUser(), $identifier, $name);

            if ($identifier != 'en') {
                $defaultLanguage = $this->languageReader->getDefaultLanguage();
                $guiTranslations = $this->translationReader->getGuiTranslations($defaultLanguage);

                foreach ($guiTranslations as $translation) {
                    $this->translationWriter->createGuiTranslation($translation->getIdentifier(), $language);
                }
            }

            $this->commit();
        } catch (Throwable $e) {
            $this->rollback();
            throw $e;
        }

        return $language;
    }

    /**
     * @param $language
     * @param $state
     * @return Language
     * @throws Exception
     * @throws UnsupportedLanguageException
     * @throws RecordNotFoundException
     */
    public function changeLanguageState($language, $state)
    {
        $languageEntity = $this->languageReader->validateLanguage($language);

        if ($languageEntity->getState() != $state) {
            try {
                $this->beginTransaction();
                $languageEntity->setState($state);
                $this->commit();
            } catch (Exception $e) {
                $this->rollback();
                throw $e;
            }
        }

        return $languageEntity;
    }

    /**
     * @param $language
     * @param $identifier
     * @return Language
     * @throws Exception
     * @throws UnsupportedLanguageException
     * @throws RecordNotFoundException
     */
    public function editLanguageIdentifier($language, $identifier)
    {
        $languageEntity = $this->languageReader->validateLanguage($language);

        if ($languageEntity->getIdentifier() != $identifier) {
            try {
                $this->beginTransaction();
                $languageEntity->setIdentifier($identifier);
                $this->commit();
            } catch (Exception $e) {
                $this->rollback();
                throw $e;
            }
        }

        return $languageEntity;
    }

    /**
     * @param $language
     * @param $name
     * @return Language
     * @throws Exception
     * @throws UnsupportedLanguageException
     * @throws RecordNotFoundException
     */
    public function editLanguageName($language, $name)
    {
        $languageEntity = $this->languageReader->validateLanguage($language);

        if ($languageEntity->getName() != $name) {
            try {
                $this->beginTransaction();
                $languageEntity->setName($name);
                $this->commit();
            } catch (Exception $e) {
                $this->rollback();
                throw $e;
            }
        }

        return $languageEntity;
    }

}