<?php

namespace idoit\Module\Pro\Model;

use idoit\Component\Helper\Purify;
use idoit\Model\Dao\Base;
use isys_component_dao_result;
use isys_exception_dao;
use isys_exception_database;

/**
 * Class Language
 *
 * @package   idoit\Module\System\Model
 * @copyright synetics GmbH
 * @license   http://www.i-doit.com/license
 */
class Language extends Base
{
    public const UNDELETABLE = ['en', 'de'];

    private const FIELDS = [
        'isys_language__id'        => 'id',
        'isys_language__title'     => 'title',
        'isys_language__short'     => 'short',
        'isys_language__icon'      => 'icon',
        'isys_language__available' => 'available',
        'isys_language__const'     => 'const',
        'isys_language__sort'      => 'sort'
    ];

    /**
     * @return isys_component_dao_result
     * @throws isys_exception_database
     */
    public function getAll(): isys_component_dao_result
    {
        $fields = $this->selectImplode(self::FIELDS);

        return $this->retrieve("SELECT {$fields} FROM isys_language;");
    }

    /**
     * @param string $abbreviation
     * @param string $name
     * @param string $icon
     * @param bool   $available
     *
     * @return bool
     * @throws isys_exception_dao
     */
    public function save(string $abbreviation, string $name, string $icon, bool $available): bool
    {
        $name = $this->convert_sql_text($name);
        $abbreviation = $this->convert_sql_text($abbreviation);
        $icon = $this->convert_sql_text($icon);
        $available = $this->convert_sql_boolean($available);

        $sql = "UPDATE isys_language SET
            isys_language__title = {$name},
            isys_language__icon = {$icon},
            isys_language__available = {$available}
            WHERE isys_language__short = {$abbreviation}
            LIMIT 1;";

        return $this->update($sql) && $this->apply_update();
    }

    /**
     * @param string $abbreviation
     * @param string $name
     * @param string $icon
     * @param bool   $available
     *
     * @return bool
     * @throws isys_exception_dao
     * @throws isys_exception_database
     */
    public function create(string $abbreviation, string $name, string $icon, bool $available): bool
    {
        $nextSort = 1 + $this
            ->retrieve('SELECT MAX(isys_language__id) AS cnt FROM isys_language LIMIT 1;')
            ->get_row_value('cnt');

        $name = $this->convert_sql_text($name);
        $abbreviation = $this->convert_sql_text($abbreviation);
        $icon = $this->convert_sql_text($icon);
        $available = $this->convert_sql_boolean($available);
        $constant = $this->convert_sql_text(Purify::formatConstant("ISYS_CUSTOM_LANGUAGE_{$name}"));

        $sql = "INSERT INTO isys_language SET
            isys_language__title = {$name},
            isys_language__short = {$abbreviation},
            isys_language__icon = {$icon},
            isys_language__available = {$available},
            isys_language__const = {$constant},
            isys_language__sort = {$nextSort};";

        return $this->update($sql) && $this->apply_update();
    }

    /**
     * @param string $abbreviation
     *
     * @return array|null
     * @throws isys_exception_database
     */
    public function getByAbbreviation(string $abbreviation): ?array
    {
        $fields = $this->selectImplode(self::FIELDS);
        $abbreviation = $this->convert_sql_text($abbreviation);

        $sql = "SELECT {$fields} FROM isys_language WHERE isys_language__short = {$abbreviation} LIMIT 1;";

        return $this->retrieve($sql)->get_row();
    }

    /**
     * @param string $abbreviation
     *
     * @return bool
     * @throws isys_exception_dao
     */
    public function delete(string $abbreviation): bool
    {
        if (in_array($abbreviation, self::UNDELETABLE, true)) {
            return false;
        }

        $abbreviation = $this->convert_sql_text($abbreviation);

        $sql = "DELETE FROM isys_language WHERE isys_language__short = {$abbreviation} LIMIT 1;";

        return $this->update($sql) && $this->apply_update();
    }
}
