<?php

namespace idoit\Module\Pro\Controller;

use idoit\Component\Helper\Purify;
use idoit\Module\Pro\Model\Language;
use idoit\Module\Pro\Model\Translation as TranslationModel;
use isys_application as Application;
use isys_component_constant_manager;
use isys_exception_general;
use isys_format_json as JSON;
use isys_register as Register;

/**
 * i-doit pro controller
 *
 * @package   Modules
 * @copyright synetics GmbH
 * @license   http://www.i-doit.com/license
 */
class Translation extends Main
{
    /**
     * @var array
     */
    protected $response;

    /**
     * @param Register    $request
     * @param Application $application
     *
     * @return null
     */
    public function handle(Register $request, Application $application)
    {
        return null;
    }

    /**
     * Pre method gets called by the framework.
     *
     * @return void
     */
    public function pre()
    {
        header('Content-Type: application/json');

        $this->response = [
            'success' => true,
            'data'    => null,
            'message' => null
        ];
    }

    /**
     * @param Register $request
     *
     * @return void
     */
    public function getTranslations(Register $request)
    {
        try {
            $translationCache = Application::instance()->container->get('language')->getCache();
            $customTranslationCache = Application::instance()->container->get('language')->getCustomCache();
            $abbreviation = Application::instance()->container->get('request')->query->get('abbreviation');
            $translationModel = new TranslationModel();

            // Empty the language cache.
            $languageCopy = [];
            $customTranslations = $translationModel->getCustomTranslations($abbreviation);

            foreach ($translationCache as $key => $value) {
                $languageCopy[$key] = [
                    'key' => $key,
                    'value' => $value,
                    'custom' => $customTranslations[$key] ?? '',
                ];
            }

            // @see ID-9220 Because we separate the "core" and "custom" language, we'll iterate over the custom translations here.
            foreach ($customTranslationCache as $key => $value) {
                if (isset($languageCopy[$key])) {
                    continue;
                }

                $languageCopy[$key] = [
                    'key' => $key,
                    'value' => $value,
                    'custom' => $customTranslations[$key] ?? '',
                ];
            }

            // @see ID-9220 Get custom keys from all languages, so that every language has all keys.
            $remainingKeys = $translationModel->getAllCustomKeys();

            foreach ($remainingKeys as $key) {
                if (isset($languageCopy[$key])) {
                    continue;
                }

                $languageCopy[$key] = [
                    'key' => $key,
                    'value' => '',
                    'custom' => '',
                ];
            }

            usort($languageCopy, function (array $a, array $b): int {
                return strcasecmp($a['value'], $b['value']);
            });

            $this->response['data'] = array_values($languageCopy);
        } catch (\Exception $e) {
            $this->response['success'] = false;
            $this->response['message'] = $e->getMessage();
        }
    }

    /**
     * @param Register $request
     *
     * @return void
     */
    public function saveTranslations(Register $request)
    {
        try {
            $request = Application::instance()->container->get('request')->request;
            $languageModel = Language::instance(Application::instance()->container->get('database_system'));

            $abbreviation = strtolower($request->get('abbreviation'));
            $translation = JSON::decode($request->get('translations'), true);
            $meta = JSON::decode($request->get('meta'), true);

            if (empty($abbreviation)) {
                if ($languageModel->getByAbbreviation($meta['abbreviation'])) {
                    throw new isys_exception_general('The abbreviation "' . $meta['abbreviation'] . '" is alrady in use. Please choose a different one!');
                }

                $meta['abbreviation'] = mb_substr(strtolower(Purify::formatFilename($meta['abbreviation'])), 0, 8);
                $languageModel->create($meta['abbreviation'], $meta['title'], $meta['icon'], (bool)$meta['available']);
                $abbreviation = $meta['abbreviation'];

                // Clear the DCS cache in order to re-create the language constants.
                isys_component_constant_manager::instance()->clear_dcs_cache();
            } else {
                $languageModel->save($abbreviation, $meta['title'], $meta['icon'], (bool)$meta['available']);
            }

            (new TranslationModel())->saveCustomTranslations($abbreviation, $translation);

            $this->response['data'] = [
                'abbreviation' => $abbreviation
            ];
        } catch (\Exception $e) {
            $this->response['success'] = false;
            $this->response['message'] = $e->getMessage();
        }
    }

    /**
     * @param Register $request
     *
     * @return void
     * @see ID-9220 This method will create new translations via popup.
     */
    public function createNewTranslation(Register $request)
    {
        try {
            $request = Application::instance()->container->get('request')->request;
            $translationModel = new TranslationModel();
            $result = Language::instance(Application::instance()->container->get('database_system'))->getAll();
            $translation = JSON::decode($request->get('translation'), true);

            while ($row = $result->get_row()) {
                $translationModel->saveCustomTranslations($row['short'], $translation);
            }
        } catch (\Exception $e) {
            $this->response['success'] = false;
            $this->response['message'] = $e->getMessage();
        }
    }

    /**
     * Post method gets called by the framework.
     *
     * @return void
     */
    public function post()
    {
        echo JSON::encode($this->response);
        die;
    }
}
