<?php

namespace app\components;

use Yii;

use yii\base\DynamicModel;
use yii\widgets\ActiveField;
use app\components\Utilities;

class BaseField{
    static public $model;
    public $field;
    public $structure;
    public $name;
    public $label;
    public $template = "{label}\n{input}\n{hint}\n{error}";
    public $form_fields;
    public $js_script;
    public $is_disabled = false;
    public $form_id;
    
    // value & document are used to fill field value in case of document exists (e.g. update method)
    public $value;
    public $document;

    public function __construct($structure, $document = null, $form_id = null){
        $this->structure = $structure;
        $this->form_id = $form_id;
        $this->document = $document;
        $this->name = $this->structure['name'];
        $this->label = $this->structure['label'];
        if(self::$model == null){
            self::$model = new DynamicModel();
        }
        $this->field = new ActiveField();
        $this->field->model = self::$model;
        $this->field->model->defineAttribute($this->name);
        $this->field->attribute = $this->name;
        if($document != null && isset($document[$this->name])){
            $this->value = $document[$this->name];
        }

        if(isset($this->structure['description'])){
            $this->field->template = "{label}\n<p>" . $this->structure['description'] . "</p>\n{input}\n{hint}\n{error}";
        }
        if((isset($this->structure['isHidden']) && $this->structure['isHidden'] && isset($this->structure['showIfLogicCheckbox']) && ! $this->structure['showIfLogicCheckbox']) || (isset($this->structure['deactivate']) && $this->structure['deactivate'])){
            $this->field->options = ['style' => 'display: none;'];
        }
        elseif(isset($this->structure['isReadOnly']) && $this->structure['isReadOnly'] && ! in_array($this->structure['type'], ['select', 'radio-group', 'checkbox-group']) && isset($this->structure['defaultValue'])){
            self::$model->{$this->name} = $this->structure['defaultValue'];
            $this->is_disabled = true;
        }
        else{
            if(isset($this->structure['required']) && $this->structure['required']){
                self::$model->addRule([$this->name], 'required', ['message' => Yii::t('app', '{field} can not be blank', ['field' => ucfirst($this->label)])]);
            }
            if(isset($this->structure['showIfLogicCheckbox']) && $this->structure['showIfLogicCheckbox']){
                $show_if_field_name = 'DynamicModel[' . $this->structure['showIfFieldName'] . ']';
                $is_checkbox_group = Utilities::isCheckboxGroup($this->structure['showIfFieldName']);
                if($is_checkbox_group){
                    $show_if_field_name .= '[]';    // We added [] because it's an array
                    $encoded_show_if_field_name = Utilities::customJsonEncode($show_if_field_name);
                    $this->js_script = "
                        $('[name=" . $encoded_show_if_field_name . "]').change(function(){
                            var values = $('[name=" . $encoded_show_if_field_name . "]:checked');
                            var valuesText = [];
                            if(values){
                                for(var i = 0; i < values.length; i++){
                                    valuesText.push($(values[i]).val());
                                }
                                if(valuesText.includes(" . Utilities::customJsonEncode($this->structure['showIfFieldValue']) . ")){
                                    $('div.field-dynamicmodel-" . $this->name . "').slideDown(250);
                                }
                                else{
                                    $('div.field-dynamicmodel-" . $this->name . "').slideUp(250);
                                }
                            }
                        });
                    ";
    
                    if(isset($this->structure['showIfIsRequired']) && $this->structure['showIfIsRequired']){
                        self::$model->addRule([$this->name], 'required', ['when' => function($model){
                            if($model->{$this->structure['showIfFieldName']}){
                                return in_array($this->structure['showIfFieldValue'], $model->{$this->structure['showIfFieldName']});
                            }
                            else{
                                return true;
                            }
                        }, 'whenClient' => "function(attribute, value){
                            var selectedOptions = $('[name=\"DynamicModel[" . $this->structure['showIfFieldName'] . "][]\"]').filter(':checked');
                            if(selectedOptions.length){
                                var values = [];
                                for(var i = 0; i < selectedOptions.length; i++){
                                    values.push($(selectedOptions[i]).val());
                                }
                                return values.includes('" . $this->structure['showIfFieldValue'] . "');
                            }
                        }", 'message' => Yii::t('app', 'This field can not be blank')]);
                    }
                }
                else{
                    $this->js_script = "
                        $('[name=" . Utilities::customJsonEncode($show_if_field_name) . "]').change(function(){
                            var value = $(this).val();
                            if(value == " . Utilities::customJsonEncode($this->structure['showIfFieldValue']) . "){
                                $('div.field-dynamicmodel-" . $this->name . "').slideDown(250);
                            }
                            else{
                                $('div.field-dynamicmodel-" . $this->name . "').slideUp(250);
                            }
                        });
                    ";
    
                    if(isset($this->structure['showIfIsRequired']) && $this->structure['showIfIsRequired']){
                        if(Utilities::isSelect($this->structure['showIfFieldName'])){
                            self::$model->addRule([$this->name], 'required', ['when' => function($model) {
                                return $model->{$this->structure['showIfFieldName']} == $this->structure['showIfFieldValue'];
                            }, 'whenClient' => "function(attribute, value){
                                return $('[name=\"DynamicModel[" . $this->structure['showIfFieldName'] . "]\"]').find(':selected').val() == '" . $this->structure['showIfFieldValue'] . "';
                            }", 'message' => Yii::t('app', 'This field can not be blank')]);   
                        }
                        else{
                            self::$model->addRule([$this->name], 'required', ['when' => function($model) {
                                return $model->{$this->structure['showIfFieldName']} == $this->structure['showIfFieldValue'];
                            }, 'whenClient' => "function(attribute, value){
                                return $('[name=\"DynamicModel[" . $this->structure['showIfFieldName'] . "]\"]:checked').val() == '" . $this->structure['showIfFieldValue'] . "';
                            }", 'message' => Yii::t('app', 'This field can not be blank')]);
                        }
                    }
                }

                $this->field->options = ['style' => 'display: none;'];
                // Check if the field visibility (within show-if rule) is related with 'selected' value by default,
                // so we have to display the field if its showIfFieldValue equals selected value
                if(in_array(Yii::$app->controller->action->id, ['render-form', 'public-form'])){
                    $show_if_selected_values = Utilities::checkShowIfSelectedValue($form_id, $this->structure['showIfFieldName']);
                    if($show_if_selected_values && in_array($this->structure['showIfFieldValue'], $show_if_selected_values)){
                        $this->field->options = ['style' => 'display: block;'];
                    }
                }
            }
            if(isset($this->structure['requiredIfLogicCheckbox']) && $this->structure['requiredIfLogicCheckbox']){
                $required_if_field_name = $this->structure['requiredIfFieldName'];
                $required_if_field_value = Utilities::customJsonEncode($this->structure['requiredIfFieldValue']);
    
                if(Utilities::isSelect($required_if_field_name)){
                    self::$model->addRule([$this->name], 'required', ['when' => function($model) use($required_if_field_name, $required_if_field_value){
                        return $model->{$required_if_field_name} == $required_if_field_value;
                    }, 'whenClient' => "function(attribute, value){
                        return $('[name=\"DynamicModel[" . $required_if_field_name . "]\"]').find(':selected').val() == " . $required_if_field_value . ";
                    }", 'message' => Yii::t('app', 'This field can not be blank')]);   
                }
                elseif(Utilities::isRadioGroup($required_if_field_name)){
                    self::$model->addRule([$this->name], 'required', ['when' => function($model) use($required_if_field_name, $required_if_field_value){
                        return $model->{$required_if_field_name} == $required_if_field_value;
                    }, 'whenClient' => "function(attribute, value){
                        return $('[name=\"DynamicModel[" . $required_if_field_name . "]\"]:checked').val() == " . $required_if_field_value . ";
                    }", 'message' => Yii::t('app', 'This field can not be blank')]);
                }
                else{
                    // Checkbox group's value is an array
                    self::$model->addRule([$this->name], 'required', ['when' => function($model) use($required_if_field_name, $required_if_field_value){
                        if($model->{$required_if_field_name}){
                            return in_array($required_if_field_value, $model->{$required_if_field_name});
                        }
                        else{
                            return true;
                        }
                        
                    }, 'whenClient' => "function(attribute, value){
                        var selectedOptions = $('[name=\"DynamicModel[" . $required_if_field_name . "][]\"]').filter(':checked');
                        if(selectedOptions.length){
                            var values = [];
                            for(var i = 0; i < selectedOptions.length; i++){
                                values.push($(selectedOptions[i]).val());
                            }
                            return values.includes(" . $required_if_field_value . ");
                        }
                    }", 'message' => Yii::t('app', 'This field can not be blank')]);
                }
            }
        }
    }
}