<?php

namespace Hura8\System\Model;


use Hura8\Database\iConnectDB;
use Hura8\System\Security\DataClean;
use Hura8\System\Security\DataType;

class SettingModel
{

    protected  $db;

    protected $tb_setting = 'tb_settings';

    const KEY = [
        'pcbuilder_config' => 'pcbuilder_config',
    ];


    public function __construct(){
        $this->db = get_db('', ENABLE_DB_DEBUG);
    }


    public function getAll(){
        $query = $this->db->runQuery(
            "SELECT * FROM `".$this->tb_setting."`  WHERE 1 ORDER BY `id` DESC LIMIT 100 "
        );

        $result = [];
        foreach ( $this->db->fetchAll($query) as $rs ){
            if($rs['setting_value']) {
                $rs['setting_value'] = \unserialize($rs['setting_value']);
            }

            $result[] = $rs;
        }

        return $result;
    }


    // get a list of keys
    public function getList(array $keys){
        $conditions = [];
        $bind_types = [];
        $bind_values = [];

        foreach ($keys as $key) {
            $conditions[] = " `setting_key`= ? ";
            $bind_types[] = 's';
            $bind_values[] = $key;
        }

        if(sizeof($conditions)) {
            $query = $this->db->runQuery(
                " SELECT `setting_key`, `setting_value` FROM `".$this->tb_setting."` WHERE ".join(" OR ", $conditions)." LIMIT 100 ",
                $bind_types, $bind_values
            );

            $result = [];
            foreach ( $this->db->fetchAll($query) as $rs ){
                $result[$rs['setting_key']] = \unserialize($rs['setting_value']);
            }

            return $result;
        }

        return [];
    }


    // get a single key, = false if not found and no default is set
    public function get($key, $default = null){
        $key = $this->cleanKey($key);
        if(!$key) return null;

        $query = $this->db->runQuery(
            "SELECT `setting_value` FROM `".$this->tb_setting."` WHERE `setting_key`= ? LIMIT 1 ",
            ['s'], [ $key ]
        );

        if($rs = $this->db->fetchAssoc($query)){
            return \unserialize($rs['setting_value']);
        }

        return ($default) ?: null;
    }


    public function delete($key){
        return $this->db->runQuery(
            "DELETE FROM `" . $this->tb_setting . "` WHERE `setting_key` = ? LIMIT 1 ",
            ['s'], [ $key ]
        );
    }


    // update or create
    public function updateOrCreate($key, $value = null, $comment = ''){
        $key = $this->cleanKey($key);
        if(!$key) return false;

        if($this->checkKeyExist($key)) {
            return $this->db->update(
                $this->tb_setting ,
                [
                    'setting_value' => ($value) ? \serialize($value) : null,
                    'comment' => subString($comment, 80),
                    'last_update' => CURRENT_TIME,
                    'last_update_by' => ADMIN_NAME,
                ],
                [
                    'setting_key' => $key,
                ]
            );
        }

        return $this->db->insert(
            $this->tb_setting ,
            [
                'setting_key' => $key,
                'setting_value' => ($value) ? \serialize($value) : null,
                'comment' => subString($comment, 80),
                'create_time' => CURRENT_TIME,
                'create_by' => ADMIN_NAME,
                'last_update' => CURRENT_TIME,
                'last_update_by' => ADMIN_NAME,
            ]
        );
    }


    public function populateKeys(array $key_list) {
        $build_inserts = [];
        foreach ($key_list as $key) {
            if( ! $this->checkKeyExist($key)) {
                $build_inserts[] = [
                    "setting_key" => $key,
                    "create_time" => CURRENT_TIME,
                    "create_by" => 'system',
                ];
            }
        }

        if(sizeof($build_inserts)) {
            $this->db->insert($this->tb_setting, $build_inserts);
        }

        return sizeof($build_inserts);
    }


    protected function checkKeyExist($key) : bool {
        $key = $this->cleanKey($key);
        if(!$key) return false;

        $query = $this->db->runQuery(
            "  SELECT `id` FROM `".$this->tb_setting."`  WHERE `setting_key`= ?  LIMIT 1 ", ['s'], [ $key ]
        );

        return (bool) $this->db->fetchAssoc($query);
    }


    // only allow some characters
    protected function cleanKey($key) {
        return DataClean::makeInputSafe($key, DataType::ID);
    }

}
