<?php
namespace model;

class database {
    
    private $pdo = null, $table, $where, $order, $limit, $prepare;
    
    public function __construct() {
        if ($this->pdo == null) {
            try {
                $this->pdo = new \PDO('mysql:host='.$GLOBALS['config']['database']['host'].';dbname='.$GLOBALS['config']['database']['database'],
                    $GLOBALS['config']['database']['username'], $GLOBALS['config']['database']['password'], [\PDO::ATTR_PERSISTENT => true]);
            } catch (PDOException $e) {
                exit('Error: ' . $e->getMessage());
            }
        }
        
        $this->table = null;
        $this->where = [];
        $this->order = '';
        $this->limit = '';
        $this->prepare = '';
    }
    
    public function table(string $table) {
        $this->table = $table;
        return $this;
    }
    
    public function where(array $where) {
        $this->where = array_merge($this->where, $where);
        return $this;
    }
    
    public function like($name, $word) {
        $this->order = ' where `'.$name.'` like "%'.$word.'%"';
        return $this;
    }
    
    public function group_by($name) {
        $this->order = ' group by `'.$name.'`';
        return $this;
    }
    
    public function select($select = null) {
        $this->prepare_where();
        
        if (is_array($select)) {
            $select = '`'.implode('`, `', $select).'`';
        } elseif ($select == 'count(*)') {
            $select = 'count(*)';
        } elseif (!empty($select)) {
            $select = '`'.$select.'`';
        } else {
            $select = '*';
        }
        
        $db = $this->pdo->prepare("select $select from `$this->table`$this->where$this->order$this->limit");
        $db->execute($this->prepare);
        if ($db = $db->fetchAll(\PDO::FETCH_ASSOC))
            return count($db) > 1 ? $db : $db[0];
        else return false;
    }
    
    public function insert(array $data) {
        if (count($data) > 1) {
            $keys = '`'.implode('`, `', array_keys($data)).'`';
            foreach ($data as $v) $values[] = '?';
            $values = implode(', ', $values);
        } else {
            $keys = '`'.array_keys($data)[0].'`';
            $values = '?';
        }
        
        $db = $this->pdo->prepare("insert into `$this->table`($keys) values($values)");
        return $db->execute(array_values($data));
    }
    
    public function update(array $data) {
        $this->prepare_where();
        
        if (count($data) > 1) {
            $update = '`'.implode('` = ?, `', array_keys($data)).'` = ?';
        } else {
            $update = '`'.array_keys($data)[0].'` = ?';
        }
        
        $db = $this->pdo->prepare("update `$this->table` set $update$this->where");
        return $db->execute(array_merge(array_values($data), $this->prepare));
    }
    
    public function delete() {
        $this->prepare_where();
        
        $db = $this->pdo->prepare("delete from `$this->table`$this->where");
        return $db->execute($this->prepare);
    }
    
    public function count() {
        return $this->select('count(*)')['count(*)'];
    }
    
    public function last($last) {
        $this->order = ' order by `'.$last.'` desc';
        $this->limit = ' limit 1';
        return $this->select();
    }
    
    public function page(int $limit, int $page) {
        $this->limit = ' limit '.($page-1)*$limit.', '.$limit;
        return $this->select();
    }
    
    public function pdo_query($sql) {
        $db = $this->pdo->query($sql);
        if ($db = $db->fetchAll(\PDO::FETCH_ASSOC))
            return count($db) > 1 ? $db : $db[0];
        else return false;
    }
    
    public function pdo_prepare($sql) {
        $this->prepare = $sql;
        return $this;
    }
    
    public function execute($arr) {
        $db = $this->pdo->prepare($this->prepare);
        $db->execute($arr);
        if ($db = $db->fetchAll(\PDO::FETCH_ASSOC))
            return count($db) > 1 ? $db : $db[0];
        else return false;
    }
    
    private function prepare_where() {
        $where = '';
        $this->prepare = [];
        if (!empty($this->where) && is_array($this->where)) {
            $where = ' where ';
            if (count($this->where) > 1) {
                $where .= '`'.implode('` = ? and `', array_keys($this->where)).'` = ?';
            } else $where .= '`'.array_keys($this->where)[0].'` = ?';
            $this->prepare = array_values($this->where);
        }
        $this->where = $where;
    }
}
