<?php
/**
 * OmniCure Network - Shared Security Functions
 * Provides CAPTCHA alternatives, honeypot, rate limiting, and input validation
 * NO EXTERNAL API KEYS REQUIRED
 */

session_start();

/**
 * ===========================================
 * MATH CAPTCHA - Simple addition/subtraction
 * ===========================================
 */

/**
 * Generate a math CAPTCHA question
 * Returns HTML for the question field
 */
function outputMathCaptcha($fieldName = 'captcha_answer') {
    if (session_status() === PHP_SESSION_NONE) session_start();
    
    $num1 = rand(1, 10);
    $num2 = rand(1, 10);
    
    // Randomly choose addition or subtraction
    if (rand(0, 1) === 0 || $num1 < $num2) {
        $operator = '+';
        $answer = $num1 + $num2;
    } else {
        $operator = '-';
        $answer = $num1 - $num2;
    }
    
    $_SESSION['math_captcha_answer'] = $answer;
    $_SESSION['math_captcha_time'] = time();
    
    return "<div class=\"captcha-field\">
    <label for=\"{$fieldName}\">Security Check: What is {$num1} {$operator} {$num2}? *</label>
    <input type=\"number\" name=\"{$fieldName}\" id=\"{$fieldName}\" required autocomplete=\"off\" style=\"width: 100px;\">
</div>";
}

/**
 * Verify math CAPTCHA answer
 */
function verifyMathCaptcha($answer, $fieldName = 'captcha_answer') {
    if (session_status() === PHP_SESSION_NONE) session_start();
    
    if (!isset($_SESSION['math_captcha_answer'])) {
        return ['valid' => false, 'error' => 'CAPTCHA expired. Please refresh and try again.'];
    }
    
    $correctAnswer = $_SESSION['math_captcha_answer'];
    $captchaTime = $_SESSION['math_captcha_time'] ?? 0;
    
    // Clear the captcha after checking
    unset($_SESSION['math_captcha_answer']);
    unset($_SESSION['math_captcha_time']);
    
    // Check if form was submitted too quickly (less than 3 seconds = bot)
    if (time() - $captchaTime < 3) {
        return ['valid' => false, 'error' => 'Form submitted too quickly. Please try again.'];
    }
    
    if ((int)$answer !== (int)$correctAnswer) {
        return ['valid' => false, 'error' => 'Incorrect answer. Please try again.'];
    }
    
    return ['valid' => true, 'error' => ''];
}

/**
 * ===========================================
 * TIME-BASED PROTECTION
 * ===========================================
 */

/**
 * Output a hidden timestamp field
 */
function outputTimestamp($fieldName = 'form_time') {
    $timestamp = time();
    $hash = hash_hmac('sha256', $timestamp, 'omnicure_secret_key_2024');
    return "<input type=\"hidden\" name=\"{$fieldName}\" value=\"{$timestamp}:{$hash}\">";
}

/**
 * Verify the timestamp (minimum 3 seconds, maximum 1 hour)
 */
function verifyTimestamp($value, $minSeconds = 3, $maxSeconds = 3600) {
    if (empty($value) || strpos($value, ':') === false) {
        return ['valid' => false, 'error' => 'Invalid form submission'];
    }
    
    list($timestamp, $hash) = explode(':', $value, 2);
    $expectedHash = hash_hmac('sha256', $timestamp, 'omnicure_secret_key_2024');
    
    if (!hash_equals($expectedHash, $hash)) {
        return ['valid' => false, 'error' => 'Invalid form submission'];
    }
    
    $elapsed = time() - (int)$timestamp;
    
    if ($elapsed < $minSeconds) {
        logSecurityEvent('timestamp', 'Form submitted too quickly', ['elapsed' => $elapsed]);
        return ['valid' => false, 'error' => 'Please take your time filling out the form'];
    }
    
    if ($elapsed > $maxSeconds) {
        return ['valid' => false, 'error' => 'Form expired. Please refresh and try again.'];
    }
    
    return ['valid' => true, 'error' => ''];
}

/**
 * ===========================================
 * HONEYPOT (Bot Trap) - Already exists
 * ===========================================
 */

function outputHoneypot($fieldName = 'website_url') {
    return "<div style=\"position:absolute;left:-9999px;top:-9999px;height:0;width:0;overflow:hidden;\" aria-hidden=\"true\">
    <label for=\"{$fieldName}\">Leave this field empty</label>
    <input type=\"text\" name=\"{$fieldName}\" id=\"{$fieldName}\" autocomplete=\"off\" tabindex=\"-1\">
</div>";
}

function isHoneypotFilled($fieldName = 'website_url') {
    return !empty($_POST[$fieldName]);
}

/**
 * ===========================================
 * RATE LIMITING
 * ===========================================
 */

function checkRateLimit($key, $maxAttempts = 5, $windowSeconds = 300) {
    if (session_status() === PHP_SESSION_NONE) session_start();

    $rateLimitKey = 'rate_limit_' . $key;
    $now = time();

    if (!isset($_SESSION[$rateLimitKey])) {
        $_SESSION[$rateLimitKey] = [];
    }

    $_SESSION[$rateLimitKey] = array_filter($_SESSION[$rateLimitKey], function($timestamp) use ($now, $windowSeconds) {
        return ($now - $timestamp) < $windowSeconds;
    });

    if (count($_SESSION[$rateLimitKey]) >= $maxAttempts) {
        return false;
    }

    $_SESSION[$rateLimitKey][] = $now;
    return true;
}

/**
 * ===========================================
 * INPUT SANITIZATION
 * ===========================================
 */

function sanitizeString($input, $maxLength = 500) {
    if (!is_string($input)) return '';
    $input = trim($input);
    $input = mb_substr($input, 0, $maxLength);
    $input = htmlspecialchars($input, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    return $input;
}

function sanitizeEmail($input) {
    $input = trim($input);
    $input = filter_var($input, FILTER_SANITIZE_EMAIL);
    if (!filter_var($input, FILTER_VALIDATE_EMAIL)) return false;
    return $input;
}

function sanitizePhone($input) {
    $input = trim($input);
    return preg_replace('/[^0-9+\-\s\(\)]/', '', $input);
}

/**
 * ===========================================
 * CSRF PROTECTION
 * ===========================================
 */

function getCSRFToken() {
    if (session_status() === PHP_SESSION_NONE) session_start();
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

function validateCSRF($token) {
    if (session_status() === PHP_SESSION_NONE) session_start();
    return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
}

function outputCSRFField() {
    $token = getCSRFToken();
    return '<input type="hidden" name="csrf_token" value="' . htmlspecialchars($token) . '">';
}

/**
 * ===========================================
 * SECURITY LOGGING
 * ===========================================
 */

function logSecurityEvent($type, $message, $data = []) {
    $logEntry = [
        'timestamp' => date('Y-m-d H:i:s'),
        'type' => $type,
        'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
        'message' => $message
    ];
    error_log('SECURITY [' . $type . ']: ' . $message . ' - ' . json_encode($logEntry));
}

/**
 * ===========================================
 * COMBINED FORM VALIDATION (No external API)
 * ===========================================
 */

function validateFormSubmission($rateLimitKey = 'form_submission', $checkMathCaptcha = false) {
    // Check request method
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        return ['valid' => false, 'error' => 'Invalid request method'];
    }

    // Check honeypot
    if (isHoneypotFilled()) {
        logSecurityEvent('honeypot', 'Bot detected via honeypot field');
        return ['valid' => false, 'error' => 'Bot detected'];
    }

    // Check rate limit
    if (!checkRateLimit($rateLimitKey, 5, 300)) {
        logSecurityEvent('rate_limit', 'Rate limit exceeded');
        return ['valid' => false, 'error' => 'Too many submissions. Please wait a few minutes and try again.'];
    }

    // Check timestamp if provided
    if (!empty($_POST['form_time'])) {
        $timestampCheck = verifyTimestamp($_POST['form_time']);
        if (!$timestampCheck['valid']) {
            return $timestampCheck;
        }
    }

    // Check math captcha if required
    if ($checkMathCaptcha && isset($_POST['captcha_answer'])) {
        $captchaCheck = verifyMathCaptcha($_POST['captcha_answer']);
        if (!$captchaCheck['valid']) {
            return $captchaCheck;
        }
    }

    return ['valid' => true, 'error' => ''];
}

/**
 * ===========================================
 * HELPER: Output all security fields at once
 * ===========================================
 */

function outputSecurityFields($includeMathCaptcha = true) {
    $output = outputHoneypot();
    $output .= outputTimestamp();
    if ($includeMathCaptcha) {
        $output .= outputMathCaptcha();
    }
    return $output;
}
?>
