<?php

namespace Tests\Unit;

use Tests\BaseTestCase;

/**
 * AuthController Unit Tests
 * Tests specific authentication controller functionality
 */
class AuthControllerTest extends BaseTestCase {
    
    private $authController;
    
    protected function setUp(): void {
        parent::setUp();
        resetTestDatabase();
        $this->authController = new \AuthController();
    }
    
    /**
     * Test login with valid credentials
     */
    public function testLoginWithValidCredentials() {
        // Create test user
        $username = 'testuser';
        $password = 'testpass123';
        $email = 'test@example.com';
        
        $userModel = new \User();
        $userId = $userModel->create([
            'username' => $username,
            'password' => $password,
            'email' => $email,
            'is_active' => 1
        ]);
        
        $this->assertNotFalse($userId);
        
        // Simulate POST request
        $_SERVER['REQUEST_METHOD'] = 'POST';
        $_POST['username'] = $username;
        $_POST['password'] = $password;
        
        // Authenticate
        $user = $userModel->authenticate($username, $password);
        
        $this->assertNotFalse($user);
        $this->assertInstanceOf(\User::class, $user);
        $this->assertEquals($username, $user->username);
        $this->assertEquals($email, $user->email);
    }
    
    /**
     * Test login with invalid credentials
     */
    public function testLoginWithInvalidCredentials() {
        // Create test user
        $username = 'testuser';
        $password = 'testpass123';
        
        $userModel = new \User();
        $userModel->create([
            'username' => $username,
            'password' => $password,
            'email' => 'test@example.com',
            'is_active' => 1
        ]);
        
        // Try to authenticate with wrong password
        $user = $userModel->authenticate($username, 'wrongpassword');
        
        $this->assertFalse($user);
    }
    
    /**
     * Test login with empty credentials
     */
    public function testLoginWithEmptyCredentials() {
        $userModel = new \User();
        
        // Try to authenticate with empty credentials
        $user = $userModel->authenticate('', '');
        
        $this->assertFalse($user);
    }
    
    /**
     * Test login with non-existent user
     */
    public function testLoginWithNonExistentUser() {
        $userModel = new \User();
        
        // Try to authenticate with non-existent user
        $user = $userModel->authenticate('nonexistent', 'password');
        
        $this->assertFalse($user);
    }
    
    /**
     * Test logout functionality
     */
    public function testLogoutFunctionality() {
        // Create and authenticate user
        $username = 'testuser';
        $password = 'testpass123';
        
        $userModel = new \User();
        $userId = $userModel->create([
            'username' => $username,
            'password' => $password,
            'email' => 'test@example.com',
            'is_active' => 1
        ]);
        
        $user = $userModel->authenticate($username, $password);
        $sessionId = $user->createSession();
        
        // Verify session exists
        $this->assertTrue(isset($_SESSION['user_id']));
        $this->assertEquals($userId, $_SESSION['user_id']);
        
        // Logout
        $result = $user->destroySession();
        
        $this->assertTrue($result);
        $this->assertFalse(isset($_SESSION['user_id']));
    }
    
    /**
     * Test session validation
     */
    public function testSessionValidation() {
        // Create and authenticate user
        $username = 'testuser';
        $password = 'testpass123';
        
        $userModel = new \User();
        $userId = $userModel->create([
            'username' => $username,
            'password' => $password,
            'email' => 'test@example.com',
            'is_active' => 1
        ]);
        
        $user = $userModel->authenticate($username, $password);
        $user->createSession();
        
        // Validate session
        $isValid = $userModel->validateSession($userId);
        $this->assertTrue($isValid);
        
        // Logout and validate again
        $user->destroySession();
        
        // Restart session for validation
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
        
        $isValid = $userModel->validateSession($userId);
        $this->assertFalse($isValid);
    }
    
    /**
     * Test that inactive users cannot login
     */
    public function testInactiveUserCannotLogin() {
        // Create inactive user
        $username = 'inactiveuser';
        $password = 'testpass123';
        
        $userModel = new \User();
        $userId = $userModel->create([
            'username' => $username,
            'password' => $password,
            'email' => 'inactive@example.com',
            'is_active' => 0
        ]);
        
        // Try to authenticate
        $user = $userModel->authenticate($username, $password);
        
        $this->assertFalse($user);
    }
    
    /**
     * Test getCurrentUser method
     */
    public function testGetCurrentUser() {
        // Create and authenticate user
        $username = 'testuser';
        $password = 'testpass123';
        $email = 'test@example.com';
        
        $userModel = new \User();
        $userId = $userModel->create([
            'username' => $username,
            'password' => $password,
            'email' => $email,
            'is_active' => 1
        ]);
        
        $user = $userModel->authenticate($username, $password);
        $user->createSession();
        
        // Get current user
        $currentUser = $this->authController->getCurrentUser();
        
        $this->assertNotNull($currentUser);
        $this->assertInstanceOf(\User::class, $currentUser);
        $this->assertEquals($username, $currentUser->username);
        $this->assertEquals($email, $currentUser->email);
    }
    
    /**
     * Test password hashing
     */
    public function testPasswordHashing() {
        $password = 'testpass123';
        
        $userModel = new \User();
        $userId = $userModel->create([
            'username' => 'testuser',
            'password' => $password,
            'email' => 'test@example.com',
            'is_active' => 1
        ]);
        
        // Get user from database
        $user = $userModel->findById($userId);
        
        // Verify password is hashed
        $this->assertNotEquals($password, $user->password_hash);
        $this->assertTrue(password_verify($password, $user->password_hash));
    }
}
