<?php
/**
 * فئة قاعدة البيانات
 * تتعامل مع الاتصال بقاعدة البيانات وتنفيذ الاستعلامات
 *
 * @version 1.0
 * @author فريق التطوير
 */

namespace App\Core;

use PDO;
use PDOException;

class Database {
    private $host;
    private $dbname;
    private $username;
    private $password;
    private $conn;
    private $use_mysql;
    private $sqlite_file;
    private static $instance;

    /**
     * إنشاء كائن قاعدة البيانات
     */
    private function __construct() {
        // استيراد إعدادات قاعدة البيانات من ملف التكوين
        $config = require_once dirname(__DIR__, 2) . '/config/database.php';
        
        $this->host = $config['db_host'];
        $this->dbname = $config['db_name'];
        $this->username = $config['db_user'];
        $this->password = $config['db_pass'];
        $this->use_mysql = $config['use_mysql'];
        $this->sqlite_file = $config['sqlite_db_file'];
        
        $this->connect();
    }

    /**
     * الحصول على نسخة واحدة من الفئة (نمط Singleton)
     */
    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * إنشاء اتصال بقاعدة البيانات
     */
    private function connect() {
        try {
            if ($this->use_mysql) {
                // استخدام MySQL
                $this->conn = new PDO(
                    "mysql:host={$this->host};dbname={$this->dbname};charset=utf8mb4",
                    $this->username,
                    $this->password
                );
                
                // ضبط خيارات PDO
                $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                $this->conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
                $this->conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
                
                // ضبط الترميز لدعم اللغة العربية بشكل صحيح
                $this->conn->exec("SET NAMES utf8mb4");
                $this->conn->exec("SET CHARACTER SET utf8mb4");
                $this->conn->exec("SET collation_connection = utf8mb4_unicode_ci");
            } else {
                // استخدام SQLite
                // التأكد من وجود مجلد قاعدة البيانات
                $db_dir = dirname($this->sqlite_file);
                if (!file_exists($db_dir)) {
                    mkdir($db_dir, 0777, true);
                }
                
                // إنشاء اتصال SQLite
                $this->conn = new PDO("sqlite:{$this->sqlite_file}");
                
                // ضبط خيارات PDO
                $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                $this->conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
            }
        } catch (PDOException $e) {
            // تسجيل الخطأ في سجل الأخطاء
            error_log("خطأ في الاتصال بقاعدة البيانات: " . $e->getMessage());
            throw new PDOException("فشل الاتصال بقاعدة البيانات: " . $e->getMessage());
        }
    }

    /**
     * الحصول على كائن الاتصال
     */
    public function getConnection() {
        return $this->conn;
    }

    /**
     * تنفيذ استعلام وإرجاع النتيجة
     */
    public function query($sql, $params = []) {
        try {
            $stmt = $this->conn->prepare($sql);
            $stmt->execute($params);
            return $stmt;
        } catch (PDOException $e) {
            error_log("خطأ في تنفيذ الاستعلام: " . $e->getMessage());
            throw new PDOException("فشل تنفيذ الاستعلام: " . $e->getMessage());
        }
    }

    /**
     * الحصول على سجل واحد
     */
    public function fetchOne($sql, $params = []) {
        $stmt = $this->query($sql, $params);
        return $stmt->fetch();
    }

    /**
     * الحصول على جميع السجلات
     */
    public function fetchAll($sql, $params = []) {
        $stmt = $this->query($sql, $params);
        return $stmt->fetchAll();
    }

    /**
     * الحصول على قيمة واحدة
     */
    public function fetchColumn($sql, $params = [], $column = 0) {
        $stmt = $this->query($sql, $params);
        return $stmt->fetchColumn($column);
    }

    /**
     * إدراج سجل جديد
     */
    public function insert($table, $data) {
        $columns = implode(', ', array_keys($data));
        $placeholders = implode(', ', array_fill(0, count($data), '?'));
        
        $sql = "INSERT INTO {$table} ({$columns}) VALUES ({$placeholders})";
        
        $this->query($sql, array_values($data));
        return $this->conn->lastInsertId();
    }

    /**
     * تحديث سجل
     */
    public function update($table, $data, $where, $whereParams = []) {
        $set = [];
        foreach (array_keys($data) as $column) {
            $set[] = "{$column} = ?";
        }
        $setClause = implode(', ', $set);
        
        $sql = "UPDATE {$table} SET {$setClause} WHERE {$where}";
        
        $params = array_merge(array_values($data), $whereParams);
        $this->query($sql, $params);
        
        return true;
    }

    /**
     * حذف سجل
     */
    public function delete($table, $where, $params = []) {
        $sql = "DELETE FROM {$table} WHERE {$where}";
        $this->query($sql, $params);
        
        return true;
    }

    /**
     * بدء معاملة
     */
    public function beginTransaction() {
        return $this->conn->beginTransaction();
    }

    /**
     * تأكيد معاملة
     */
    public function commit() {
        return $this->conn->commit();
    }

    /**
     * التراجع عن معاملة
     */
    public function rollback() {
        return $this->conn->rollBack();
    }
}
