<?php
/**
 * Security Configuration - COMPLETE VERSION WITH PHPDOC
 */

class Security {
    
    /**
     * Generate CSRF Token
     * 
     * @return string
     */
    public static function generateCSRFToken() {
        if (!isset($_SESSION['csrf_token'])) {
            $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
            $_SESSION['csrf_token_time'] = time();
        }
        return $_SESSION['csrf_token'];
    }
    
    /**
     * Validate CSRF Token
     * 
     * @param string $token
     * @return bool
     */
    public static function validateCSRFToken($token) {
        if (!isset($_SESSION['csrf_token'])) {
            return false;
        }
        return hash_equals($_SESSION['csrf_token'], $token);
    }
    
    /**
     * Hash password
     * 
     * @param string $password
     * @return string
     */
    public static function hashPassword($password) {
        return password_hash($password, PASSWORD_DEFAULT);
    }
    
    /**
     * Verify password
     * 
     * @param string $password
     * @param string $hash
     * @return bool
     */
    public static function verifyPassword($password, $hash) {
        return password_verify($password, $hash);
    }
    
    /**
     * AES-256 Encryption
     * 
     * @param string $data
     * @return string
     */
    public static function encrypt($data) {
        $key = hex2bin(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($iv . $encrypted);
    }
    
    /**
     * AES-256 Decryption
     * 
     * @param string $data
     * @return string|false
     */
    public static function decrypt($data) {
        $key = hex2bin(ENCRYPTION_KEY);
        $data = base64_decode($data);
        $iv_length = openssl_cipher_iv_length('aes-256-cbc');
        $iv = substr($data, 0, $iv_length);
        $encrypted = substr($data, $iv_length);
        return openssl_decrypt($encrypted, 'aes-256-cbc', $key, 0, $iv);
    }
    
    /**
     * Sanitize input
     * 
     * @param mixed $input
     * @return mixed
     */
    public static function sanitize($input) {
        if (is_array($input)) {
            return array_map([self::class, 'sanitize'], $input);
        }
        return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
    }
    
    /**
     * Validate email
     * 
     * @param string $email
     * @return bool
     */
    public static function validateEmail($email) {
        return filter_var($email, FILTER_VALIDATE_EMAIL);
    }
    
    /**
     * Generate CSRF field HTML
     * 
     * @return string
     */
    public static function generateCSRFField() {
        $token = self::generateCSRFToken();
        return '<input type="hidden" name="csrf_token" value="' . $token . '">';
    }
    
    /**
     * Generate secure random string
     * 
     * @param int $length
     * @return string
     */
    public static function generateSecureString($length = 32) {
        return bin2hex(random_bytes($length / 2));
    }
    
    /**
     * Check rate limiting for login attempts
     * 
     * @param string $ip
     * @param string|null $username
     * @return bool
     */
    public static function checkLoginRateLimit($ip, $username = null) {
        $db = \Database::getInstance()->getConnection();
        
        $stmt = $db->prepare("
            SELECT COUNT(*) as attempts 
            FROM login_attempts 
            WHERE (ip_address = ? OR username = ?)
            AND attempt_time > DATE_SUB(NOW(), INTERVAL ? MINUTE)
        ");
        
        $stmt->execute([$ip, $username, LOGIN_TIMEOUT_MINUTES]);
        $result = $stmt->fetch();
        
        return $result['attempts'] < MAX_LOGIN_ATTEMPTS;
    }
    
    /**
     * Log login attempt
     * 
     * @param string $username
     * @param string $ip
     * @param bool $success
     * @return void
     */
    public static function logLoginAttempt($username, $ip, $success) {
        $db = \Database::getInstance()->getConnection();
        
        $stmt = $db->prepare("
            INSERT INTO login_attempts (username, ip_address, attempt_time, success)
            VALUES (?, ?, NOW(), ?)
        ");
        
        $stmt->execute([$username, $ip, $success ? 1 : 0]);
    }
}