<?php
// includes/db.php

class Database {
    private $host = DB_HOST;
    private $db_name = DB_NAME;
    private $username = DB_USER;
    private $password = DB_PASS;
    private $conn;
    private $stmt;
    private $error;
    
    public function __construct() {
        $dsn = "mysql:host={$this->host};dbname={$this->db_name};charset=utf8mb4";
        $options = [
            PDO::ATTR_PERSISTENT => true,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES => false
        ];
        
        try {
            $this->conn = new PDO($dsn, $this->username, $this->password, $options);
        } catch(PDOException $e) {
            $this->error = $e->getMessage();
            error_log("Erro de conexão com banco de dados: " . $this->error);
            throw new Exception("Erro de conexão com banco de dados");
        }
    }
    
    // Prepara a query
    public function query($sql) {
        $this->stmt = $this->conn->prepare($sql);
    }
    
    // Bind de valores
    public function bind($param, $value, $type = null) {
        if(is_null($type)) {
            switch(true) {
                case is_int($value):
                    $type = PDO::PARAM_INT;
                    break;
                case is_bool($value):
                    $type = PDO::PARAM_BOOL;
                    break;
                case is_null($value):
                    $type = PDO::PARAM_NULL;
                    break;
                default:
                    $type = PDO::PARAM_STR;
            }
        }
        
        $this->stmt->bindValue($param, $value, $type);
    }
    
    // Executa a query
    public function execute() {
        try {
            return $this->stmt->execute();
        } catch(PDOException $e) {
            $this->error = $e->getMessage();
            error_log("Erro na execução da query: " . $this->error);
            throw new Exception("Erro na execução da query");
        }
    }
    
    // Retorna múltiplos registros
    public function resultSet() {
        $this->execute();
        return $this->stmt->fetchAll();
    }
    
    // Retorna um único registro
    public function single() {
        $this->execute();
        return $this->stmt->fetch();
    }
    
    // Retorna o número de linhas afetadas
    public function rowCount() {
        return $this->stmt->rowCount();
    }
    
    // Retorna o último ID inserido
    public function lastInsertId() {
        return $this->conn->lastInsertId();
    }
    
    // Inicia uma transação
    public function beginTransaction() {
        return $this->conn->beginTransaction();
    }
    
    // Commit da transação
    public function commit() {
        return $this->conn->commit();
    }
    
    // Rollback da transação
    public function rollback() {
        return $this->conn->rollBack();
    }
    
    // Verifica se uma tabela existe
    public function tableExists($table) {
        try {
            $result = $this->conn->query("SHOW TABLES LIKE '{$table}'");
            return $result->rowCount() > 0;
        } catch(PDOException $e) {
            return false;
        }
    }
    
    // Debug da query
    public function debugDumpParams() {
        return $this->stmt->debugDumpParams();
    }
    
    // Retorna o erro
    public function getError() {
        return $this->error;
    }
    
    // Retorna a conexão PDO
    public function getConnection() {
        return $this->conn;
    }
    
    // Verifica se está em transação
    public function inTransaction() {
        return $this->conn->inTransaction();
    }
}

// Instancia a conexão global
$db = new Database();