<?php
    declare(strict_types=1);
    date_default_timezone_set('America/New_York'); // Change to your Preferred Time Zone

    // Enforce HTTPS
    if (empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === 'off') {
        $redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
        header('HTTP/1.1 301 Moved Permanently');
        header('Location: ' . $redirect);
        exit();
    }

    if (session_status() === PHP_SESSION_NONE) {
        session_set_cookie_params([
            'lifetime' => 1200, // Session Lifetime (in seconds)
            'path' => '/',
            'secure' => isset($_SERVER['HTTPS']),
            'httponly' => true,
            'samesite' => 'Lax'
        ]);
        session_start();
    }

    // Regenerate Session ID to Prevent Session Hijacking
    if (!isset($_SESSION['CREATED'])) {
        $_SESSION['CREATED'] = time();
    } else if (time() - $_SESSION['CREATED'] > 1800) {
        // Regenerate Session ID every 30 Minutes
        session_regenerate_id(true);
        $_SESSION['CREATED'] = time();
    }

    // Store and Verify IP and User Agent to Prevent Session Hijacking
    if (!isset($_SESSION['IPaddress']) || !isset($_SESSION['userAgent'])) {
        $_SESSION['IPaddress'] = $_SERVER['REMOTE_ADDR'];
        $_SESSION['userAgent'] = $_SERVER['HTTP_USER_AGENT'];
    } else if ($_SESSION['IPaddress'] !== $_SERVER['REMOTE_ADDR'] || $_SESSION['userAgent'] !== $_SERVER['HTTP_USER_AGENT']) {
        // Session Hijacking Attempts
        session_unset();
        session_destroy();
        header("Location: /home/");
        exit();
    }

    include_once __DIR__ . '/PDO-DBConnect.php';

    // Directory to Log File for Data Logging
    $logFilePath = __DIR__ . '/../logs/log.csv';
    $ip = $_SERVER['REMOTE_ADDR'];
    $time = date("Y-m-d H:i:s");
    $script = $_SERVER['PHP_SELF'];
    $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
    $requestMethod = $_SERVER['REQUEST_METHOD'];
    $queryString = $_SERVER['QUERY_STRING'];
    $sessionId = session_id();

    // Define the Log Data
    $logData = [
        'ip' => $ip,
        'time' => $time,
        'script' => $script,
        'user_agent' => $userAgent,
        'request_method' => $requestMethod,
        'query_string' => $queryString,
        'session_id' => $sessionId
    ];

    // Ensure Log Directory Exists or Create it
    $logDir = dirname($logFilePath);
    if (!file_exists($logDir)) {
        if (!mkdir($logDir, 0755, true) && !is_dir($logDir)) {
            error_log("Failed to Create Log Directory: $logDir");
            throw new RuntimeException(sprintf('Directory "%s" was not Created', $logDir));
        }
    }

    // Write Log Data to File
    $file = fopen($logFilePath, 'a');
    if ($file !== false) {
        fputcsv($file, $logData);
        fclose($file);
    } else {
        error_log("Failed to Open Log File for Writing.");
    }

    // Input Sanitization
    if (!function_exists('sanitize_input')) {
        function sanitize_input(string $input): string {
            return htmlspecialchars($input, ENT_QUOTES | ENT_HTML5, 'UTF-8');
        }
    }

    // User Activity Tracking
    $_SESSION['LAST_ACTIVITY'] = time();

    // Input Validation
    function validate_input(string $input): string {
        return trim($input);
    }

    // Output Escaping
    function escape_output(string $output): string {
        return htmlspecialchars($output, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    }

    // Content Security Policy (CSP)
    header("Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.jsdelivr.net http://www.shaiyadahlia.com https://www.paypal.com https://kit.fontawesome.com https://ajax.googleapis.com https://cdnjs.cloudflare.com 'unsafe-inline'; style-src 'self' https://cdn.jsdelivr.net https://www.paypalobjects.com https://cdnjs.cloudflare.com 'unsafe-inline'; img-src 'self' https://www.paypalobjects.com blob: data:; frame-src 'self' https://www.paypal.com https://www.sandbox.paypal.com; connect-src 'self' https://api.paypal.com https://www.sandbox.paypal.com https://www.paypal.com https://ka-f.fontawesome.com; font-src 'self' https://ka-f.fontawesome.com; object-src 'none'; frame-ancestors 'none';");

    // Generate CSRF Tokens
    if (!isset($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }

    // Verify CSRF Tokens
    function verify_csrf_token($token) {
        return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
    }

    // Handle Database Errors
    function handle_database_error($pdo, $query) {
        $errorInfo = $pdo->errorInfo();
        $errorMessage = isset($errorInfo[2]) ? $errorInfo[2] : 'Unknown error';
        log_error("Database error on query: $query | Error: $errorMessage");
        echo "An unexpected error occurred. Please try again later.";
    }

    // Execute Prepared Statement Function
    function execute_prepared_statement($pdo, $query, $params) {
        $stmt = $pdo->prepare($query);
        if ($stmt === false) {
            handle_database_error($pdo, $query);
            return false;
        }

        if ($stmt->execute($params) === false) {
            handle_database_error($pdo, $query);
            return false;
        }

        return $stmt;
    }

    // Error Messaging
    function display_error_message() {
        echo "An Unexpected Error Occurred. Please Try Again Later.";
    }

    // Error Logging
    function log_error(string $error_message) {
        $logFilePath = __DIR__ . '/../../logs/error.log';
        $logMessage = '[' . date('Y-m-d H:i:s') . '] ' . $error_message . PHP_EOL;
        file_put_contents($logFilePath, $logMessage, FILE_APPEND | LOCK_EX);
    }
?>