<?php
/**
 * Core Functions File
 * Contains helper functions for sanitization, file uploads, routing, and formatting.
 */

// Ensure this file is not accessed directly
if (!defined('DS')) {
    exit('Direct access not permitted.');
}

/**
 * Sanitizes user input to prevent XSS.
 * * @param string $data The input string to sanitize.
 * @return string The sanitized string.
 */
function sanitize_input($data) {
    if (is_null($data)) {
        return '';
    }
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
    return $data;
}

/**
 * Redirects to a specified URL and cleanly exits the script.
 * * @param string $url The URL to redirect to.
 */
function redirect($url) {
    header("Location: " . $url);
    exit();
}

/**
 * Generates an SEO-friendly slug from a string.
 * * @param string $string The string to convert.
 * @return string The generated slug.
 */
function generate_slug($string) {
    // Replace non-letter or digits by divider
    $string = preg_replace('~[^\pL\d]+~u', '-', $string);
    // Transliterate
    $string = iconv('utf-8', 'us-ascii//TRANSLIT', $string);
    // Remove unwanted characters
    $string = preg_replace('~[^-\w]+~', '', $string);
    // Trim
    $string = trim($string, '-');
    // Remove duplicate dividers
    $string = preg_replace('~-+~', '-', $string);
    // Lowercase
    $string = strtolower($string);

    if (empty($string)) {
        return 'n-a';
    }

    return $string;
}

/**
 * Sets a flash message in the session.
 * * @param string $type The type of message (e.g., 'success', 'error').
 * @param string $message The message content.
 */
function set_flash_message($type, $message) {
    $_SESSION['flash_messages'][] = [
        'type' => $type,
        'message' => $message
    ];
}

/**
 * Retrieves and clears flash messages from the session.
 * * @return array Array of flash messages.
 */
function get_flash_messages() {
    if (isset($_SESSION['flash_messages'])) {
        $messages = $_SESSION['flash_messages'];
        unset($_SESSION['flash_messages']);
        return $messages;
    }
    return [];
}

/**
 * Formats a price using the defined currency symbol.
 * * @param float $price The price to format.
 * @return string Formatted price.
 */
function format_price($price) {
    if ($price <= 0) {
        return 'Free';
    }
    return CURRENCY_SYMBOL . number_format($price, 2);
}

/**
 * Formats a date string into a readable format.
 * * @param string $date The database date string.
 * @param string $format The output format.
 * @return string Formatted date.
 */
function format_date($date, $format = 'M j, Y') {
    if (empty($date)) return 'N/A';
    return date($format, strtotime($date));
}

/**
 * Securely uploads a file.
 * * @param array $file The $_FILES array element.
 * @param string $destination_folder The absolute path to the destination folder.
 * @param array $allowed_extensions Array of allowed file extensions.
 * @param array $allowed_mimes Array of allowed MIME types.
 * @param int $max_size Maximum allowed file size in bytes.
 * @return string|false The final file name on success, or false on failure.
 */
function secure_file_upload($file, $destination_folder, $allowed_extensions, $allowed_mimes, $max_size) {
    // Check for upload errors
    if (!isset($file['error']) || is_array($file['error']) || $file['error'] !== UPLOAD_ERR_OK) {
        set_flash_message('error', 'File upload error code: ' . (isset($file['error']) ? $file['error'] : 'Unknown'));
        return false;
    }

    // Check file size
    if ($file['size'] > $max_size) {
        set_flash_message('error', 'File exceeds the maximum allowed size.');
        return false;
    }

    // Verify extension
    $file_info = pathinfo($file['name']);
    $extension = strtolower(isset($file_info['extension']) ? $file_info['extension'] : '');
    if (!in_array($extension, $allowed_extensions)) {
        set_flash_message('error', 'Invalid file extension.');
        return false;
    }

    // Verify MIME type using Fileinfo for strict security
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $mime_type = $finfo->file($file['tmp_name']);
    if (!in_array($mime_type, $allowed_mimes)) {
        set_flash_message('error', 'Invalid file MIME type.');
        return false;
    }

    // Generate a secure, unique file name to prevent overwriting and path traversal
    $new_filename = bin2hex(random_bytes(16)) . '_' . time() . '.' . $extension;
    $destination_path = $destination_folder . DS . $new_filename;

    // Move the uploaded file
    if (move_uploaded_file($file['tmp_name'], $destination_path)) {
        return $new_filename;
    }

    set_flash_message('error', 'Failed to move the uploaded file to the destination.');
    return false;
}

/**
 * Helper function to retrieve all active settings from the database.
 * * @param PDO $pdo The PDO connection instance.
 * @return array Associative array of settings.
 */
function get_site_settings($pdo) {
    $stmt = $pdo->prepare("SELECT * FROM settings LIMIT 1");
    $stmt->execute();
    return $stmt->fetch();
}