<?php
/**
 * RUHONDO BEACH RESORT HMS + POS System
 * Global Helper Functions
 * Developer: JOACHIM'S INNOTECH
 */

// Prevent direct access
if (!defined('BASE_PATH')) {
    exit('Direct access not permitted');
}

// =============================================
// DATABASE HELPER FUNCTIONS (that depend on database.php)
// =============================================

/**
 * Get database size in MB
 * @return array Array with size information
 */
function get_db_size() {
    // Check if db_connect function exists
    if (!function_exists('db_connect')) {
        error_log("db_connect() function not found. Make sure database.php is loaded.");
        return ['size_mb' => 0, 'size_bytes' => 0, 'size_formatted' => 'N/A'];
    }
    
    try {
        $db = db_connect();
        if (!$db) {
            return ['size_mb' => 0, 'size_bytes' => 0, 'size_formatted' => '0 MB'];
        }
        
        // Get database name from connection
        $db_name = defined('DB_NAME') ? DB_NAME : '';
        if (empty($db_name)) {
            return ['size_mb' => 0, 'size_bytes' => 0, 'size_formatted' => 'N/A'];
        }
        
        // Query to get database size
        $query = "SELECT 
                    ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) as size_mb,
                    SUM(data_length + index_length) as size_bytes
                  FROM information_schema.tables 
                  WHERE table_schema = ?";
        
        $stmt = $db->prepare($query);
        $stmt->execute([$db_name]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($result && $result['size_mb']) {
            $size_mb = $result['size_mb'];
            $size_bytes = $result['size_bytes'];
            
            // Format size for display
            if ($size_mb < 1) {
                $size_formatted = round($size_bytes / 1024, 2) . ' KB';
            } elseif ($size_mb < 1024) {
                $size_formatted = $size_mb . ' MB';
            } else {
                $size_formatted = round($size_mb / 1024, 2) . ' GB';
            }
            
            return [
                'size_mb' => $size_mb,
                'size_bytes' => $size_bytes,
                'size_formatted' => $size_formatted
            ];
        }
        
        return ['size_mb' => 0, 'size_bytes' => 0, 'size_formatted' => '0 MB'];
        
    } catch (Exception $e) {
        error_log("Error getting database size: " . $e->getMessage());
        return ['size_mb' => 0, 'size_bytes' => 0, 'size_formatted' => 'Error'];
    }
}

/**
 * Test database connection
 * @return bool True if connection successful
 */
function test_db_connection() {
    // Check if db_connect function exists
    if (!function_exists('db_connect')) {
        error_log("db_connect() function not found. Make sure database.php is loaded.");
        return false;
    }
    
    try {
        $db = db_connect();
        return $db !== null;
    } catch (Exception $e) {
        return false;
    }
}

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

/**
 * Generate random string
 */
if (!function_exists('generate_random_string')) {
    function generate_random_string($length = 32) {
        return bin2hex(random_bytes($length / 2));
    }
}

/**
 * Generate random number
 */
if (!function_exists('generate_random_number')) {
    function generate_random_number($min = 100000, $max = 999999) {
        return random_int($min, $max);
    }
}

/**
 * Truncate text to specified length
 */
if (!function_exists('truncate_text')) {
    function truncate_text($text, $length = 100, $suffix = '...') {
        if (strlen($text) <= $length) {
            return $text;
        }
        return substr($text, 0, $length) . $suffix;
    }
}

/**
 * Convert string to slug
 */
if (!function_exists('create_slug')) {
    function create_slug($string) {
        $string = strtolower($string);
        $string = preg_replace('/[^a-z0-9-]/', '-', $string);
        $string = preg_replace('/-+/', '-', $string);
        return trim($string, '-');
    }
}

/**
 * Mask email address
 */
if (!function_exists('mask_email')) {
    function mask_email($email) {
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            return $email;
        }
        
        $parts = explode('@', $email);
        $name = $parts[0];
        $domain = $parts[1];
        
        $masked_name = substr($name, 0, 2) . str_repeat('*', strlen($name) - 2);
        
        return $masked_name . '@' . $domain;
    }
}

/**
 * Mask phone number
 */
if (!function_exists('mask_phone')) {
    function mask_phone($phone) {
        $length = strlen($phone);
        if ($length <= 4) {
            return $phone;
        }
        
        $visible = 4;
        $masked = str_repeat('*', $length - $visible);
        return $masked . substr($phone, -$visible);
    }
}

/**
 * Format bytes to human readable
 */
if (!function_exists('format_bytes')) {
    function format_bytes($bytes, $precision = 2) {
        $units = ['B', 'KB', 'MB', 'GB', 'TB'];
        
        $bytes = max($bytes, 0);
        $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
        $pow = min($pow, count($units) - 1);
        
        $bytes /= pow(1024, $pow);
        
        return round($bytes, $precision) . ' ' . $units[$pow];
    }
}

// =============================================
// DATE/TIME HELPER FUNCTIONS
// =============================================

/**
 * Format date
 */
if (!function_exists('format_date')) {
    function format_date($date, $format = 'Y-m-d') {
        // Use constant if defined
        if (defined('DISPLAY_DATE_FORMAT')) {
            $format = DISPLAY_DATE_FORMAT;
        }
        
        if (empty($date)) return '';
        $timestamp = is_numeric($date) ? $date : strtotime($date);
        return date($format, $timestamp);
    }
}

/**
 * Format datetime
 */
if (!function_exists('format_datetime')) {
    function format_datetime($datetime, $format = 'Y-m-d H:i:s') {
        // Use constant if defined
        if (defined('DISPLAY_DATETIME_FORMAT')) {
            $format = DISPLAY_DATETIME_FORMAT;
        }
        
        if (empty($datetime)) return '';
        $timestamp = is_numeric($datetime) ? $datetime : strtotime($datetime);
        return date($format, $timestamp);
    }
}

/**
 * Format time
 */
if (!function_exists('format_time')) {
    function format_time($time, $format = 'H:i:s') {
        // Use constant if defined
        if (defined('DISPLAY_TIME_FORMAT')) {
            $format = DISPLAY_TIME_FORMAT;
        }
        
        if (empty($time)) return '';
        $timestamp = is_numeric($time) ? $time : strtotime($time);
        return date($format, $timestamp);
    }
}

/**
 * Get time ago string
 */
if (!function_exists('time_ago')) {
    function time_ago($datetime) {
        $timestamp = is_numeric($datetime) ? $datetime : strtotime($datetime);
        $diff = time() - $timestamp;
        
        if ($diff < 60) {
            return $diff . ' seconds ago';
        } elseif ($diff < 3600) {
            $mins = floor($diff / 60);
            return $mins . ' minute' . ($mins > 1 ? 's' : '') . ' ago';
        } elseif ($diff < 86400) {
            $hours = floor($diff / 3600);
            return $hours . ' hour' . ($hours > 1 ? 's' : '') . ' ago';
        } elseif ($diff < 604800) {
            $days = floor($diff / 86400);
            return $days . ' day' . ($days > 1 ? 's' : '') . ' ago';
        } elseif ($diff < 2592000) {
            $weeks = floor($diff / 604800);
            return $weeks . ' week' . ($weeks > 1 ? 's' : '') . ' ago';
        } elseif ($diff < 31536000) {
            $months = floor($diff / 2592000);
            return $months . ' month' . ($months > 1 ? 's' : '') . ' ago';
        } else {
            $years = floor($diff / 31536000);
            return $years . ' year' . ($years > 1 ? 's' : '') . ' ago';
        }
    }
}

/**
 * Get date range array
 */
if (!function_exists('get_date_range')) {
    function get_date_range($start_date, $end_date) {
        $dates = [];
        $current = strtotime($start_date);
        $end = strtotime($end_date);
        
        while ($current <= $end) {
            $dates[] = date('Y-m-d', $current);
            $current = strtotime('+1 day', $current);
        }
        
        return $dates;
    }
}

/**
 * Calculate nights between dates
 */
if (!function_exists('calculate_nights')) {
    function calculate_nights($check_in, $check_out) {
        $start = strtotime($check_in);
        $end = strtotime($check_out);
        return ceil(($end - $start) / 86400); // SECONDS_PER_DAY = 86400
    }
}

/**
 * Check if date is in range
 */
if (!function_exists('date_in_range')) {
    function date_in_range($date, $start_date, $end_date) {
        $date = strtotime($date);
        $start = strtotime($start_date);
        $end = strtotime($end_date);
        
        return ($date >= $start && $date <= $end);
    }
}

// =============================================
// NUMBER/FINANCIAL HELPER FUNCTIONS
// =============================================

/**
 * Format currency
 */
if (!function_exists('format_currency')) {
    function format_currency($amount, $currency = 'USD') {
        // Use constants if defined
        $symbol = '$';
        $decimals = 2;
        $dec_sep = '.';
        $thousand_sep = ',';
        
        if (defined('DEFAULT_CURRENCY')) {
            $currency = DEFAULT_CURRENCY;
        }
        
        if (defined('CURRENCY_SYMBOL')) {
            $symbol = CURRENCY_SYMBOL;
        }
        
        if (defined('DECIMAL_PLACES')) {
            $decimals = DECIMAL_PLACES;
        }
        
        if (defined('DECIMAL_SEPARATOR')) {
            $dec_sep = DECIMAL_SEPARATOR;
        }
        
        if (defined('THOUSAND_SEPARATOR')) {
            $thousand_sep = THOUSAND_SEPARATOR;
        }
        
        $formatted = number_format(
            (float)$amount, 
            $decimals, 
            $dec_sep, 
            $thousand_sep
        );
        
        return $symbol . ' ' . $formatted;
    }
}

/**
 * Format number
 */
if (!function_exists('format_number')) {
    function format_number($number, $decimals = 2) {
        // Use constant if defined
        if (defined('DECIMAL_PLACES')) {
            $decimals = DECIMAL_PLACES;
        }
        
        $dec_sep = defined('DECIMAL_SEPARATOR') ? DECIMAL_SEPARATOR : '.';
        $thousand_sep = defined('THOUSAND_SEPARATOR') ? THOUSAND_SEPARATOR : ',';
        
        return number_format(
            (float)$number, 
            $decimals, 
            $dec_sep, 
            $thousand_sep
        );
    }
}

/**
 * Calculate percentage
 */
if (!function_exists('calculate_percentage')) {
    function calculate_percentage($value, $total, $decimals = 2) {
        if ($total == 0) return 0;
        return round(($value / $total) * 100, $decimals);
    }
}

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

/**
 * Get array value with default
 */
if (!function_exists('array_get')) {
    function array_get($array, $key, $default = null) {
        if (is_null($key)) return $array;
        
        if (isset($array[$key])) {
            return $array[$key];
        }
        
        foreach (explode('.', $key) as $segment) {
            if (!is_array($array) || !array_key_exists($segment, $array)) {
                return $default;
            }
            $array = $array[$segment];
        }
        
        return $array;
    }
}

/**
 * Pluck column from array
 */
if (!function_exists('array_pluck')) {
    function array_pluck($array, $column) {
        return array_map(function($item) use ($column) {
            return is_object($item) ? $item->$column : $item[$column];
        }, $array);
    }
}

/**
 * Group array by key
 */
if (!function_exists('array_group_by')) {
    function array_group_by($array, $key) {
        $result = [];
        
        foreach ($array as $item) {
            $value = is_object($item) ? $item->$key : $item[$key];
            $result[$value][] = $item;
        }
        
        return $result;
    }
}

/**
 * Sort array by key
 */
if (!function_exists('array_sort_by')) {
    function array_sort_by($array, $key, $direction = 'asc') {
        usort($array, function($a, $b) use ($key, $direction) {
            $val_a = is_object($a) ? $a->$key : $a[$key];
            $val_b = is_object($b) ? $b->$key : $b[$key];
            
            if ($val_a == $val_b) return 0;
            
            if ($direction === 'asc') {
                return ($val_a < $val_b) ? -1 : 1;
            } else {
                return ($val_a > $val_b) ? -1 : 1;
            }
        });
        
        return $array;
    }
}

// =============================================
// FILE/UPLOAD HELPER FUNCTIONS
// =============================================

/**
 * Upload file with validation
 */
if (!function_exists('upload_file')) {
    function upload_file($file, $target_dir, $allowed_types = null, $max_size = null) {
        $errors = [];
        
        // Check if file was uploaded
        if (!isset($file) || $file['error'] !== UPLOAD_ERR_OK) {
            $errors[] = 'No file uploaded or upload error occurred';
            return ['success' => false, 'errors' => $errors];
        }
        
        // Set defaults
        if ($allowed_types === null && defined('UPLOAD_ALLOWED_EXTENSIONS')) {
            $allowed_types = explode(',', UPLOAD_ALLOWED_EXTENSIONS);
        } elseif ($allowed_types === null) {
            $allowed_types = ['jpg', 'jpeg', 'png', 'gif', 'pdf'];
        }
        
        if ($max_size === null && defined('UPLOAD_MAX_SIZE')) {
            $max_size = UPLOAD_MAX_SIZE;
        } elseif ($max_size === null) {
            $max_size = 5 * 1024 * 1024; // 5MB default
        }
        
        // Validate file size
        if ($file['size'] > $max_size) {
            $errors[] = 'File size exceeds maximum allowed (' . format_bytes($max_size) . ')';
        }
        
        // Validate file type
        $extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        if (!in_array($extension, $allowed_types)) {
            $errors[] = 'File type not allowed. Allowed types: ' . implode(', ', $allowed_types);
        }
        
        // If errors, return
        if (!empty($errors)) {
            return ['success' => false, 'errors' => $errors];
        }
        
        // Generate unique filename
        $new_filename = uniqid() . '_' . time() . '.' . $extension;
        $target_path = rtrim($target_dir, '/') . '/' . $new_filename;
        
        // Ensure target directory exists
        if (!file_exists($target_dir)) {
            mkdir($target_dir, 0755, true);
        }
        
        // Move uploaded file
        if (move_uploaded_file($file['tmp_name'], $target_path)) {
            return [
                'success' => true,
                'filename' => $new_filename,
                'path' => $target_path,
                'size' => $file['size'],
                'mime' => $file['type']
            ];
        } else {
            $errors[] = 'Failed to move uploaded file';
            return ['success' => false, 'errors' => $errors];
        }
    }
}

/**
 * Delete file
 */
if (!function_exists('delete_file')) {
    function delete_file($file_path) {
        if (file_exists($file_path) && is_file($file_path)) {
            return unlink($file_path);
        }
        return false;
    }
}

/**
 * Get file extension
 */
if (!function_exists('get_file_extension')) {
    function get_file_extension($filename) {
        return strtolower(pathinfo($filename, PATHINFO_EXTENSION));
    }
}

/**
 * Is image file
 */
if (!function_exists('is_image_file')) {
    function is_image_file($filename) {
        $ext = get_file_extension($filename);
        return in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']);
    }
}

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

/**
 * Validate email
 */
if (!function_exists('validate_email')) {
    function validate_email($email) {
        return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
    }
}

/**
 * Validate phone number
 */
if (!function_exists('validate_phone')) {
    function validate_phone($phone) {
        // Simple phone validation
        $pattern = '/^[0-9+\-\s()]{10,20}$/';
        return preg_match($pattern, $phone);
    }
}

/**
 * Validate password strength
 */
if (!function_exists('validate_password')) {
    function validate_password($password) {
        // At least 8 characters, at least one uppercase, one lowercase, one number
        $pattern = '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/';
        return preg_match($pattern, $password);
    }
}

/**
 * Validate date
 */
if (!function_exists('validate_date')) {
    function validate_date($date, $format = 'Y-m-d') {
        $d = DateTime::createFromFormat($format, $date);
        return $d && $d->format($format) === $date;
    }
}

/**
 * Validate URL
 */
if (!function_exists('validate_url')) {
    function validate_url($url) {
        return filter_var($url, FILTER_VALIDATE_URL) !== false;
    }
}

/**
 * Validate required fields
 */
if (!function_exists('validate_required')) {
    function validate_required($data, $fields) {
        $errors = [];
        
        foreach ($fields as $field) {
            if (empty($data[$field])) {
                $errors[$field] = ucfirst(str_replace('_', ' ', $field)) . ' is required';
            }
        }
        
        return $errors;
    }
}

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

/**
 * Sanitize input
 */
if (!function_exists('sanitize_input')) {
    function sanitize_input($data) {
        if (is_array($data)) {
            return array_map('sanitize_input', $data);
        }
        
        $data = trim($data);
        $data = stripslashes($data);
        $data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
        return $data;
    }
}

/**
 * Escape output for HTML
 */
if (!function_exists('escape_html')) {
    function escape_html($data) {
        if (is_array($data)) {
            return array_map('escape_html', $data);
        }
        
        return htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
    }
}

/**
 * Escape for JSON
 */
if (!function_exists('escape_json')) {
    function escape_json($data) {
        return json_encode($data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE);
    }
}

/**
 * Generate CSRF token
 */
if (!function_exists('generate_csrf_token')) {
    function generate_csrf_token() {
        $token_name = defined('CSRF_TOKEN_NAME') ? CSRF_TOKEN_NAME : 'csrf_token';
        
        if (empty($_SESSION[$token_name])) {
            $_SESSION[$token_name] = bin2hex(random_bytes(32));
        }
        return $_SESSION[$token_name];
    }
}

/**
 * Verify CSRF token
 */
if (!function_exists('verify_csrf_token')) {
    function verify_csrf_token($token) {
        $token_name = defined('CSRF_TOKEN_NAME') ? CSRF_TOKEN_NAME : 'csrf_token';
        
        if (empty($_SESSION[$token_name]) || empty($token)) {
            return false;
        }
        return hash_equals($_SESSION[$token_name], $token);
    }
}

/**
 * Get client IP address
 */
if (!function_exists('get_client_ip')) {
    function get_client_ip() {
        $ipaddress = '';
        
        if (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } elseif (isset($_SERVER['HTTP_X_FORWARDED'])) {
            $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
        } elseif (isset($_SERVER['HTTP_FORWARDED_FOR'])) {
            $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
        } elseif (isset($_SERVER['HTTP_FORWARDED'])) {
            $ipaddress = $_SERVER['HTTP_FORWARDED'];
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ipaddress = $_SERVER['REMOTE_ADDR'];
        } else {
            $ipaddress = 'UNKNOWN';
        }
        
        return $ipaddress;
    }
}

/**
 * Get user agent
 */
if (!function_exists('get_user_agent')) {
    function get_user_agent() {
        return $_SERVER['HTTP_USER_AGENT'] ?? 'UNKNOWN';
    }
}

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

/**
 * Log message
 */
if (!function_exists('log_message')) {
    function log_message($message, $level = 'INFO', $file = null) {
        // Use default log file if not specified
        if ($file === null && defined('LOG_APP')) {
            $file = LOG_APP;
        } elseif ($file === null) {
            $file = dirname(__DIR__) . '/logs/app.log';
        }
        
        $timestamp = date('Y-m-d H:i:s');
        $log_entry = "[$timestamp] [$level] $message" . PHP_EOL;
        
        // Ensure directory exists
        $log_dir = dirname($file);
        if (!file_exists($log_dir)) {
            mkdir($log_dir, 0755, true);
        }
        
        file_put_contents($file, $log_entry, FILE_APPEND | LOCK_EX);
    }
}

/**
 * Debug log (only when DEBUG mode)
 */
if (!function_exists('debug_log')) {
    function debug_log($message) {
        if (defined('DEBUG') && DEBUG === true) {
            log_message($message, 'DEBUG');
        }
    }
}

/**
 * Audit log
 */
if (!function_exists('audit_log')) {
    function audit_log($user_id, $action, $table_name = null, $record_id = null, $old_values = null, $new_values = null) {
        // Check if audit log is enabled
        if (defined('ENABLE_AUDIT_LOG') && !ENABLE_AUDIT_LOG) {
            return;
        }
        
        // Check if db_insert function exists
        if (!function_exists('db_insert')) {
            log_message("db_insert() function not found. Cannot create audit log.", 'ERROR');
            return;
        }
        
        try {
            db_insert('audit_logs', [
                'user_id' => $user_id,
                'action' => $action,
                'table_name' => $table_name,
                'record_id' => $record_id,
                'old_values' => $old_values ? json_encode($old_values) : null,
                'new_values' => $new_values ? json_encode($new_values) : null,
                'ip_address' => get_client_ip(),
                'user_agent' => get_user_agent(),
                'request_uri' => $_SERVER['REQUEST_URI'] ?? null
            ]);
        } catch (Exception $e) {
            log_message("Audit log failed: " . $e->getMessage(), 'ERROR');
        }
    }
}

// =============================================
// SESSION/FLASH MESSAGE FUNCTIONS
// =============================================

/**
 * Set flash message
 */
if (!function_exists('set_flash_message')) {
    function set_flash_message($type, $message) {
        if (!isset($_SESSION['flash_messages'])) {
            $_SESSION['flash_messages'] = [];
        }
        
        $_SESSION['flash_messages'][] = [
            'type' => $type,
            'message' => $message,
            'time' => time()
        ];
    }
}

/**
 * Get flash messages
 */
if (!function_exists('get_flash_messages')) {
    function get_flash_messages() {
        $messages = $_SESSION['flash_messages'] ?? [];
        
        // Remove old messages (older than 5 minutes)
        $messages = array_filter($messages, function($msg) {
            return (time() - $msg['time']) < 300;
        });
        
        $_SESSION['flash_messages'] = [];
        
        return $messages;
    }
}

/**
 * Display flash messages
 */
if (!function_exists('display_flash_messages')) {
    function display_flash_messages() {
        $messages = get_flash_messages();
        
        foreach ($messages as $msg) {
            $type = $msg['type'];
            $message = escape_html($msg['message']);
            
            echo "<div class='alert alert-{$type} alert-dismissible fade show' role='alert'>";
            echo $message;
            echo "<button type='button' class='btn-close' data-bs-dismiss='alert' aria-label='Close'></button>";
            echo "</div>";
        }
    }
}

// =============================================
// NOTIFICATION FUNCTIONS
// =============================================

/**
 * Create notification
 */
if (!function_exists('create_notification')) {
    function create_notification($user_id, $type, $title, $message, $link = null) {
        // Check if db_insert function exists
        if (!function_exists('db_insert')) {
            log_message("db_insert() function not found. Cannot create notification.", 'ERROR');
            return false;
        }
        
        try {
            return db_insert('notifications', [
                'user_id' => $user_id,
                'type' => $type,
                'title' => $title,
                'message' => $message,
                'link' => $link
            ]);
        } catch (Exception $e) {
            log_message("Notification creation failed: " . $e->getMessage(), 'ERROR');
            return false;
        }
    }
}

/**
 * Get unread notification count
 */
if (!function_exists('get_unread_notification_count')) {
    function get_unread_notification_count($user_id) {
        // Check if db_count function exists
        if (!function_exists('db_count')) {
            log_message("db_count() function not found. Cannot get notification count.", 'ERROR');
            return 0;
        }
        
        return db_count('notifications', 'user_id = ? AND is_read = 0', [$user_id]);
    }
}

/**
 * Get user notifications
 */
if (!function_exists('get_user_notifications')) {
    function get_user_notifications($user_id, $limit = 10) {
        // Check if db_fetch_all function exists
        if (!function_exists('db_fetch_all')) {
            log_message("db_fetch_all() function not found. Cannot get notifications.", 'ERROR');
            return [];
        }
        
        return db_fetch_all(
            "SELECT * FROM notifications 
             WHERE user_id = ? 
             ORDER BY created_at DESC 
             LIMIT ?",
            [$user_id, $limit]
        );
    }
}

// =============================================
// URL/REDIRECT FUNCTIONS
// =============================================

/**
 * Get base URL
 */
if (!function_exists('base_url')) {
    function base_url($path = '') {
        $base_url = defined('BASE_URL') ? BASE_URL : '';
        return rtrim($base_url, '/') . '/' . ltrim($path, '/');
    }
}

/**
 * Get assets URL
 */
if (!function_exists('assets_url')) {
    function assets_url($path = '') {
        return base_url('assets/' . ltrim($path, '/'));
    }
}

/**
 * Get uploads URL
 */
if (!function_exists('uploads_url')) {
    function uploads_url($path = '') {
        return base_url('uploads/' . ltrim($path, '/'));
    }
}

/**
 * Redirect to URL
 */
if (!function_exists('redirect')) {
    function redirect($url) {
        header('Location: ' . base_url($url));
        exit;
    }
}

/**
 * Redirect back
 */
if (!function_exists('redirect_back')) {
    function redirect_back($default = '/') {
        $back = $_SERVER['HTTP_REFERER'] ?? base_url($default);
        header('Location: ' . $back);
        exit;
    }
}

/**
 * Refresh page
 */
if (!function_exists('refresh')) {
    function refresh() {
        header('Location: ' . current_url());
        exit;
    }
}

/**
 * Get current URL
 */
if (!function_exists('current_url')) {
    function current_url() {
        $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://';
        return $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    }
}

// =============================================
// AJAX RESPONSE FUNCTIONS
// =============================================

/**
 * Send JSON response
 */
if (!function_exists('json_response')) {
    function json_response($data, $status_code = 200) {
        http_response_code($status_code);
        header('Content-Type: application/json');
        echo json_encode($data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE);
        exit;
    }
}

/**
 * Send success response
 */
if (!function_exists('json_success')) {
    function json_success($data = null, $message = 'Success') {
        json_response([
            'status' => 'success',
            'message' => $message,
            'data' => $data
        ]);
    }
}

/**
 * Send error response
 */
if (!function_exists('json_error')) {
    function json_error($message = 'Error', $errors = null, $status_code = 400) {
        $response = [
            'status' => 'error',
            'message' => $message
        ];
        
        if ($errors !== null) {
            $response['errors'] = $errors;
        }
        
        json_response($response, $status_code);
    }
}

// =============================================
// PERMISSION FUNCTIONS
// =============================================

/**
 * Check if user is logged in
 */
if (!function_exists('is_logged_in')) {
    function is_logged_in() {
        return isset($_SESSION['user_id']);
    }
}

/**
 * Get current user ID
 */
if (!function_exists('current_user_id')) {
    function current_user_id() {
        return $_SESSION['user_id'] ?? null;
    }
}

/**
 * Get current user
 */
if (!function_exists('current_user')) {
    function current_user() {
        if (!is_logged_in()) {
            return null;
        }
        
        static $user = null;
        
        if ($user === null) {
            // Check if db_fetch_one function exists
            if (!function_exists('db_fetch_one')) {
                log_message("db_fetch_one() function not found. Cannot get current user.", 'ERROR');
                return null;
            }
            
            $user = db_fetch_one(
                "SELECT * FROM users WHERE user_id = ?",
                [$_SESSION['user_id']]
            );
        }
        
        return $user;
    }
}

/**
 * Require authentication
 */
if (!function_exists('require_auth')) {
    function require_auth() {
        if (!is_logged_in()) {
            set_flash_message('warning', 'Please log in to continue');
            redirect('login.php?redirect=' . urlencode($_SERVER['REQUEST_URI']));
        }
    }
}

/**
 * Require permission
 */
if (!function_exists('require_permission')) {
    function require_permission($permission_key) {
        if (!function_exists('has_permission')) {
            log_message("has_permission() function not found. Cannot check permission.", 'ERROR');
            return;
        }
        
        if (!has_permission($permission_key)) {
            set_flash_message('danger', 'You do not have permission to access this page');
            redirect('access-denied.php');
        }
    }
}

/**
 * Check if request is AJAX
 */
if (!function_exists('is_ajax_request')) {
    function is_ajax_request() {
        return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && 
               strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
    }
}

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

/**
 * Get setting value
 */
if (!function_exists('get_setting')) {
    function get_setting($key, $default = null) {
        static $settings = null;
        
        // Check if db_fetch_all function exists
        if (!function_exists('db_fetch_all')) {
            log_message("db_fetch_all() function not found. Cannot get settings.", 'ERROR');
            return $default;
        }
        
        if ($settings === null) {
            try {
                $results = db_fetch_all("SELECT setting_key, setting_value FROM system_settings");
                $settings = [];
                foreach ($results as $row) {
                    $settings[$row['setting_key']] = $row['setting_value'];
                }
            } catch (Exception $e) {
                log_message("Failed to load settings: " . $e->getMessage(), 'ERROR');
                $settings = [];
            }
        }
        
        return $settings[$key] ?? $default;
    }
}

/**
 * Format phone number for display
 */
if (!function_exists('format_phone')) {
    function format_phone($phone) {
        if (empty($phone)) return '';
        
        // Simple formatting - can be enhanced based on country
        $phone = preg_replace('/[^0-9+]/', '', $phone);
        
        if (strlen($phone) > 10) {
            return substr($phone, 0, -10) . ' ' . substr($phone, -10, 3) . ' ' . 
                   substr($phone, -7, 3) . ' ' . substr($phone, -4);
        }
        
        return $phone;
    }
}

/**
 * Generate QR code data URL (simplified - would need QR library in production)
 */
if (!function_exists('generate_qr_code')) {
    function generate_qr_code($data) {
        // Placeholder - would use a QR library like phpqrcode in production
        return "https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=" . urlencode($data);
    }
}

/**
 * Get gravatar URL
 */
if (!function_exists('get_gravatar_url')) {
    function get_gravatar_url($email, $size = 80) {
        $hash = md5(strtolower(trim($email)));
        return "https://www.gravatar.com/avatar/{$hash}?s={$size}&d=mp";
    }
}

/**
 * Generate random color
 */
if (!function_exists('random_color')) {
    function random_color() {
        return sprintf('#%06X', mt_rand(0, 0xFFFFFF));
    }
}

/**
 * Check if string contains only digits
 */
if (!function_exists('is_digits')) {
    function is_digits($str) {
        return ctype_digit($str);
    }
}

/**
 * Convert to boolean
 */
if (!function_exists('to_bool')) {
    function to_bool($value) {
        return filter_var($value, FILTER_VALIDATE_BOOLEAN);
    }
}

/**
 * Get microtime as float
 */
if (!function_exists('microtime_float')) {
    function microtime_float() {
        list($usec, $sec) = explode(" ", microtime());
        return ((float)$usec + (float)$sec);
    }
}