<?php
// ============================================================================
// includes/functions.php (Helper Functions)
// ============================================================================
/**
 * Sanitize input data
 */
function sanitize($data) {
    if (is_array($data)) {
        return array_map('sanitize', $data);
    }
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
    return $data;
}

/**
 * Validate phone number (Uganda format)
 */
function validatePhone($phone) {
    $phone = preg_replace('/[^0-9+]/', '', $phone);
    
    // +256... format
    if (preg_match('/^\+?256[0-9]{9}$/', $phone)) {
        return preg_replace('/^([^+])/', '+$1', $phone);
    }
    
    // 0... format -> +256...
    if (preg_match('/^0[0-9]{9}$/', $phone)) {
        return '+256' . substr($phone, 1);
    }
    
    return false;
}

/**
 * Format phone number for display
 */
function formatPhone($phone) {
    if (substr($phone, 0, 4) === '+256') {
        return '0' . substr($phone, 4);
    }
    return $phone;
}

/**
 * Validate email address
 */
function validateEmail($email) {
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

/**
 * Hash password
 */
function hashPassword($password) {
    return password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
}

/**
 * Verify password
 */
function verifyPassword($password, $hash) {
    return password_verify($password, $hash);
}

/**
 * Generate random OTP
 */
function generateOTP($length = 6) {
    return str_pad(random_int(0, pow(10, $length) - 1), $length, '0', STR_PAD_LEFT);
}

/**
 * Generate unique order number
 */
function generateOrderNumber() {
    return 'ORD-' . date('Ymd') . '-' . strtoupper(substr(uniqid(), -6));
}

/**
 * Format currency (UGX)
 */
function formatCurrency($amount, $decimals = 0) {
    return 'UGX ' . number_format($amount, $decimals, '.', ',');
}

/**
 * Format number
 */
function formatNumber($number, $decimals = 2) {
    return number_format($number, $decimals, '.', ',');
}

/**
 * Format date
 */
function formatDate($date, $format = 'd M Y') {
    if (empty($date) || $date === '0000-00-00' || $date === '0000-00-00 00:00:00') {
        return 'N/A';
    }
    return date($format, strtotime($date));
}

/**
 * Format datetime
 */
function formatDateTime($datetime, $format = 'd M Y H:i') {
    if (empty($datetime) || $datetime === '0000-00-00 00:00:00') {
        return 'N/A';
    }
    return date($format, strtotime($datetime));
}

/**
 * Time ago function
 */
function timeAgo($datetime) {
    if (empty($datetime)) return 'N/A';
    
    $timestamp = strtotime($datetime);
    $diff = time() - $timestamp;
    
    if ($diff < 60) {
        return 'Just now';
    } elseif ($diff < 3600) {
        $mins = floor($diff / 60);
        return $mins . ' min' . ($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';
    } else {
        return date('d M Y', $timestamp);
    }
}

/**
 * Upload file with validation
 */
function uploadFile($file, $folder = 'general', $allowedTypes = null) {
    try {
        // Validate file exists
        if (!isset($file['tmp_name']) || !is_uploaded_file($file['tmp_name'])) {
            return ['success' => false, 'message' => 'No file uploaded'];
        }
        
        // Check for upload errors
        if ($file['error'] !== UPLOAD_ERR_OK) {
            return ['success' => false, 'message' => 'Upload error: ' . $file['error']];
        }
        
        // Create upload directory
        $uploadDir = UPLOAD_PATH . $folder . '/';
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }
        
        // Get file extension
        $extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        
        // Validate file size
        if ($file['size'] > MAX_FILE_SIZE) {
            return ['success' => false, 'message' => 'File too large. Maximum ' . (MAX_FILE_SIZE/1048576) . 'MB'];
        }
        
        // Validate file type
        if ($allowedTypes === null) {
            $allowedTypes = array_merge(ALLOWED_IMAGE_TYPES, ALLOWED_DOC_TYPES);
        }
        
        if (!in_array($extension, $allowedTypes)) {
            return ['success' => false, 'message' => 'Invalid file type'];
        }
        
        // Generate unique filename
        $filename = uniqid() . '_' . time() . '.' . $extension;
        $filepath = $uploadDir . $filename;
        
        // Move uploaded file
        if (move_uploaded_file($file['tmp_name'], $filepath)) {
            // Optimize image if it's an image file AND GD is available
            if (in_array($extension, ALLOWED_IMAGE_TYPES) && extension_loaded('gd')) {
                optimizeImage($filepath, $extension);
            }
            
            return [
                'success' => true,
                'filename' => $filename,
                'path' => $_ENV['UPLOAD_PATH'] . $folder . '/' . $filename,
                'url' => APP_URL . '/' . $_ENV['UPLOAD_PATH'] . $folder . '/' . $filename
            ];
        }
        
        return ['success' => false, 'message' => 'Failed to move uploaded file'];
        
    } catch (Exception $e) {
        logError('Upload error: ' . $e->getMessage());
        return ['success' => false, 'message' => 'Upload failed'];
    }
}

/**
 * Optimize image
 */
function optimizeImage($filepath, $extension) {
    // Check if GD extension is loaded
    if (!extension_loaded('gd')) {
        logError('GD extension not available for image optimization');
        return false;
    }
    
    try {
        $maxWidth = 1200;
        $maxHeight = 1200;
        $quality = 85;
        
        list($width, $height) = getimagesize($filepath);
        
        // Don't resize if image is already smaller
        if ($width <= $maxWidth && $height <= $maxHeight) {
            return true;
        }
        
        // Calculate new dimensions
        $ratio = min($maxWidth / $width, $maxHeight / $height);
        $newWidth = round($width * $ratio);
        $newHeight = round($height * $ratio);
        
        // Create new image
        $newImage = imagecreatetruecolor($newWidth, $newHeight);
        
        // Load source image
        switch ($extension) {
            case 'jpg':
            case 'jpeg':
                $source = imagecreatefromjpeg($filepath);
                break;
            case 'png':
                $source = imagecreatefrompng($filepath);
                imagealphablending($newImage, false);
                imagesavealpha($newImage, true);
                break;
            case 'gif':
                $source = imagecreatefromgif($filepath);
                break;
            default:
                return false;
        }
        
        if (!$source) {
            return false;
        }
        
        // Resize
        imagecopyresampled($newImage, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
        
        // Save optimized image
        switch ($extension) {
            case 'jpg':
            case 'jpeg':
                imagejpeg($newImage, $filepath, $quality);
                break;
            case 'png':
                imagepng($newImage, $filepath, 9);
                break;
            case 'gif':
                imagegif($newImage, $filepath);
                break;
        }
        
        // Free memory
        imagedestroy($source);
        imagedestroy($newImage);
        
        return true;
    } catch (Exception $e) {
        logError('Image optimization error: ' . $e->getMessage());
        return false;
    }
}

/**
 * Delete file
 */
function deleteFile($filepath) {
    $fullPath = __DIR__ . '/../' . $filepath;
    if (file_exists($fullPath)) {
        return unlink($fullPath);
    }
    return false;
}

/**
 * Redirect with message
 */
function redirect($url, $message = '', $type = 'info') {
    if (!empty($message)) {
        $_SESSION['flash_message'] = $message;
        $_SESSION['flash_type'] = $type;
    }
    
    // Handle relative vs absolute URLs
    if (strpos($url, 'http') !== 0) {
        $url = APP_URL . $url;
    }
    
    header('Location: ' . $url);
    exit();
}

/**
 * Get and clear flash message
 */
function getFlashMessage() {
    if (isset($_SESSION['flash_message'])) {
        $message = $_SESSION['flash_message'];
        $type = $_SESSION['flash_type'] ?? 'info';
        unset($_SESSION['flash_message'], $_SESSION['flash_type']);
        return ['message' => $message, 'type' => $type];
    }
    return null;
}

/**
 * Generate slug from string
 */
function generateSlug($string) {
    $string = strtolower(trim($string));
    $string = preg_replace('/[^a-z0-9-]/', '-', $string);
    $string = preg_replace('/-+/', '-', $string);
    return trim($string, '-');
}

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

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

/**
 * Check if request is POST
 */
function isPost() {
    return $_SERVER['REQUEST_METHOD'] === 'POST';
}

/**
 * Get request method
 */
function getRequestMethod() {
    return $_SERVER['REQUEST_METHOD'];
}

/**
 * Get client IP address
 */
function getClientIP() {
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
        return $_SERVER['HTTP_CLIENT_IP'];
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        return $_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}

/**
 * JSON Response
 */
function jsonResponse($data, $statusCode = 200) {
    http_response_code($statusCode);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($data, JSON_UNESCAPED_UNICODE);
    exit();
}

/**
 * Success JSON response
 */
function jsonSuccess($message, $data = []) {
    jsonResponse([
        'success' => true,
        'message' => $message,
        'data' => $data
    ]);
}

/**
 * Error JSON response
 */
function jsonError($message, $statusCode = 400) {
    jsonResponse([
        'success' => false,
        'message' => $message
    ], $statusCode);
}

/**
 * Log error to file
 */
function logError($message, $file = 'error.log') {
    $logFile = __DIR__ . '/../logs/' . $file;
    $timestamp = date('Y-m-d H:i:s');
    $ip = getClientIP();
    $logMessage = "[{$timestamp}] [{$ip}] {$message}" . PHP_EOL;
    error_log($logMessage, 3, $logFile);
}

/**
 * Log activity
 */
function logActivity($userId, $action, $description = '') {
    try {
        $db = \App\Database::getInstance()->getConnection();
        $sql = "INSERT INTO activity_log (user_id, action, description, ip_address, user_agent)
                VALUES (?, ?, ?, ?, ?)";
        $stmt = $db->prepare($sql);
        $stmt->execute([
            $userId,
            $action,
            $description,
            getClientIP(),
            $_SERVER['HTTP_USER_AGENT'] ?? ''
        ]);
    } catch (Exception $e) {
        logError('Activity log error: ' . $e->getMessage());
    }
}

/**
 * Generate random string
 */
function generateRandomString($length = 32) {
    return bin2hex(random_bytes($length / 2));
}

/**
 * Encrypt data
 */
function encryptData($data) {
    $key = ENCRYPTION_KEY;
    $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
    $encrypted = openssl_encrypt($data, 'aes-256-cbc', $key, 0, $iv);
    return base64_encode($encrypted . '::' . $iv);
}

/**
 * Decrypt data
 */
function decryptData($data) {
    $key = ENCRYPTION_KEY;
    list($encrypted, $iv) = explode('::', base64_decode($data), 2);
    return openssl_decrypt($encrypted, 'aes-256-cbc', $key, 0, $iv);
}

/**
 * Format file size
 */
function formatFileSize($bytes) {
    $units = ['B', 'KB', 'MB', 'GB'];
    $i = 0;
    while ($bytes >= 1024 && $i < count($units) - 1) {
        $bytes /= 1024;
        $i++;
    }
    return round($bytes, 2) . ' ' . $units[$i];
}

/**
 * Check if user has permission
 */
function hasPermission($requiredRole) {
    $userType = getUserType();
    
    // Admin has all permissions
    if ($userType === USER_ADMIN) {
        return true;
    }
    
    // Check specific role
    if (is_array($requiredRole)) {
        return in_array($userType, $requiredRole);
    }
    
    return $userType === $requiredRole;
}

/**
 * Get avatar URL
 */
function getAvatarUrl($profilePicture = null, $defaultIcon = 'person-circle') {
    if (!empty($profilePicture) && file_exists(__DIR__ . '/../' . $profilePicture)) {
        return APP_URL . '/' . $profilePicture;
    }
    return APP_URL . '/assets/images/default-avatar.png';
}

/**
 * Get product category badge color
 */
function getCategoryColor($category) {
    global $PRODUCT_CATEGORIES;
    return $PRODUCT_CATEGORIES[$category]['color'] ?? '#6b7280';
}

/**
 * Get status badge class
 */
function getStatusBadgeClass($status) {
    $classes = [
        'available' => 'bg-success',
        'sold' => 'bg-secondary',
        'reserved' => 'bg-warning',
        'expired' => 'bg-danger',
        'pending' => 'bg-warning',
        'confirmed' => 'bg-info',
        'processing' => 'bg-primary',
        'completed' => 'bg-success',
        'cancelled' => 'bg-danger',
        'accepted' => 'bg-success',
        'blocked' => 'bg-danger'
    ];
    return $classes[$status] ?? 'bg-secondary';
}
?>