<?php
/**
 * Enhanced Configuration File
 * Global, Secure, and Optimized Settings
 * 
 * @version 2.0
 * @author Enhanced Development Team
 */

// Security Headers - Enhanced Protection
if (!headers_sent()) {
    // Prevent clickjacking
    header('X-Frame-Options: SAMEORIGIN');
    // Prevent MIME type sniffing
    header('X-Content-Type-Options: nosniff');
    // Enable XSS protection
    header('X-XSS-Protection: 1; mode=block');
    // Referrer policy
    header('Referrer-Policy: strict-origin-when-cross-origin');
    // Content Security Policy (adjust as needed)
    header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://maps.googleapis.com https://cdn.jsdelivr.net https://cdn.sheetjs.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https://maps.googleapis.com https://api.mapbox.com;");
}

// Enhanced Session Configuration
if (session_status() == PHP_SESSION_NONE) {
    // إعدادات الجلسة المحسّنة للأمان والأداء
    ini_set('session.gc_maxlifetime', 28800); // 8 ساعات
    ini_set('session.cookie_lifetime', 28800);
    
    // Enhanced security settings
    $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || 
               (!empty($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443);
    
    session_set_cookie_params([
        'lifetime' => 28800,
        'path' => '/',
        'domain' => '',
        'secure' => $isHttps, // Secure cookies in HTTPS
        'httponly' => true, // Prevent JavaScript access
        'samesite' => 'Strict' // CSRF protection
    ]);
    
    ini_set('session.use_strict_mode', 1); // منع هجمات تثبيت الجلسة
    ini_set('session.cookie_httponly', 1); // منع الوصول إلى الكوكيز عبر JavaScript
    ini_set('session.use_only_cookies', 1); // استخدام الكوكيز فقط
    ini_set('session.cookie_samesite', 'Strict'); // CSRF protection
    
    // Performance optimizations
    ini_set('session.gc_probability', 1);
    ini_set('session.gc_divisor', 100);
    
    session_start();
    
    // Regenerate session ID periodically for security
    if (!isset($_SESSION['created'])) {
        $_SESSION['created'] = time();
    } else if (time() - $_SESSION['created'] > 1800) { // 30 minutes
        session_regenerate_id(true);
        $_SESSION['created'] = time();
    }
}

// Enhanced Database Configuration
// ✅ Best Practice: Use environment variables for sensitive data
$host     = getenv('DB_HOST') ?: "localhost";
$dbname   = getenv('DB_NAME') ?: "amanarac_almanara";
$username = getenv('DB_USER') ?: "amanarac_almanara";
$password = getenv('DB_PASS') ?: "amanarac_almanara";

// Validate database credentials
if (empty($host) || empty($dbname)) {
    error_log("❌ خطأ: إعدادات قاعدة البيانات غير مكتملة");
    die(json_encode(["status" => "error", "message" => "خطأ في إعدادات قاعدة البيانات"]));
}

/**
 * API Keys Configuration
 * ⚠️ Security Best Practice: Always use environment variables for API keys
 * 
 * ملاحظة مهمة: إذا ظهرت رسالة "يتعذّر على هذه الصفحة تحميل خرائط Google بشكل صحيح"
 * تأكد من:
 * 1. تفعيل واجهات برمجة التطبيقات التالية في Google Cloud Console:
 *    - Maps JavaScript API
 *    - Geocoding API
 *    - Places API (اختياري)
 * 2. التحقق من قيود النطاق (Domain Restrictions) - يجب أن يتطابق النطاق مع موقعك
 * 3. التأكد من تفعيل الفوترة (Billing) في المشروع
 * 4. التحقق من صلاحية مفتاح API
 * رابط Google Cloud Console: https://console.cloud.google.com/google/maps-apis
 */
$google_maps_api_key = getenv('GOOGLE_MAPS_API_KEY') ?: "AIzaSyAP5Kk6WJL-HWPDWCt8Q98bvSfXhr3BB2s";
$mapbox_token        = getenv('MAPBOX_TOKEN')        ?: "pk.eyJ1IjoiaWJyYWhpbWNvbSIsImEiOiJja2YxZnB6OWowc2xxMnFxZGxya2ppdmZxIn0.keECQuu1Bs0JeWDP8dSFQ";

// Validate API keys format (basic validation)
if (empty($google_maps_api_key) || strlen($google_maps_api_key) < 20) {
    error_log("⚠️ تحذير: مفتاح Google Maps API غير صالح أو غير موجود");
}

// تعريف ثابت لتوكن Mapbox لسهولة الوصول إليه في الملفات الأخرى
if (!defined('MAPBOX_TOKEN')) {
    define('MAPBOX_TOKEN', $mapbox_token);
}

// ✅ إعدادات Firebase Realtime Database
// ✅ تهيئة Firebase فقط عند الحاجة (ليس في كل طلب)
// ✅ هذا يحسن الأداء وخاصة في صفحات مثل login.php
if (!defined('SKIP_FIREBASE_INIT')) {
    require_once __DIR__ . '/firebase_service.php';
    
    // إعدادات Firebase من google-services.json
    $firebase_project_id = getenv('FIREBASE_PROJECT_ID') ?: "almanara-65382";
    $firebase_api_key = getenv('FIREBASE_API_KEY') ?: "AIzaSyC8nvFEOWfFTdo7GGDVr9N8qKeldDg1RIo";
    
    // ✅ URL قاعدة البيانات Firebase
    // الرابط الصحيح من Firebase Console
    $firebase_database_url = getenv('FIREBASE_DATABASE_URL') ?: "https://almanara-65382-default-rtdb.firebaseio.com";
    
    // تهيئة خدمة Firebase
    FirebaseService::initialize($firebase_project_id, $firebase_api_key, $firebase_database_url);
}

// ✅ ثابت للتحكم في استخدام Firebase أو MySQL
// قم بتعيينه إلى true لاستخدام Firebase، أو false لاستخدام MySQL (phpMyAdmin)
if (!defined('USE_FIREBASE')) {
    define('USE_FIREBASE', false); // false = استخدام قاعدة بيانات phpMyAdmin
}

// ✅ تحسين: استخدام Singleton Pattern لإعادة استخدام نفس الاتصال وتقليل عدد الاتصالات
class DatabaseConnection {
    private static $instance = null;
    private $connection = null;
    private $host;
    private $dbname;
    private $username;
    private $password;
    
    private function __construct($host, $dbname, $username, $password) {
        // حفظ إعدادات الاتصال
        $this->host = $host;
        $this->dbname = $dbname;
        $this->username = $username;
        $this->password = $password;
    }
    
    public static function getInstance($host = null, $dbname = null, $username = null, $password = null) {
        if (self::$instance === null) {
            // استخدام القيم الممررة أو القيم الافتراضية
            $host = $host ?? "localhost";
            $dbname = $dbname ?? "amanarac_almanara";
            $username = $username ?? "amanarac_almanara";
            $password = $password ?? "amanarac_almanara";
            self::$instance = new self($host, $dbname, $username, $password);
        }
        return self::$instance;
    }
    
    public function getConnection() {
        // ✅ إذا كان الاتصال موجوداً، أرجعه مباشرة بدون اختبار (لتقليل عدد الاتصالات)
        // ✅ اختبار الاتصال بـ SELECT 1 يفتح اتصالات جديدة، لذا تم إزالته
        if ($this->connection !== null) {
            return $this->connection;
        }
        
        // إنشاء اتصال جديد
        try {
            $options = [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_PERSISTENT => false, // ✅ تعطيل الاتصالات الدائمة لتقليل عدد الاتصالات
                PDO::ATTR_TIMEOUT => 3, // ✅ تقليل timeout إلى 3 ثوانٍ
                PDO::ATTR_EMULATE_PREPARES => false, // ✅ استخدام prepared statements الحقيقية
                PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci", // ✅ UTF-8 encoding
                PDO::ATTR_STRINGIFY_FETCHES => false, // ✅ الحفاظ على أنواع البيانات
            ];
            
            // ✅ التأكد من تمرير كلمة المرور بشكل صحيح (حتى لو كانت فارغة)
            $dsn = "mysql:host={$this->host};dbname={$this->dbname};charset=utf8mb4";
            
            // ✅ التأكد من أن كلمة المرور هي string وليست null
            $password = (string)$this->password;
            
            $this->connection = new PDO(
                $dsn, 
                $this->username, 
                $password, 
                $options
            );
            
            // ✅ Enhanced MySQL Performance Settings
            // ✅ تقليل wait_timeout و interactive_timeout إلى 5 ثوانٍ فقط لتقليل عدد الاتصالات النشطة بشكل جذري جداً
            $this->connection->exec("SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'");
            $this->connection->exec("SET SESSION wait_timeout=5");
            $this->connection->exec("SET SESSION interactive_timeout=5");
            
            // ✅ SQL Mode - Compatible with MySQL 8.0+ (NO_AUTO_CREATE_USER removed in 8.0.11+)
            // Check MySQL version to set appropriate sql_mode
            try {
                $version = $this->connection->query("SELECT VERSION()")->fetchColumn();
                $versionNum = (float)substr($version, 0, 3);
                
                if ($versionNum >= 8.0) {
                    // MySQL 8.0+ - NO_AUTO_CREATE_USER is deprecated
                    $this->connection->exec("SET SESSION sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'");
                } else {
                    // MySQL 5.7 and earlier
                    $this->connection->exec("SET SESSION sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'");
                }
            } catch (PDOException $e) {
                // Fallback to safe mode if version check fails
                error_log("⚠️ Warning: Could not set sql_mode: " . $e->getMessage());
                $this->connection->exec("SET SESSION sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'");
            }
            
            // Enable query cache if available (deprecated in MySQL 8.0, but safe to try)
            try {
                $this->connection->exec("SET SESSION query_cache_type=1");
            } catch (PDOException $e) {
                // Query cache is deprecated in MySQL 8.0, ignore error
                error_log("ℹ️ Info: Query cache not available (MySQL 8.0+): " . $e->getMessage());
            }
            
        } catch (PDOException $e) {
            error_log("❌ فشل الاتصال بقاعدة البيانات: " . $e->getMessage());
            throw $e;
        }
        
        return $this->connection;
    }
    
    public function closeConnection() {
        if ($this->connection !== null) {
            try {
                // ✅ إغلاق الاتصال بشكل صحيح
                // ✅ في PDO، يجب تعيين الاتصال إلى null لإغلاقه
                // ✅ لكن قد نحتاج أيضاً إلى إغلاق جميع الاستعلامات المعلقة أولاً
                $this->connection = null;
                
                // ✅ إجبار PHP على إغلاق الاتصال فوراً بدلاً من الانتظار للـ garbage collector
                if (function_exists('gc_collect_cycles')) {
                    gc_collect_cycles();
                }
            } catch (Exception $e) {
                // تجاهل أي أخطاء أثناء الإغلاق
                error_log("⚠️ تحذير: خطأ أثناء إغلاق الاتصال: " . $e->getMessage());
            }
        }
    }
    
    /**
     * ✅ دالة جديدة: إغلاق الاتصال بشكل قسري (للاستخدام في حالات الطوارئ)
     */
    public function forceCloseConnection() {
        if ($this->connection !== null) {
            try {
                // ✅ إغلاق الاتصال بشكل قسري
                $this->connection = null;
                
                // ✅ إجبار PHP على إغلاق الاتصال فوراً
                if (function_exists('gc_collect_cycles')) {
                    gc_collect_cycles();
                }
            } catch (Exception $e) {
                // تجاهل أي أخطاء
            }
        }
        // ✅ إعادة تعيين الـ instance لإجبار إنشاء اتصال جديد في المرة القادمة
        self::$instance = null;
    }
    
    /**
     * ✅ دالة جديدة: إعادة تعيين الـ Singleton (للاستخدام في حالات الطوارئ)
     */
    public static function resetInstance() {
        if (self::$instance !== null) {
            try {
                self::$instance->forceCloseConnection();
            } catch (Exception $e) {
                // تجاهل الأخطاء
            }
        }
        self::$instance = null;
    }
}

// ✅ استخدام Singleton للحصول على اتصال واحد قابل لإعادة الاستخدام
try {
    $dbInstance = DatabaseConnection::getInstance($host, $dbname, $username, $password);
    $conn = $dbInstance->getConnection();
    
    // ✅ جعل $dbInstance متاحاً كمتغير عام للوصول إليه من الملفات الأخرى
    $GLOBALS['dbInstance'] = $dbInstance;
    
    // ✅ إضافة آلية لإغلاق الاتصال تلقائياً في نهاية الطلب
    // هذا يضمن إغلاق الاتصال حتى لو حدث خطأ أو لم يتم استدعاء closeConnection() يدوياً
    register_shutdown_function(function() use ($dbInstance) {
        try {
            // ✅ إغلاق الاتصال بشكل قسري في نهاية الطلب
            if ($dbInstance !== null) {
                $dbInstance->forceCloseConnection();
            }
            // ✅ إعادة تعيين Singleton لإجبار إنشاء اتصال جديد في الطلب التالي
            DatabaseConnection::resetInstance();
        } catch (Exception $e) {
            // تجاهل الأخطاء أثناء الإغلاق التلقائي
        }
    });
    
} catch (PDOException $e) {
    // في حال فشل الاتصال
    die(json_encode(["status" => "error", "message" => "❌ فشل الاتصال بقاعدة البيانات: " . $e->getMessage()]));
}
?>
