<?php
namespace App\Models;

class Access extends \Core\Model
{
    public function __construct()
    {
        $this->createTable(
            [
                'id int(3) NOT NULL AUTO_INCREMENT',
                'username varchar(25) NOT NULL',
                'password char(13) NOT NULL',
                'salt char(23) NOT NULL',
                'full_name varchar(50) NOT NULL',
                'registered_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP',
                'privilege tinyint(1) NOT NULL DEFAULT 0',
                'max_user int(1) NOT NULL DEFAULT 5',
                'PRIMARY KEY (id)'
            ]
        );
    }

    protected function createTable($fields, $table = 'users') {
        try {
            if ($fields == []) {
                return false;
            }
            $sql = "CREATE TABLE IF NOT EXISTS {$table} (".implode(',', $fields).") ENGINE=InnoDB DEFAULT CHARSET=utf8;";

            $db = static::connectDB();
            $query = $db->prepare($sql);

            $query->execute();
            return true;
        } catch (PDOException $e) {
            throw new \Exception($e->getMessage(), 444);
        }
    }

    protected function dropTable($table = 'users') {
        try {
            $sql = "DROP TABLE IF EXISTS {$table}";

            $db = static::connectDB();
            $query = $db->prepare($sql);
            $query->execute();
            return true;
        } catch (PDOException $e) {
            throw new \Exception($e->getMessage(), 444);
        }
    }

    public function showAll($conditions = [], $table = 'users')
    {
        try {
            $db = static::connectDB();

            $sql = "SELECT * FROM {$table}";

            if ($conditions) {
                $sql .= " WHERE";
                foreach ($conditions as $condition) {

                    $keys[] = $condition[0];
                    $operators[] = $condition[1];
                    $values[] = $condition[2];
                }

                $x = 0;
                foreach ($keys as $key) {
                    $sql .= " $key $operators[$x] ?";
                    $x++;
                    if ($x < count($keys)) {
                        $sql .= " AND";
                    }
                }
            }

            $query = $db->prepare($sql);

            if (count($conditions)) {
                $x = 1;
                foreach ($values as $value) {
                    $query->bindValue($x, $value);
                    $x++;
                }
            }

            $query->execute();
            if ($query->rowCount() == 1) {
                $result = $query->fetch(\PDO::FETCH_ASSOC);
            } elseif ($query->rowCount() > 1) {
                $result = $query->fetchAll(\PDO::FETCH_ASSOC);
            } else {
                return false;
            }
            return $result;
        } catch (PDOException $e) {
            throw new \Exception($e->getMessage, 444);
        }
    }

    public function entry($args, $table = 'users')
    {
        if (count($args)) {
            $keys = '`'.implode('`, `', array_keys($args)).'`';
            $values = '';

            // This is if want to insert multiple rows
            foreach ($args as $key => $val) {
                if (preg_match('/,/', $val)) {
                    $val = explode(',', $val);
                    $args[$key] = $val;
                }
            }

            $x = 1;
            foreach ($args as $field) {
                // Setting the query for multiple rows
                if (is_array($field)) {
                    foreach ($field as $fields) {
                        $values .= '(?)';
                        if ($x < count($field)) {
                            $values .= ', ';
                        }
                        $x++;
                    }
                } else {
                    if ($x === 1) {
                        $values .= '(';
                    }
                    $values .= '?';
                    if ($x < count($args)) {
                        $values .= ', ';
                    } else {
                        $values .= ')';
                    }
                    $x++;
                }
            }

            try {
                $sql = "INSERT INTO {$table} ({$keys}) VALUES {$values}";

                $db = static::connectDB();

                $query = $db->prepare($sql);

                $x = 1;
                foreach ($args as $value) {
                    if (is_array($value)) {
                        foreach ($value as $vals) {
                            $query->bindValue($x, $vals);
                            $x++;
                        }
                    } else {
                        $query->bindValue($x, $value);
                        $x++;
                    }
                }

                $query->execute();
                return true;
            } catch (PDOException $e) {
                throw new \Exception($e->getMessage(), 444);
            }
        }
        return false;
    }

    public function update($args, $id, $table = 'users')
    {
        if (count($args)) {
            $keys = array_keys($args);

            $fields = [];
            foreach ($keys as $key) {
                $fields[] = $key.' = ?';
            }

            if (count($fields) > 1) {
                $fields = implode(', ', $fields);
            } else {
                $fields = implode('', $fields);
            }

            try {
                $db = static::connectDB();

                $result = $this->showAll([
                    ['id', '=', $id]
                ]);

                $sql = "UPDATE {$table} SET {$fields} WHERE id = ?";

                $query = $db->prepare($sql);
                $x = 1;
                foreach ($args as $value) {
                    $query->bindValue($x, $value);
                    $x++;
                }
                $query->bindValue($x, $id);

                $query->execute();
                return true;
            } catch (PDOException $e) {
                throw new \Exception($e->getMessage(), 444);
            }
        }
        return false;
    }

    public function delete($id, $status, $table = 'users')
    {
        try {
            $db = static::connectDB();

            $sql = "UPDATE {$table} SET status = ? WHERE id = ?";

            $query = $db->prepare($sql);
            $query->bindValue(1, $status);
            $query->bindValue(2, $id);

            $query->execute();
            return true;
        } catch (PDOException $e) {
            throw new \Exception($e->getMessage(), 444);
        }
    }
}
