<?php
// Security.php

class Security {
    private $db;
    
    public function __construct($db) {
        $this->db = $db;
    }
    
    // Rate limiting for login attempts
    public function checkLoginAttempts($ip_address) {
        $stmt = $this->db->prepare("
            SELECT COUNT(*) as attempts 
            FROM login_attempts 
            WHERE ip_address = ? 
            AND attempted_at > DATE_SUB(NOW(), INTERVAL 15 MINUTE)
            AND success = FALSE
        ");
        
        $stmt->execute([$ip_address]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($result['attempts'] >= 5) {
            throw new Exception('Too many login attempts. Please try again later.');
        }
    }
    
    // Log login attempt
    public function logLoginAttempt($userId, $ip_address, $success) {
        $stmt = $this->db->prepare("
            INSERT INTO login_attempts (user_id, ip_address, success)
            VALUES (?, ?, ?)
        ");
        
        $stmt->execute([$userId, $ip_address, $success]);
    }
    
    // Generate secure random token
    public function generateToken($length = 32) {
        return bin2hex(random_bytes($length));
    }
    
    // Validate password strength
    public function validatePassword($password) {
        $errors = [];
        
        if (strlen($password) < 8) {
            $errors[] = 'Password must be at least 8 characters long';
        }
        
        if (!preg_match('/[A-Z]/', $password)) {
            $errors[] = 'Password must contain at least one uppercase letter';
        }
        
        if (!preg_match('/[a-z]/', $password)) {
            $errors[] = 'Password must contain at least one lowercase letter';
        }
        
        if (!preg_match('/[0-9]/', $password)) {
            $errors[] = 'Password must contain at least one number';
        }
        
        if (!preg_match('/[^A-Za-z0-9]/', $password)) {
            $errors[] = 'Password must contain at least one special character';
        }
        
        return $errors;
    }
    
    // Sanitize input
    public function sanitize($input) {
        if (is_array($input)) {
            return array_map([$this, 'sanitize'], $input);
        }
        
        return htmlspecialchars(strip_tags(trim($input)));
    }
    
    // Validate file upload
    public function validateFile($file, $allowedTypes, $maxSize) {
        if ($file['size'] > $maxSize) {
            throw new Exception('File size exceeds maximum limit');
        }
        
        $fileType = mime_content_type($file['tmp_name']);
        if (!in_array($fileType, $allowedTypes)) {
            throw new Exception('Invalid file type');
        }
        
        return true;
    }
    
    // Check if user is verified
    public function isVerified($userId) {
        $stmt = $this->db->prepare("
            SELECT email_verified 
            FROM users 
            WHERE id = ?
        ");
        
        $stmt->execute([$userId]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        
        return $result['email_verified'] ?? false;
    }
    
    // Create email verification token
    public function createVerificationToken($userId) {
        $token = $this->generateToken();
        $expires = date('Y-m-d H:i:s', strtotime('+24 hours'));
        
        $stmt = $this->db->prepare("
            INSERT INTO email_verification_tokens (user_id, token, expires_at)
            VALUES (?, ?, ?)
        ");
        
        $stmt->execute([$userId, $token, $expires]);
        
        return $token;
    }
    
    // Verify email token
    public function verifyEmailToken($token) {
        $stmt = $this->db->prepare("
            SELECT user_id 
            FROM email_verification_tokens 
            WHERE token = ? 
            AND expires_at > NOW()
            AND created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)
        ");
        
        $stmt->execute([$token]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$result) {
            throw new Exception('Invalid or expired token');
        }
        
        // Update user verification status
        $stmt = $this->db->prepare("
            UPDATE users 
            SET email_verified = TRUE 
            WHERE id = ?
        ");
        
        $stmt->execute([$result['user_id']]);
        
        // Delete used token
        $stmt = $this->db->prepare("
            DELETE FROM email_verification_tokens 
            WHERE token = ?
        ");
        
        $stmt->execute([$token]);
        
        return true;
    }
}r