<?php
require_once 'Database.php';
require_once 'Security.php';

class User {
    private $db;
    
    public function __construct() {
        $this->db = new Database();
    }
    
    // Register new user
    public function register($data) {
        try {
            // Validate input
            if (!Security::validateEmail($data['email'])) {
                return ['success' => false, 'message' => 'Invalid email address'];
            }
            
            if (strlen($data['password']) < 8) {
                return ['success' => false, 'message' => 'Password must be at least 8 characters'];
            }
            
            // Check if user exists
            $this->db->query("SELECT id FROM users WHERE email = :email OR username = :username");
            $this->db->bind(':email', $data['email']);
            $this->db->bind(':username', $data['username']);
            
            if ($this->db->single()) {
                return ['success' => false, 'message' => 'User already exists'];
            }
            
            // Hash password
            $passwordHash = Security::hashPassword($data['password']);
            $verificationToken = Security::generateToken();
            
            // Insert user
            $this->db->query("INSERT INTO users (username, email, password_hash, first_name, last_name, phone, country, verification_token) 
                             VALUES (:username, :email, :password, :fname, :lname, :phone, :country, :token)");
            
            $this->db->bind(':username', $data['username']);
            $this->db->bind(':email', $data['email']);
            $this->db->bind(':password', $passwordHash);
            $this->db->bind(':fname', $data['first_name']);
            $this->db->bind(':lname', $data['last_name']);
            $this->db->bind(':phone', $data['phone'] ?? '');
            $this->db->bind(':country', $data['country'] ?? '');
            $this->db->bind(':token', $verificationToken);
            
            if ($this->db->execute()) {
                $userId = $this->db->lastInsertId();
                
                // Create initial wallets for all cryptocurrencies
                $this->createInitialWallets($userId);
                
                Security::logSecurityEvent('USER_REGISTERED', 'New user registered: ' . $data['username'], $userId);
                
                return [
                    'success' => true, 
                    'message' => 'Registration successful',
                    'user_id' => $userId,
                    'verification_token' => $verificationToken
                ];
            }
            
            return ['success' => false, 'message' => 'Registration failed'];
            
        } catch (Exception $e) {
            error_log('Registration error: ' . $e->getMessage());
            return ['success' => false, 'message' => 'Registration failed'];
        }
    }
    
    // Login user
    public function login($email, $password) {
        try {
            // Check rate limiting
            if (!Security::checkRateLimit('login_' . $_SERVER['REMOTE_ADDR'])) {
                return ['success' => false, 'message' => 'Too many login attempts. Please try again later.'];
            }
            
            // Get user
            $this->db->query("SELECT * FROM users WHERE email = :email");
            $this->db->bind(':email', $email);
            $user = $this->db->single();
            
            if (!$user) {
                Security::logSecurityEvent('LOGIN_FAILED', 'Invalid email: ' . $email);
                return ['success' => false, 'message' => 'Invalid credentials'];
            }
            
            // Check if account is locked
            if ($user['locked_until'] && strtotime($user['locked_until']) > time()) {
                return ['success' => false, 'message' => 'Account temporarily locked'];
            }
            
            // Verify password
            if (!Security::verifyPassword($password, $user['password_hash'])) {
                $this->incrementLoginAttempts($user['id']);
                Security::logSecurityEvent('LOGIN_FAILED', 'Invalid password for: ' . $email, $user['id']);
                return ['success' => false, 'message' => 'Invalid credentials'];
            }
            
            // Check if account is active
            if (!$user['is_active']) {
                return ['success' => false, 'message' => 'Account is deactivated'];
            }
            
            // Reset login attempts
            $this->resetLoginAttempts($user['id']);
            
            // Create session
            session_regenerate_id(true);
            $_SESSION['user_id'] = $user['id'];
            $_SESSION['username'] = $user['username'];
            $_SESSION['email'] = $user['email'];
            $_SESSION['is_admin'] = $user['is_admin'];
            $_SESSION['user_authenticated'] = true;
            $_SESSION['login_time'] = time();
            
            Security::logSecurityEvent('LOGIN_SUCCESS', 'User logged in', $user['id']);
            
            return [
                'success' => true, 
                'message' => 'Login successful',
                'user' => [
                    'id' => $user['id'],
                    'username' => $user['username'],
                    'email' => $user['email'],
                    'is_admin' => $user['is_admin']
                ]
            ];
            
        } catch (Exception $e) {
            error_log('Login error: ' . $e->getMessage());
            return ['success' => false, 'message' => 'Login failed'];
        }
    }
    
    // Logout user
    public function logout() {
        if (isset($_SESSION['user_id'])) {
            Security::logSecurityEvent('LOGOUT', 'User logged out', $_SESSION['user_id']);
        }
        
        session_destroy();
        session_start();
        session_regenerate_id(true);
    }
    
    // Get user by ID
    public function getUserById($id) {
        $this->db->query("SELECT * FROM users WHERE id = :id");
        $this->db->bind(':id', $id);
        return $this->db->single();
    }
    
    // Update user profile
    public function updateProfile($userId, $data) {
        try {
            $this->db->query("UPDATE users SET 
                             first_name = :fname, 
                             last_name = :lname, 
                             phone = :phone, 
                             country = :country, 
                             address = :address,
                             date_of_birth = :dob
                             WHERE id = :id");
            
            $this->db->bind(':fname', $data['first_name']);
            $this->db->bind(':lname', $data['last_name']);
            $this->db->bind(':phone', $data['phone']);
            $this->db->bind(':country', $data['country']);
            $this->db->bind(':address', $data['address']);
            $this->db->bind(':dob', $data['date_of_birth']);
            $this->db->bind(':id', $userId);
            
            if ($this->db->execute()) {
                Security::logSecurityEvent('PROFILE_UPDATED', 'User profile updated', $userId);
                return ['success' => true, 'message' => 'Profile updated successfully'];
            }
            
            return ['success' => false, 'message' => 'Update failed'];
            
        } catch (Exception $e) {
            error_log('Profile update error: ' . $e->getMessage());
            return ['success' => false, 'message' => 'Update failed'];
        }
    }
    
    // Create initial wallets for new user
    private function createInitialWallets($userId) {
        $this->db->query("INSERT INTO wallets (user_id, crypto_id, wallet_address) 
                         SELECT :user_id, id, CONCAT(:user_id, '_', symbol, '_', UNIX_TIMESTAMP()) 
                         FROM cryptocurrencies WHERE is_active = 1");
        $this->db->bind(':user_id', $userId);
        $this->db->execute();
    }
    
    // Increment login attempts
    private function incrementLoginAttempts($userId) {
        $this->db->query("UPDATE users SET login_attempts = login_attempts + 1 WHERE id = :id");
        $this->db->bind(':id', $userId);
        $this->db->execute();
        
        // Lock account after max attempts
        $this->db->query("SELECT login_attempts FROM users WHERE id = :id");
        $this->db->bind(':id', $userId);
        $user = $this->db->single();
        
        if ($user['login_attempts'] >= MAX_LOGIN_ATTEMPTS) {
            $lockUntil = date('Y-m-d H:i:s', time() + LOCKOUT_TIME);
            $this->db->query("UPDATE users SET locked_until = :lock_until WHERE id = :id");
            $this->db->bind(':lock_until', $lockUntil);
            $this->db->bind(':id', $userId);
            $this->db->execute();
        }
    }
    
    // Reset login attempts
    private function resetLoginAttempts($userId) {
        $this->db->query("UPDATE users SET login_attempts = 0, locked_until = NULL WHERE id = :id");
        $this->db->bind(':id', $userId);
        $this->db->execute();
    }
}
?>