<?php

class Database {
	private $mysqli;

	function __construct($server, $user, $password, $name){
		$this->openConnection($server, $user, $password, $name);
	}

	private function openConnection($server, $user, $password, $name){
		$this->mysqli = new mysqli($server, $user, $password, $name);

		if($this->mysqli->connect_error){
            trigger_error('Database connection failed!', E_USER_ERROR);
		}
		if (!$this->mysqli->set_charset("utf8")) {
		    trigger_error('Error loading character set '.$mysqli->error, E_USER_ERROR);
		}
	}
	public function closeConnection(){
		if(isset($this->mysqli)){
			$closeResult = $this->mysqli->close();
			if($closeResult === false){
				trigger_error('Cannot close MySQL connection!', E_USER_ERROR);
			}
		}
	}

	public function query($sql){
		$result= $this->mysqli->query($sql) ;

		if(!$result){
			$err_mes = 'Database query failed on line '.__LINE__.'  in file '.__FILE__.'!<br/>';
			$err_mes .= 'SQL: <span class="notice"><pre>'.$sql.'</pre></span><br/>';
			$err_mes .= 'Error: <span class="error">'.$this->mysqli->error.'</span>';
			var_dump(debug_backtrace());
			trigger_error($err_mes, E_USER_ERROR);
		}

		return $result;
	}

	public function escapeValue($value){
		$value=$this->mysqli->real_escape_string($value);

		return $value;
	}

	public function prepare($sql){
		$query = $this->mysqli->prepare($sql);

		if(!$query) {
			$err_mes = 'Database query failed on line '.__LINE__.'  in file '.__FILE__.'!<br/>';
	  		$err_mes .= 'SQL: <span class="notice"><pre>'.$sql.'</pre></span><br/>';
	  		$err_mes .= 'Error: <span class="error">'.$this->mysqli->error.'</span>';
	  		var_dump(debug_backtrace());
	  		trigger_error($err_mes, E_USER_ERROR);
		}

		return $query;
	}

	public function fetchArray($result_set){
		return $result_set->fetch_array(MYSQLI_ASSOC);
	}

	public function fetchResultArray($sql){
		$query = $this->query($sql);
        $data = [];

        while($row = $this->fetchArray($query)){
            array_push($data, $row);
        }

		if($query){
				$query->close();
		}

		return $data;
	}

	public function numRows($result_set){
		return $result_set->num_rows;
	}

	public function affectedRows(){
		return $this->mysqli->affected_rows;
	}

	public function getInsertId(){
		return $this->mysqli->insert_id;
	}

	public function closeQuery($query){
		if($query){
			var_dump($query);
			$query->close();
		}
	}

	public function beginTransaction($mode = MYSQLI_TRANS_START_READ_WRITE){
		return	$this->mysqli->begin_transaction();
	}

	public function commit(){
		return $this->mysqli->commit();
	}

	public function rollback(){
		return $this->mysqli->rollback();
	}

	/**
     * check if empty value
     * @param  String  $key   key for translation
     * @param  String| INT| FLOAT  $value value to be checked
     * @return array       error message array or null if passed
     */
    public function isEmpty($key, $value){
        $err_mes = null;

        if($value === '' || $value === null){
            $err_mes = [
                'code' => 'error',
                'message' => 'EMPTY_VALUE',
                'key' => $key
            ];
        }

        return $err_mes;
    }

	/**
     * check lenght for value
     * @param  String  $key   key for translation
     * @param  String| INT| FLOAT  $value value to be checked
     * @param  INT $maxChars    maximum chatacters
     * @return array       error message array or null if passed
     */
    public function invalidLength($key ,$value, $maxChars){
        $err_mes = null;
		
        if(strlen($value) > $maxChars){
            $err_mes = [
                'code' => 'error',
                'message' => 'MAX_CHARACTERS',
                'key' => $key
            ];
        }

        return $err_mes;
    }

	 /**
     * check if number is to big or to low
     * @param  String  $key   key for translation
     * @param  INT| FLOAT  $value value to be checked
     * @param  INT $min   minimum value to cehck
     * @param  INT $max   maximum value to cehck
     * @return array       error message array or null if passed
     */
    public function invalidNumber($key, $value, $min, $max){
        $err_mes = null;
		$value = filter_var($value, FILTER_VALIDATE_FLOAT);

        if(($value < $min || $value > $max) || $value === false){
            $err_mes = [
                'code' => 'error',
                'message' => 'INVALID_NUMBER',
                'key' => $key
            ];
        }

        return $err_mes;
    }

	public function invalidDate($key, $value, $delimiter = '-'){
		$err_mes = [
			'code' => 'error',
			'message' => 'INVALID_DATE',
			'key' => $key
		];

		$dateValues = explode($delimiter, $value);

		if(count($dateValues) !== 3){
			return $err_mes;
		}

		if(!checkdate($dateValues[1], $dateValues[2], $dateValues[0])){
			return $err_mes;
		}

		return null;
	}

}
