<?php
declare(strict_types=1);

require_once("config.inc.php");

class DBConnector
{
    private string $server;
    private string $userName;
    private string $password;
    private string $database;
    private ?PDO $con = null;

    public function __construct()
    {
        $this->server = DB_SERVER;
        $this->userName = DB_USER_NAME;
        $this->password = DB_PASSWORD;
        $this->database = DB_DATABSE;
        
        $this->OpenConnection();
    }

    public function OpenConnection(): void
    {
        if ($this->con === null) {
            $dsn = "mysql:host={$this->server};dbname={$this->database};charset=utf8mb4";
            $options = [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_EMULATE_PREPARES => false,
                PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci, FILE_USAGE 'None', SQL_MODE='STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'"
            ];
            
            try {
                $this->con = new PDO($dsn, $this->userName, $this->password, $options);
            } catch (PDOException $e) {
                // In production, log this, don't echo raw error
                error_log("Connection failed: " . $e->getMessage());
                throw new Exception("Database connection failed.");
            }
        }
    }

    // Modern replacement for query execution with binding
    public function RunQuery(string $sql, array $params = []): PDOStatement
    {
        try {
            $stmt = $this->con->prepare($sql);
            $stmt->execute($params);
            return $stmt;
        } catch (PDOException $e) {
            error_log("Query failed: " . $e->getMessage() . " SQL: " . $sql);
            throw new Exception("Database query failed.");
        }
    }

    // Helper to fetch all rows easily
    public function FetchAll(string $sql, array $params = []): array
    {
        return $this->RunQuery($sql, $params)->fetchAll();
    }

    // Replacement for ExecuteQuery (Insert/Update/Delete) return bool or count
    public function ExecuteQuery(string $sql, array $params = []): bool
    {
        try {
            $stmt = $this->con->prepare($sql);
            return $stmt->execute($params);
        } catch (PDOException $e) {
            error_log("Execution failed: " . $e->getMessage() . " SQL: " . $sql);
            throw new Exception("Database operation failed.");
        }
    }

    // Replacement for CheckRecordAvailability
    public function CheckRecordAvailability(string $sql, array $params = []): bool
    {
        $stmt = $this->RunQuery($sql, $params);
        return $stmt->rowCount() > 0; // Note: rowCount works for SELECT in MySQL usually, but fetchColumn is safer for portable count(*)
    }

    // Replacement for AutoIncrementExecuteQuery
    public function AutoIncrementExecuteQuery(string $sql, array $params = []): int
    {
        $this->ExecuteQuery($sql, $params);
        return (int)$this->con->lastInsertId();
    }
    
    // Helper to get underlying connection if needed (legacy escape, etc - though should be avoided)
    public function GetConnection(): PDO
    {
        return $this->con;
    }

    public function CloseConnection(): void
    {
        $this->con = null;
    }
}
?>

