<?php
/**
 * Created by Error202
 * Date: 04.06.2018
 */

namespace core\forms;

use core\components\LanguageDynamicModel;
use core\entities\Settings;
use yii\base\DynamicModel;
use yii\helpers\Json;
use Yii;

class SettingsForm extends LanguageDynamicModel
{
    public $type;
    public $section;
    public $key;
    public $value;
    public $active;

    public $_settings;

    //public function __construct(Settings $settings = null, $config = [])
    public function __construct(Settings $settings = null, array $attributes = [], $config = [])
    {
        if ($settings) {
            $this->type      = $settings->type;
            $this->section   = $settings->section;
            $this->key       = $settings->key;
            $this->value     = $settings->value;
            $this->active    = $settings->active;
            $this->_settings = $settings;
        }
        //parent::__construct($config);
        parent::__construct($settings, $attributes, $config);
    }

    public function rules()
    {
        return array_merge(
            parent::rules(),
            [
                [['value'], 'string'],
                [['section', 'key'], 'string', 'max' => 255],
                [
                    ['key'],
                    'unique',
                    'targetAttribute' => ['section', 'key'],
                    'targetClass'     => Settings::class,
                    //'filter'          => $this->_settings ? ['<>', 'id', $this->_settings->id] : null,
                    'filter'          => $this->_settings ? ['AND', ['<>', 'section', $this->_settings->section], ['<>', 'key', $this->_settings->key]] : null,
                    'message'         =>
                        Yii::t('main', '{attribute} "{value}" already exists for this section.')
                ],
                ['type', 'in', 'range' => array_keys($this->getTypes(false))],
                [['type'], 'safe'],
                [['active'], 'integer'],
            ]
        );
    }

    public function getTypes($forDropDown = true)
    {
        $values = [
            'string'  => ['value', 'string'],
            'integer' => ['value', 'integer'],
            'boolean' => ['value', 'boolean', 'trueValue' => '1', 'falseValue' => '0', 'strict' => true],
            'float'   => ['value', 'number'],
            'email'   => ['value', 'email'],
            'ip'      => ['value', 'ip'],
            'url'     => ['value', 'url'],
            'object'  => [
                'value',
                function ($attribute) {
                    $object = null;
                    try {
                        Json::decode($this->$attribute);
                    } catch (\InvalidArgumentException $e) {
                        $this->addError($attribute, Yii::t('main', '"{attribute}" must be a valid JSON object', [
                            'attribute' => $attribute,
                        ]));
                    }
                }
            ],
        ];
        if (!$forDropDown) {
            return $values;
        }
        $return = [];
        foreach ($values as $key => $value) {
            $return[$key] = Yii::t('main', $key);
        }

        return $return;
    }

    public function attributeLabels()
    {
        return array_merge(
            parent::attributeLabels(),
            [
                'id'         => Yii::t('main', 'ID'),
                'type'       => Yii::t('main', 'Type'),
                'section'    => Yii::t('main', 'Section'),
                'key'        => Yii::t('main', 'Key'),
                'value'      => Yii::t('main', 'Value'),
                'active'     => Yii::t('main', 'Active'),
                'crated_at'  => Yii::t('main', 'Created At'),
                'updated_at' => Yii::t('main', 'Updated At'),
            ]
        );
    }

    public function beforeValidate()
    {
        $validators = $this->getTypes(false);
        if (!array_key_exists($this->type, $validators)) {
            $this->addError('type', Yii::t('main', 'Please select correct type'));

            return false;
        }
        $model = DynamicModel::validateData([
            'value' => $this->value
        ], [
            $validators[$this->type],
        ]);
        if ($model->hasErrors()) {
            $this->addError('value', $model->getFirstError('value'));

            return false;
        }
        if ($this->hasErrors()) {
            return false;
        }

        return parent::beforeValidate();
    }
}