<?php
/**
 * Kontroler autoryzacji
 */

require_once __DIR__ . '/BaseController.php';

class AuthController extends BaseController
{
    private ?LoginSecurity $loginSecurity = null;
    private AuditLog $auditLog;
    
    public function __construct()
    {
        parent::__construct();
        $this->auditLog = new AuditLog();
    }
    
    private function getLoginSecurity(): LoginSecurity
    {
        if ($this->loginSecurity === null) {
            $this->loginSecurity = new LoginSecurity();
        }
        return $this->loginSecurity;
    }
    
    /**
     * Logowanie
     */
    public function login(): void
    {
        // Jeśli już zalogowany, przekieruj do dashboard
        if ($this->auth->check()) {
            $this->redirect('dashboard');
            return;
        }
        
        $security = $this->getLoginSecurity();

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $username = trim(post('username', ''));
            $password = post('password', '');
            $remember = (bool)post('remember');

            // Sprawdź czy IP jest zablokowane
            if ($security->isIpBlocked()) {
                $blockedUntil = $security->getBlockedUntil();
                $this->render('login.tpl', [
                    'error' => 'Za dużo nieudanych prób. Spróbuj ponownie po ' . date('H:i', strtotime($blockedUntil)),
                    'username' => $username
                ]);
                return;
            }

            if (empty($username) || empty($password)) {
                $this->render('login.tpl', [
                    'error' => 'Podaj nazwę użytkownika i hasło.',
                    'username' => $username
                ]);
                return;
            }

            $result = $this->auth->login($username, $password, $remember);

            if ($result['success']) {
                // Zapisz udane logowanie
                $security->logLogin($result['user']['id'], true);
                
                // Audit log - udane logowanie
                $this->auditLog->log(
                    AuditLog::ENTITY_USER,
                    $result['user']['id'],
                    'login',
                    null,
                    ['username' => $username, 'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown']
                );
                
                $this->redirect('dashboard');
            } else {
                // Zapisz nieudane logowanie
                $attemptResult = $security->recordFailedAttempt($username);
                
                // Jeśli użytkownik istnieje, zapisz w historii
                $userModel = new User();
                $user = $userModel->getByUsername($username);
                if ($user) {
                    $security->logLogin($user['id'], false, $result['error']);
                    
                    // Audit log - nieudane logowanie
                    $this->auditLog->log(
                        AuditLog::ENTITY_USER,
                        $user['id'],
                        'login_failed',
                        null,
                        ['username' => $username, 'reason' => $result['error'], 'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown']
                    );
                }
                
                $error = $result['error'];
                if ($attemptResult['blocked']) {
                    $error = 'Za dużo nieudanych prób. Konto tymczasowo zablokowane.';
                } elseif ($attemptResult['remaining'] <= 2) {
                    $error .= " (Pozostało prób: {$attemptResult['remaining']})";
                }
                
                $this->render('login.tpl', [
                    'error' => $error,
                    'username' => $username
                ]);
            }
            return;
        }

        $this->render('login.tpl');
    }

    /**
     * Wylogowanie
     */
    public function logout(): void
    {
        $userId = $this->currentUser['id'] ?? null;
        $username = $this->currentUser['username'] ?? 'unknown';
        
        $this->auth->logout();
        
        // Audit log - wylogowanie
        if ($userId) {
            $this->auditLog->log(
                AuditLog::ENTITY_USER,
                $userId,
                'logout',
                null,
                ['username' => $username]
            );
        }
        
        $this->redirect('login', 'success', 'Zostałeś wylogowany.');
    }

    /**
     * Zmiana hasła
     */
    public function changePassword(): void
    {
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            if (!$this->verifyCsrf()) {
                return;
            }

            $currentPassword = post('current_password', '');
            $newPassword = post('new_password', '');
            $confirmPassword = post('confirm_password', '');

            if (empty($currentPassword) || empty($newPassword)) {
                if (isAjax()) {
                    $this->json(['success' => false, 'error' => 'Wszystkie pola są wymagane.']);
                } else {
                    $this->redirect('dashboard', 'danger', 'Wszystkie pola są wymagane.');
                }
                return;
            }

            if ($newPassword !== $confirmPassword) {
                if (isAjax()) {
                    $this->json(['success' => false, 'error' => 'Hasła nie są identyczne.']);
                } else {
                    $this->redirect('dashboard', 'danger', 'Hasła nie są identyczne.');
                }
                return;
            }

            $result = $this->auth->changePassword(
                $this->currentUser['id'],
                $currentPassword,
                $newPassword
            );

            // Audit log - zmiana hasła
            if ($result['success']) {
                $this->auditLog->log(
                    AuditLog::ENTITY_USER,
                    $this->currentUser['id'],
                    'password_changed',
                    null,
                    ['username' => $this->currentUser['username']]
                );
            }

            if (isAjax()) {
                $this->json($result);
            } else {
                if ($result['success']) {
                    $this->redirect('dashboard', 'success', 'Hasło zostało zmienione.');
                } else {
                    $this->redirect('dashboard', 'danger', $result['error']);
                }
            }
            return;
        }

        $this->redirect('dashboard');
    }
}
