<?php
/**
 * Security Functions - WeaverSM
 */

function generateCSRFToken() {
    if (empty($_SESSION['csrf_token']) || empty($_SESSION['csrf_token_time']) || 
        (time() - $_SESSION['csrf_token_time']) > CSRF_TOKEN_EXPIRY) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        $_SESSION['csrf_token_time'] = time();
    }
    return $_SESSION['csrf_token'];
}

function verifyCSRFToken($token) {
    if (empty($_SESSION['csrf_token']) || empty($token)) return false;
    if ((time() - $_SESSION['csrf_token_time']) > CSRF_TOKEN_EXPIRY) return false;
    return hash_equals($_SESSION['csrf_token'], $token);
}

function csrfTokenField() {
    return '<input type="hidden" name="csrf_token" value="' . htmlspecialchars(generateCSRFToken()) . '">';
}

function sanitize($input) {
    if (is_array($input)) return array_map('sanitize', $input);
    return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
}

function sanitizeEmail($email) {
    return filter_var(trim($email), FILTER_SANITIZE_EMAIL);
}

function isValidEmail($email) {
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

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

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

function generateToken($length = 32) {
    return bin2hex(random_bytes($length));
}

function getClientIP() {
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) return $_SERVER['HTTP_CLIENT_IP'];
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) return explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0];
    return $_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN';
}

function checkLoginAttempts($email) {
    $pdo = getDBConnection();
    $ip = getClientIP();
    $lockoutTime = date('Y-m-d H:i:s', strtotime('-' . LOCKOUT_DURATION . ' minutes'));
    $stmt = $pdo->prepare("SELECT COUNT(*) FROM login_attempts WHERE (email = ? OR ip_address = ?) AND attempted_at > ?");
    $stmt->execute([$email, $ip, $lockoutTime]);
    return $stmt->fetchColumn() < MAX_LOGIN_ATTEMPTS;
}

function recordLoginAttempt($email) {
    $pdo = getDBConnection();
    $stmt = $pdo->prepare("INSERT INTO login_attempts (email, ip_address) VALUES (?, ?)");
    $stmt->execute([$email, getClientIP()]);
}

function clearLoginAttempts($email) {
    $pdo = getDBConnection();
    $stmt = $pdo->prepare("DELETE FROM login_attempts WHERE email = ? OR ip_address = ?");
    $stmt->execute([$email, getClientIP()]);
}

function regenerateSession() {
    session_regenerate_id(true);
    $_SESSION['last_activity'] = time();
}

function logActivity($userId, $action, $description = null) {
    try {
        $pdo = getDBConnection();
        $stmt = $pdo->prepare("INSERT INTO activity_logs (user_id, action, description, ip_address) VALUES (?, ?, ?, ?)");
        $stmt->execute([$userId, $action, $description, getClientIP()]);
    } catch (Exception $e) {
        // Silently fail
    }
}

function isStrongPassword($password) {
    if (strlen($password) < 8) return ['valid' => false, 'message' => 'Password must be at least 8 characters'];
    if (!preg_match('/[A-Z]/', $password)) return ['valid' => false, 'message' => 'Password must contain uppercase letter'];
    if (!preg_match('/[a-z]/', $password)) return ['valid' => false, 'message' => 'Password must contain lowercase letter'];
    if (!preg_match('/[0-9]/', $password)) return ['valid' => false, 'message' => 'Password must contain a number'];
    return ['valid' => true, 'message' => 'Password is strong'];
}
