<?php
/**
 * Database Configuration and Connection
 * فوترة بلس - POS System
 * 
 * IMPORTANT: Update the following values with your cPanel MySQL credentials
 */

// ============================================
// TIMEZONE CONFIGURATION - الوقت المحلي
// ============================================
date_default_timezone_set('Asia/Riyadh');

// ============================================
// DATABASE CONFIGURATION - UPDATE THESE VALUES
// ============================================
define('DB_HOST', 'localhost');
define('DB_NAME', 'jopythonpos_clean');      // Change this
define('DB_USER', 'jopythonpos_clean');      // Change this
define('DB_PASS', 'hQ-Cl}I@+cQai9)u');  // Change this
define('DB_CHARSET', 'utf8mb4');

// JWT Secret Key
define('JWT_SECRET', 'Fawtra_بلس_2025_Secure_مفتاح_Key!');

// Token expiration time in seconds (30 days for trusted POS devices)
define('TOKEN_EXPIRY', 60 * 60 * 24 * 30); // 30 days


// ============================================
// PERFORMANCE: Brotli/GZIP Compression
// ============================================
if (!headers_sent()) {
    $acceptEncoding = $_SERVER['HTTP_ACCEPT_ENCODING'] ?? '';
    
    // Try Brotli first (better compression)
    if (function_exists('brotli_compress') && strpos($acceptEncoding, 'br') !== false) {
        // Brotli will be applied in jsonResponse
        define('USE_BROTLI', true);
    } elseif (extension_loaded('zlib') && !ini_get('zlib.output_compression') && strpos($acceptEncoding, 'gzip') !== false) {
        ob_start('ob_gzhandler');
        define('USE_BROTLI', false);
    } else {
        define('USE_BROTLI', false);
    }
}

// ============================================
// CORS HEADERS - Allow requests from frontend
// ============================================
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, If-None-Match');
header('Content-Type: application/json; charset=utf-8');

// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit();
}

// ============================================
// DATABASE CONNECTION with Retry Mechanism
// ============================================
global $pdo;

$dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET;
$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, time_zone = '+03:00'",
    // تعطيل الاتصالات الدائمة لتجنب Too many connections
    PDO::ATTR_PERSISTENT         => false,
];

// آلية إعادة المحاولة عند فشل الاتصال
$maxRetries = 3;
$retryDelay = 500000; // 0.5 ثانية
$pdo = null;

for ($attempt = 1; $attempt <= $maxRetries; $attempt++) {
    try {
        $pdo = new PDO($dsn, DB_USER, DB_PASS, $options);
        break; // نجح الاتصال
    } catch (PDOException $e) {
        $isTooManyConnections = ($e->getCode() == 1040 || strpos($e->getMessage(), 'Too many connections') !== false);
        
        // إذا كانت آخر محاولة أو خطأ غير "Too many connections"
        if ($attempt === $maxRetries || !$isTooManyConnections) {
            http_response_code(500);
            
            if ($isTooManyConnections) {
                echo json_encode([
                    'success' => false,
                    'message' => 'الخادم مشغول حالياً، يرجى المحاولة بعد قليل',
                    'error_code' => 'DB_OVERLOADED'
                ]);
            } else {
                echo json_encode([
                    'success' => false,
                    'message' => 'Database connection failed: ' . $e->getMessage()
                ]);
            }
            exit();
        }
        
        // انتظار متزايد قبل إعادة المحاولة
        usleep($retryDelay * $attempt);
    }
}

// ============================================
// PERFORMANCE: Query Result Cache (APCu/File)
// ============================================
define('CACHE_DIR', sys_get_temp_dir() . '/pos_cache/');

// Cache TTL by data type
define('CACHE_TTL_STATIC', 600);    // 10 minutes for products, categories
define('CACHE_TTL_DYNAMIC', 60);     // 1 minute for invoices, shifts
define('CACHE_TTL_DEFAULT', 300);    // 5 minutes default

if (!is_dir(CACHE_DIR)) {
    @mkdir(CACHE_DIR, 0755, true);
}

// ============================================
// PERFORMANCE: Query Logging for Optimization
// ============================================
define('SLOW_QUERY_THRESHOLD', 0.5); // 500ms
$queryLog = [];

function logQuery($sql, $duration) {
    global $queryLog;
    $queryLog[] = [
        'sql' => substr($sql, 0, 200),
        'duration' => $duration,
        'slow' => $duration > SLOW_QUERY_THRESHOLD
    ];
    
    if ($duration > SLOW_QUERY_THRESHOLD) {
        error_log("SLOW QUERY ({$duration}s): " . substr($sql, 0, 200));
    }
}

/**
 * Get cached data or execute callback
 */
function getCachedData($key, $ttl, $callback) {
    $cacheFile = CACHE_DIR . md5($key) . '.cache';
    
    // Check if cache exists and is valid
    if (file_exists($cacheFile)) {
        $cacheTime = filemtime($cacheFile);
        if (time() - $cacheTime < $ttl) {
            $cached = file_get_contents($cacheFile);
            if ($cached !== false) {
                return json_decode($cached, true);
            }
        }
    }
    
    // Execute callback and cache result
    $data = $callback();
    file_put_contents($cacheFile, json_encode($data), LOCK_EX);
    
    return $data;
}

/**
 * Invalidate cache by key pattern
 */
function invalidateCache($pattern = '*') {
    $files = glob(CACHE_DIR . $pattern . '*.cache');
    foreach ($files as $file) {
        @unlink($file);
    }
}

// ============================================
// HELPER FUNCTIONS
// ============================================

/**
 * Send JSON response with intelligent caching headers
 * @param bool $success
 * @param string $message
 * @param mixed $data
 * @param int $statusCode
 * @param string|bool $cacheType - false, 'static', 'dynamic', or true (default)
 */
function jsonResponse($success, $message, $data = null, $statusCode = 200, $cacheType = false) {
    http_response_code($statusCode);
    
    // Determine cache settings based on type
    $maxAge = 0;
    if ($cacheType && $_SERVER['REQUEST_METHOD'] === 'GET' && $success) {
        switch ($cacheType) {
            case 'static':
                $maxAge = 600; // 10 minutes
                break;
            case 'dynamic':
                $maxAge = 60; // 1 minute
                break;
            case true:
            default:
                $maxAge = 300; // 5 minutes
                break;
        }
    }
    
    // Add cache headers for GET requests
    if ($maxAge > 0) {
        $etag = md5(json_encode($data) . $maxAge);
        header("Cache-Control: private, max-age={$maxAge}, stale-while-revalidate=" . ($maxAge * 2));
        header('ETag: "' . $etag . '"');
        header('Vary: Authorization');
        
        // Check If-None-Match for 304 response (saves bandwidth)
        if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
            $clientEtag = trim($_SERVER['HTTP_IF_NONE_MATCH'], '"');
            if ($clientEtag === $etag) {
                http_response_code(304);
                exit();
            }
        }
    } else {
        header('Cache-Control: no-cache, no-store, must-revalidate');
        header('Pragma: no-cache');
    }
    
    $response = [
        'success' => $success,
        'message' => $message
    ];
    if ($data !== null) {
        $response['data'] = $data;
    }
    
    // Add performance metrics in development
    global $queryLog;
    if (defined('DEV_MODE') && DEV_MODE && !empty($queryLog)) {
        $response['_debug'] = [
            'queries' => count($queryLog),
            'slow_queries' => count(array_filter($queryLog, fn($q) => $q['slow'])),
            'total_time' => array_sum(array_column($queryLog, 'duration'))
        ];
    }
    
    // Encode JSON with optimized flags
    $json = json_encode($response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    
    // Apply Brotli compression if available
    if (defined('USE_BROTLI') && USE_BROTLI && function_exists('brotli_compress')) {
        header('Content-Encoding: br');
        echo brotli_compress($json, 4); // Quality 4 for speed/compression balance
    } else {
        echo $json;
    }
    
    exit();
}

/**
 * Get JSON input from request body
 */
function getJsonInput() {
    $input = file_get_contents('php://input');
    return json_decode($input, true) ?? [];
}

/**
 * Sanitize input string
 */
function sanitize($input) {
    if (is_string($input)) {
        return htmlspecialchars(strip_tags(trim($input)), ENT_QUOTES, 'UTF-8');
    }
    return $input;
}

/**
 * Generate UUID v4
 */
function generateUUID() {
    $data = random_bytes(16);
    $data[6] = chr(ord($data[6]) & 0x0f | 0x40);
    $data[8] = chr(ord($data[8]) & 0x3f | 0x80);
    return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}

/**
 * Validate UUID format
 */
function isValidUUID($uuid) {
    return preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i', $uuid);
}

/**
 * Get current timestamp in MySQL format
 */
function getCurrentTimestamp() {
    return date('Y-m-d H:i:s');
}
?>
