<?php
namespace Core;

use PDO;
use PDOException;

/**
 * Singleton Database Wrapper
 * Handles secure PDO connections and simple prepared statements execution
 */
class Database {
    private static $instance = null;
    private $pdo;

    private function __construct() {
        // Load configuration
        $config = require __DIR__ . '/../config/database.php';
        
        $dsn = "{$config['driver']}:host={$config['host']};dbname={$config['db_name']};charset={$config['charset']}";
        
        // Secure options
        $options = [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ, // Fetch as Objects
            PDO::ATTR_EMULATE_PREPARES   => false,          // Native prepares prevent SQL Injection
        ];

        try {
            $this->pdo = new PDO($dsn, $config['user'], $config['pass'], $options);
        } catch (PDOException $e) {
            // Auto install database if missing (1049 Unknown database)
            if ($e->getCode() == 1049) {
                die("عذراً، قاعدة البيانات ( {$config['db_name']} ) غير موجودة. لأسباب أمنية، تم إيقاف التثبيت التلقائي في بيئة الإنتاج. يرجى إنشاء قاعدة البيانات واستيراد ملف otis_full_schema.sql يدوياً.");
            }
            
            error_log("Database Connection Error: " . $e->getMessage());
            die("نعتذر، فشل الاتصال بقاعدة البيانات. (يُرجى التأكد من تشغيل XAMPP MySQL وأن بيانات الاتصال صحيحة). رسالة الخطأ: " . htmlspecialchars($e->getMessage()));
        }
    }

    /**
     * Singleton instance pattern
     * Ensures only one database connection runs at a time
     */
    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Get the active PDO instance
     */
    public function getConnection() {
        return $this->pdo;
    }

    /**
     * Alias for getConnection() — returns raw PDO for transactions
     */
    public function getPDO(): \PDO {
        return $this->pdo;
    }

    /**
     * Helper to execute queries with prepared statements safely
     * Example: query("SELECT * FROM users WHERE email = ?", [$email])
     */
    public function query($sql, $params = []) {
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute($params);
        return $stmt;
    }

    /**
     * Get last inserted ID (auto-increment)
     */
    public function lastInsertId() {
        return $this->pdo->lastInsertId();
    }

    /**
     * Prevent clone
     */
    private function __clone() {}
}
