<?php

/**
 * Manage application and plugins configurations with key/value pair.
 * **nb:** It's possible to specify namespace in order to distinct global configuration to plugin custom configuration
 * @author valentin carruesco
 * @category Core
 * @license copyright
 */
class Configuration extends Entity
{
    public $id,$key,$value;
    protected $confTab;
    protected $fields =
    array(
        'id' => 'key',
        'key' => 'longstring',
        'value' => 'longstring',
    );

    /**
     * Get all configurations from database OR session if it was yet loaded
     * This function is called at start of program and global var '$conf' is filled with response, so use global $conf instead of call this function.
     * #### Example
     * ```php
     * $confs = Configuration::getAll();
     * var_dump($confs);
     * ```.
     * @return array Array of configurations
     */
    public function getAll()
    {
        if (!isset($_SESSION['configuration'])) {
           
            $configurationManager = new self();
            $configs = $configurationManager->loadAll();
            $confTab = array();

            foreach ($configs as $config) {
                $this->confTab[$config->key] = decrypt($config->value);
            }

            $_SESSION['configuration'] = serialize($this->confTab);
        } else {
            $this->confTab = unserialize($_SESSION['configuration']);
        }
    }

    //Définit / récupere un set de configurations générique
    public static function setting($name,$settings=null){
        if(!isset($settings)) return isset($GLOBALS['setting'][$name]) ? $GLOBALS['setting'][$name] : array();
        $GLOBALS['setting'][$name] = $settings; 
    }

    //Met en page (tableau html) un set de configuration générique
    public static function html($name){
        global $conf;
        $options = $GLOBALS['setting'][$name]; ?>

        <table id="<?php echo $name; ?>-setting-form" class="table table-striped">
            <tbody>
                <?php foreach($options as $key=>$infos): ?>
                    <?php
                        $input = '';
                     if(!is_array($infos)): ?>
                    <tr><th colspan="2"><h4 class="m-0"><i class="fas fa-angle-right"></i> <?php echo $infos;?></h4></th></tr>
                    <?php continue; endif; ?>
                    <tr>
                        <th class="align-middle"><?php echo $infos['label']; ?>
                            <?php if (isset($infos['legend'])): ?>
                            <small class="text-muted"> - <?php echo $infos['legend']; ?></small>
                            <?php endif; ?>
                        </th>
                        
                        <td class="align-middle position-relative">
                            <?php $attributes = array();
                            if(isset($infos['placeholder'])) $attributes[] = 'placeholder="'.$infos['placeholder'].'"';
                            $attributes['class'] = 'class="form-control"';
                            $attributes[] = 'id="'.$key.'"';
                            $attributes['value'] = 'value="'.htmlentities($conf->get($key)).'"';

                            if(isset($infos['parameters'])){
                                foreach($infos['parameters'] as $attribute=>$parameter){
                                    if(isset($attributes[$attribute])) continue;
                                    $attributes[$attribute] = $attribute.'="'.$parameter.'"';
                               }
                            }
                            
                            switch($infos['type']){
                                case 'password':
                                    $attributes['type'] = 'data-type="password"';
                                    $input = '<input type="text" '.implode(' ',$attributes).' >'; 
                                break;
                                case 'dictionnary':
                                    $attributes['type'] = 'data-type="dictionnary"';
                                    $attributes['parameters'] = 'data-slug="'.$infos['slug'].'"';
                                    $input = '<select type="text" '.implode(' ',$attributes).' >'; 
                                break;
                                case 'checkbox':
                                    unset($attributes['class']);
                                    unset($attributes['value']);
                                    $attributes['type'] = 'data-type="checkbox"';
                                    if($conf->get($key)) $attributes['value'] = 'checked="checked"';
                                    $input = '<label class="mb-0 pointer no-select"><input type="checkbox" '.implode(' ',$attributes).' > Activer</label>'; 
                                break;
                                case 'select':
                                    unset($attributes['value']);

                                    $input = '<select '.implode(' ',$attributes).'>'; 
                                    foreach($infos['values'] as $id=>$label)
                                        $input .= '<option value="'.$id.'" '.($id==$conf->get($key)?'selected="selected"':'').' type="checkbox">'.$label.'</option>'; 
                                    $input .= '</select>'; 
                                break;
                               case 'user':
                                    $attributes['data-type'] = 'data-type="user"';
                                    $input = '<input type="text" '.implode(' ',$attributes).'>'; 
                                break;
                                case 'rank':
                                    $attributes['data-type'] = 'data-type="user" data-types="rank"';
                                    $input = '<input type="text" '.implode(' ',$attributes).'  >'; 
                                 break;
                                case 'number':
                                    $input = '<input type="number" onkeydown="return input_number_control(event,true,true);" '.implode(' ',$attributes).' >';
                                break;
                                case 'hour':
                                    $input = '<input type="text" data-type="hour" '.implode(' ',$attributes).' >';
                                break;
                                 case 'date':
                                    $input = '<input type="text" data-type="date" '.implode(' ',$attributes).' >';
                                break;
                                case 'textarea':
                                    $input = '<textarea '.implode(' ',$attributes).' >'.htmlentities($conf->get($key)).'</textarea>';
                                break;
                                case 'file':
                                    $input = '<input type="file" '.implode(' ',$attributes).' >';
                                break;
                                default:
                                    Plugin::callHook('configuration_fields',array(&$input, $infos, $attributes));
                                    if(empty($input)) $input = '<input type="text" '.implode(' ',$attributes).' >';
                                break;
                            }
                            echo $input; ?>
                        </td>
                    </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
        <?php
    }

    /**
     * Get configuration value from it key
     * #### Example
     * ```php
     * global $conf; // global var, contain configurations
     * echo $conf->get('myConfigKey'); // print myConfigKey value
     * ```.
     * @param string configuration key
     * @param string configuration namespace (default is 'conf')
     *
     * @return string valeur de la configuration
     */
    public function get($key)
    {
        return isset($this->confTab[$key]) ? $this->confTab[$key] : '';
    }

    /**
     * Update or insert configuration value in database with specified key
     * #### Example
     * ```php
     * global $conf; // global var, contain configurations
     * echo $conf->put('myNewConfigKey','hello!'); //create configuration myNewConfigKey with value 'hello!'
     * echo $conf->put('myNewConfigKey','hello 2!'); //update configuration myNewConfigKey with value 'hello2!'
     * ```.
     *
     * @param string configuration key
     * @param string configuration value
     * @param string configuration namespace (default is 'conf')
     */
    public function put($key, $value)
    {
        $secured_value = encrypt($value);
        $configurationManager = new self();
        if (isset($this->confTab[$key])) {
            $configurationManager->change(array('value' => $secured_value), array('key' => $key));
        } else {
            $configurationManager->add($key, $secured_value);
        }
        $this->confTab[$key] = $value;
        unset($_SESSION['configuration']);
    }

    /**
     * Remove configuration value in database with specified key
     * #### Example
     * ```php
     * global $conf; // global var, contain configurations
     * echo $conf->remove('myNewConfigKey'); //delete myNewConfigKey from 'conf' default namespace 
     * echo $conf->remove('myNewConfigKey','myCustomPluginConfig'); //delete myNewConfigKey from 'myCustomPluginConfig' namespace
     * ```.
     *
     * @param string configuration key
     * @param string configuration namespace (default is 'conf')
     */
    public function add($key, $value)
    {
        $config = new self();
        $config->key = $key;
        $config->value = $value;
        $config->save();
        $this->confTab[$key] = $value;
        unset($_SESSION['configuration']);
    }


}