<?php
/**
 * (c) ININOUT & PYXIS. All Rights Reserved.
 * Wszelkie modyfikacje tego pliku wymagaja zgloszenia oraz zgody autorow.
 * Any modifications to this file require notification and consent of the authors.
 */
/**
 * i-BOK 5 - Panel klienta (router + logowanie)
 */
error_reporting(0);

require_once __DIR__ . '/config.php';
require_once __DIR__ . '/inc/session.php';
require_once __DIR__ . '/inc/security.php';
require_once __DIR__ . '/inc/db_config.php';
config_load_from_db();
require_once __DIR__ . '/inc/auth.php';
require_once __DIR__ . '/inc/functions.php';
require_once __DIR__ . '/inc/ip_access.php';
require_once __DIR__ . '/lang/loader.php';
load_language();

// Kontrola dostępu IP (panel klienta)
if (!ip_access_check('client')) {
    header('HTTP/1.0 403 Forbidden');
    echo '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>403</title>';
    echo '<link href="css/nunito-sans.css" rel="stylesheet"><link rel="stylesheet" href="css/bootstrap.min.css"></head>';
    echo '<body class="d-flex align-items-center justify-content-center vh-100">';
    echo '<div class="text-center"><h1 class="text-danger">403</h1>';
    echo '<p>' . __('access_control.ip_denied') . '</p></div></body></html>';
    exit;
}

// Obsługa wylogowania
if (isset($_GET['action']) && $_GET['action'] === 'logout') {
    auth_logout();
    header('Location: index.php?msg=logged_out');
    exit;
}

// Sprawdzenie licencji i-BOK
require_once __DIR__ . '/inc/db_mysql.php';
$license_ok = db_check_license();

// Obsługa logowania POST
$login_error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['login_client'])) {
    if (!$license_ok) {
        $login_error = __('license.no_license');
    } elseif (!csrf_validate()) {
        $login_error = __('login.error_csrf');
    } else {
        $result = auth_client_login(
            trim($_POST['username'] ?? ''),
            $_POST['password'] ?? ''
        );
        if ($result['success']) {
            if (!empty($result['needs_2fa'])) {
                header('Location: index.php?action=verify2fa');
            } else {
                header('Location: index.php?page=dashboard');
            }
            exit;
        } else {
            if ($result['message'] === 'too_many_attempts') {
                $login_error = __('login.error_rate_limit');
            } else {
                $login_error = __('login.error_credentials');
            }
        }
    }
}

// Komunikat po wylogowaniu
$msg = '';
if (isset($_GET['msg'])) {
    if ($_GET['msg'] === 'logged_out') {
        $msg = __('login.logged_out');
    } elseif ($_GET['msg'] === '2fa_timeout') {
        $msg = __('2fa.error_timeout');
    }
}

// Obsługa weryfikacji 2FA
if (isset($_GET['action']) && $_GET['action'] === 'verify2fa') {
    if (empty($_SESSION['2fa_pending']) || ($_SESSION['2fa_type'] ?? '') !== 'client') {
        header('Location: index.php');
        exit;
    }
    // 2FA timeout (5 minut)
    if (!empty($_SESSION['2fa_started']) && (time() - $_SESSION['2fa_started']) > 300) {
        unset($_SESSION['2fa_pending'], $_SESSION['2fa_type'], $_SESSION['2fa_user_id'],
              $_SESSION['2fa_user_login'], $_SESSION['2fa_user_name'], $_SESSION['2fa_started']);
        header('Location: index.php?msg=2fa_timeout');
        exit;
    }
    $twofa_error = '';
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['verify_2fa'])) {
        if (!csrf_validate()) {
            $twofa_error = __('login.error_csrf');
        } else {
            $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
            // Rate limiting na 2FA
            if (!rate_limit_check($ip . '_2fa')) {
                $twofa_error = __('login.error_rate_limit');
            } else {
                $code = trim($_POST['code'] ?? '');
                $uid = $_SESSION['2fa_user_id'];
                $data = twofa_load('client', $uid);
                if ($data && (totp_verify($data['secret'], $code) || twofa_use_backup_code('client', $uid, $code))) {
                    $client = vbk_find_client_by_login($_SESSION['2fa_user_login']);
                    if ($client) {
                        rate_limit_clear($ip . '_2fa');
                        ibok_log("Login klienta udany (2FA): {$client['login']} (ID: {$client['id']})", 'info');
                        auth_complete_client_login($client);
                        header('Location: index.php?page=dashboard');
                        exit;
                    }
                }
                rate_limit_record($ip . '_2fa');
                $twofa_error = __('2fa.error_invalid');
            }
        }
    }
    render_2fa_verification($twofa_error);
    exit;
}

// Sprawdź czy klient jest zalogowany
if (!is_client_logged_in()) {
    render_client_login($login_error, $msg, $license_ok);
    exit;
}

// Heartbeat (raz na dobę)
require_once __DIR__ . '/inc/heartbeat.php';
heartbeat_check();

// Router - klient zalogowany
$page = $_GET['page'] ?? 'dashboard';
$allowed_pages = ['dashboard', 'faktury', 'korekty', 'platnosci', 'serwis', 'info', 'kontakt', 'zmiana_taryfy', '2fa', 'umowy', 'zmiana_hasla'];

if (!in_array($page, $allowed_pages)) {
    $page = 'dashboard';
}

render_client_page($page);

// ======================================
// FUNKCJE RENDEROWANIA
// ======================================

function render_client_login($error = '', $msg = '', $license_ok = true) {
    global $nazwa_firmy, $site_title;
    $logo_exists = file_exists(IBOK_ADMIN_DIR . '/logo.jpg');
    $theme = 'default';
    $theme_file = IBOK_CFG_DIR . '/theme.cfg';
    if (file_exists($theme_file)) {
        $td = @json_decode(file_get_contents($theme_file), true);
        if (!empty($td['theme'])) $theme = $td['theme'];
    }
?>
<!DOCTYPE html>
<html lang="<?= get_current_language() ?>">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><?= e($site_title) ?></title>
    <link href="css/nunito-sans.css" rel="stylesheet">
    <link rel="stylesheet" href="css/bootstrap.min.css" integrity="sha384-fL9V/bsikv3LKbNkFSb61GgLP+DTHbCcG2xHBYToSgBPxbg1+pAT6RnFkH+IgnA4" crossorigin="anonymous">
    <link rel="stylesheet" href="css/bootstrap-icons.min.css" integrity="sha384-Bca1ixhIOt81mB6hA19Aw4tW6VlVOpe+GFzuxikssw8pDFyAzEkFnXrFIptwniGC" crossorigin="anonymous">
    <link rel="stylesheet" href="css/ibok.css">
</head>
<body class="login-page<?= $theme !== 'default' ? ' theme-' . $theme : '' ?>">
    <div id="particles-login"></div>
    <div class="login-container">
        <div class="login-card card shadow-lg">
            <div class="card-body p-4 p-md-5">
                <div class="text-center mb-4">
                    <?php if ($logo_exists): ?>
                        <img src="admin/logo.jpg" alt="Logo" class="login-logo mb-3" style="max-height: 80px;">
                    <?php else: ?>
                        <div class="login-icon mb-3">
                            <i class="bi bi-person-circle"></i>
                        </div>
                    <?php endif; ?>
                    <h4 class="fw-bold">i-BOK 5</h4>
                    <p class="text-muted mb-0"><?= e($nazwa_firmy) ?></p>
                </div>

                <?php if ($msg): ?>
                    <div class="alert alert-info alert-dismissible fade show" role="alert">
                        <i class="bi bi-info-circle me-1"></i> <?= e($msg) ?>
                        <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
                    </div>
                <?php endif; ?>

                <?php if ($error): ?>
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
                        <i class="bi bi-exclamation-triangle me-1"></i> <?= e($error) ?>
                        <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
                    </div>
                <?php endif; ?>

                <?php if (!$license_ok): ?>
                    <div class="alert alert-danger" role="alert">
                        <i class="bi bi-exclamation-triangle-fill me-1"></i> <?= e(__('license.client_blocked')) ?>
                    </div>
                <?php endif; ?>

                <?php $naglowek_form = read_admin_text('naglowek_form.txt'); ?>
                <?php if (!empty($naglowek_form)): ?>
                    <div class="small text-muted mb-3"><?= $naglowek_form ?></div>
                <?php endif; ?>

                <form method="post" action="index.php" autocomplete="off">
                    <?= csrf_field() ?>
                    <input type="hidden" name="login_client" value="1">
                    <fieldset <?= !$license_ok ? 'disabled' : '' ?>>

                    <div class="mb-3">
                        <label for="username" class="form-label">
                            <i class="bi bi-person me-1"></i> <?= __('login.username') ?>
                        </label>
                        <input type="text" class="form-control form-control-lg" id="username" name="username"
                               value="<?= e($_POST['username'] ?? '') ?>" required autofocus>
                    </div>

                    <div class="mb-4">
                        <label for="password" class="form-label">
                            <i class="bi bi-lock me-1"></i> <?= __('login.password') ?>
                        </label>
                        <input type="password" class="form-control form-control-lg" id="password" name="password" required>
                    </div>

                    <button type="submit" class="btn btn-primary btn-lg w-100 mb-3">
                        <i class="bi bi-box-arrow-in-right me-1"></i> <?= __('login.btn_login') ?>
                    </button>
                    </fieldset>
                </form>

                <?php $stopka_form = read_admin_text('stopka_form.txt'); ?>
                <?php if (!empty($stopka_form)): ?>
                    <div class="small text-muted mt-2"><?= $stopka_form ?></div>
                <?php endif; ?>

                <div class="text-center mt-3">
                    <?php foreach (['pl' => 'PL', 'en' => 'EN'] as $code => $label): ?>
                        <a href="?lang=<?= $code ?>" class="btn btn-sm <?= get_current_language() === $code ? 'btn-outline-primary' : 'btn-outline-secondary' ?> mx-1"><?= $label ?></a>
                    <?php endforeach; ?>
                </div>
            </div>
        </div>
    </div>

    <script nonce="<?= csp_nonce() ?>" src="js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
    <?php include __DIR__ . '/inc/particles_login.php'; ?>
</body>
</html>
<?php
}

function render_client_page($page) {
    global $nazwa_firmy, $site_title, $stan_na_dzien;

    $client_id = $_SESSION['client_id'] ?? '';
    $client_name = $_SESSION['nazwisko'] ?? '';
    $current_page = $page;
    $theme = 'default';
    $theme_file = IBOK_CFG_DIR . '/theme.cfg';
    if (file_exists($theme_file)) {
        $td = @json_decode(file_get_contents($theme_file), true);
        if (!empty($td['theme'])) $theme = $td['theme'];
    }
?>
<!DOCTYPE html>
<html lang="<?= get_current_language() ?>">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><?= e($site_title) ?> - <?= e($client_name) ?></title>
    <link href="css/nunito-sans.css" rel="stylesheet">
    <link rel="stylesheet" href="css/bootstrap.min.css" integrity="sha384-fL9V/bsikv3LKbNkFSb61GgLP+DTHbCcG2xHBYToSgBPxbg1+pAT6RnFkH+IgnA4" crossorigin="anonymous">
    <link rel="stylesheet" href="css/bootstrap-icons.min.css" integrity="sha384-Bca1ixhIOt81mB6hA19Aw4tW6VlVOpe+GFzuxikssw8pDFyAzEkFnXrFIptwniGC" crossorigin="anonymous">
    <link rel="stylesheet" href="css/datatables.min.css" integrity="sha384-ISVEfRng8Op3e05C6sGn0g+2Dx1ksAPwbTbkf3mNMmYLxY883tj0WZV+vPNjwvt6" crossorigin="anonymous">
    <link rel="stylesheet" href="css/ibok.css">
    <script nonce="<?= csp_nonce() ?>" src="js/chart.min.js" integrity="sha384-9MhbyIRcBVQiiC7FSd7T38oJNj2Zh+EfxS7/vjhBi4OOT78NlHSnzM31EZRWR1LZ" crossorigin="anonymous"></script>
</head>
<body class="<?= $theme !== 'default' ? 'theme-' . $theme : '' ?>">
    <script nonce="<?= csp_nonce() ?>">if(localStorage.getItem('ibok_dark_mode')==='1')document.body.classList.add('dark-mode');</script>
    <!-- Nawigacja -->
    <nav class="navbar navbar-expand-xl navbar-dark bg-primary-gradient shadow-sm">
        <?php include __DIR__ . '/inc/particles_navbar.php'; ?>
        <div class="container-fluid">
            <a class="navbar-brand" href="index.php?page=dashboard">
                <span class="fw-bold"><i class="bi bi-speedometer2 me-1"></i> i-BOK 5</span><br>
                <small class="navbar-brand-sub"><?= e($nazwa_firmy) ?></small>
            </a>

            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarMain"
                    aria-controls="navbarMain" aria-expanded="false" aria-label="<?= __('common.toggle_navigation') ?>">
                <span class="navbar-toggler-icon"></span>
            </button>

            <div class="collapse navbar-collapse" id="navbarMain">
                <ul class="navbar-nav me-auto">
                    <li class="nav-item">
                        <a class="nav-link nav-icon-link <?= $current_page === 'dashboard' ? 'active' : '' ?>" href="index.php?page=dashboard">
                            <i class="bi bi-house"></i><span><?= __('menu.dashboard') ?></span>
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link nav-icon-link <?= $current_page === 'faktury' ? 'active' : '' ?>" href="index.php?page=faktury">
                            <i class="bi bi-receipt"></i><span><?= __('menu.invoices') ?></span>
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link nav-icon-link <?= $current_page === 'platnosci' ? 'active' : '' ?>" href="index.php?page=platnosci">
                            <i class="bi bi-credit-card"></i><span><?= __('menu.payments') ?></span>
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link nav-icon-link <?= $current_page === 'serwis' ? 'active' : '' ?>" href="index.php?page=serwis">
                            <i class="bi bi-tools"></i><span><?= __('menu.service') ?></span>
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link nav-icon-link <?= $current_page === 'info' ? 'active' : '' ?>" href="index.php?page=info">
                            <i class="bi bi-info-circle"></i><span><?= __('menu.info') ?></span>
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link nav-icon-link <?= $current_page === 'kontakt' ? 'active' : '' ?>" href="index.php?page=kontakt">
                            <i class="bi bi-envelope"></i><span><?= __('menu.contact') ?></span>
                        </a>
                    </li>
                    <?php
                    require_once __DIR__ . '/inc/tariff_offers.php';
                    if (tariff_offers_enabled($client_id)):
                    ?>
                    <li class="nav-item">
                        <a class="nav-link nav-icon-link <?= $current_page === 'zmiana_taryfy' ? 'active' : '' ?>" href="index.php?page=zmiana_taryfy">
                            <i class="bi bi-arrow-left-right"></i><span><?= __('tariff_change.menu_label_short') ?></span>
                        </a>
                    </li>
                    <?php endif; ?>
                    <?php
                    require_once __DIR__ . '/inc/contracts.php';
                    if (contracts_menu_visible()):
                        $pending_contracts = contracts_count_pending_db($client_id);
                    ?>
                    <li class="nav-item">
                        <a class="nav-link nav-icon-link <?= $current_page === 'umowy' ? 'active' : '' ?><?php if ($pending_contracts > 0): ?> nav-icon-pulse<?php endif; ?>" href="index.php?page=umowy">
                            <i class="bi bi-file-earmark-check"></i><span><?= __('contracts.menu_label') ?></span>
                        </a>
                    </li>
                    <?php endif; ?>
                </ul>

                <ul class="navbar-nav">
                    <li class="nav-item">
                        <a class="nav-link" href="#" id="darkModeToggle" role="button"
                           aria-label="<?= __('common.dark_mode') ?>" title="<?= __('common.dark_mode') ?>">
                            <i id="darkModeIcon" class="bi bi-moon-fill" aria-hidden="true"></i>
                        </a>
                    </li>
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown">
                            <i class="bi bi-person-circle me-1"></i> <?= e($client_name) ?>
                        </a>
                        <ul class="dropdown-menu dropdown-menu-end">
                            <li><span class="dropdown-item-text text-muted small">ID: <?= e(nr_klienta($client_id)) ?></span></li>
                            <li><hr class="dropdown-divider"></li>
                            <li>
                                <?php foreach (['pl' => 'Polski', 'en' => 'English'] as $code => $label): ?>
                                    <a class="dropdown-item <?= get_current_language() === $code ? 'active' : '' ?>" href="?page=<?= $current_page ?>&lang=<?= $code ?>">
                                        <?= $label ?>
                                    </a>
                                <?php endforeach; ?>
                            </li>
                            <li><hr class="dropdown-divider"></li>
                            <li>
                                <a class="dropdown-item" href="index.php?page=zmiana_hasla">
                                    <i class="bi bi-key me-1"></i> <?= __('menu.change_password') ?>
                                </a>
                            </li>
                            <li>
                                <a class="dropdown-item" href="index.php?page=2fa">
                                    <i class="bi bi-shield-lock me-1"></i> <?= __('2fa.title') ?>
                                </a>
                            </li>
                            <li><hr class="dropdown-divider"></li>
                            <li>
                                <a class="dropdown-item text-danger" href="index.php?action=logout">
                                    <i class="bi bi-box-arrow-right me-1"></i> <?= __('common.logout') ?>
                                </a>
                            </li>
                        </ul>
                    </li>
                </ul>
            </div>
        </div>
    </nav>

    <!-- Treść -->
    <div class="container-fluid py-4">
        <?php if (ibok_is_demo()): ?>
        <div class="alert alert-info alert-dismissible fade show mb-3" role="alert">
            <i class="bi bi-info-circle-fill me-1"></i>
            <strong><?= __('demo.banner_title') ?>.</strong> <?= __('demo.banner_text') ?>
            <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
        </div>
        <?php endif; ?>
        <?php
        $page_file = __DIR__ . '/pages/' . $page . '.php';
        if (file_exists($page_file)) {
            include $page_file;
        } else {
            echo '<div class="alert alert-warning">' . __('common.error') . '</div>';
        }
        ?>
    </div>

    <!-- Stopka -->
    <footer class="footer text-center text-muted py-3 mt-4 border-top">
        <small>
            i-BOK 5 &copy; <?= date('Y') ?> ININOUT &amp; PYXIS
        </small>
    </footer>

    <!-- Modal auto-logout -->
    <div class="modal fade" id="sessionExpireModal" tabindex="-1" data-bs-backdrop="static"
         aria-labelledby="sessionExpireModalLabel" aria-modal="true">
        <div class="modal-dialog modal-dialog-centered modal-sm">
            <div class="modal-content">
                <div class="modal-header bg-warning">
                    <h5 class="modal-title" id="sessionExpireModalLabel"><i class="bi bi-clock-history me-1"></i> <?= __('session.expire_title') ?></h5>
                </div>
                <div class="modal-body text-center">
                    <p><?= __('session.expire_message') ?></p>
                    <p class="fw-bold fs-4" id="sessionCountdown"></p>
                </div>
                <div class="modal-footer justify-content-center">
                    <button type="button" class="btn btn-primary" id="sessionExtendBtn">
                        <i class="bi bi-arrow-clockwise me-1"></i> <?= __('session.btn_extend') ?>
                    </button>
                    <a href="index.php?action=logout" class="btn btn-outline-danger">
                        <i class="bi bi-box-arrow-right me-1"></i> <?= __('common.logout') ?>
                    </a>
                </div>
            </div>
        </div>
    </div>

    <script nonce="<?= csp_nonce() ?>" src="js/jquery.min.js" integrity="sha384-vtXRMe3mGCbOeY7l30aIg8H9p3GdeSe4IFlP6G8JMa7o7lXvnz3GFKzPxzJdPfGK" crossorigin="anonymous"></script>
    <script nonce="<?= csp_nonce() ?>" src="js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
    <script nonce="<?= csp_nonce() ?>" src="js/datatables.min.js" integrity="sha384-306KF85tRO+G7ykYDGqV91XPFq9HliTuciJvdee2LkNAh2LOzC9q4r/C9cZUQyWu" crossorigin="anonymous"></script>
    <script nonce="<?= csp_nonce() ?>" src="js/dataTables.bootstrap5.min.js" integrity="sha384-ON66nBewQ67SNHiJWBO8f7ldsYeQ6wShDTaaikVGjNyNxC7P2rTge/Gf77mL/Ijt" crossorigin="anonymous"></script>
    <script nonce="<?= csp_nonce() ?>" src="js/particles.min.js" integrity="sha384-3u0U01MLvyGLlqCxH5vNw55TTJ2zWaZDnxbCYz81kDzq3RYYXMVSDPLxPJu+jcCg" crossorigin="anonymous"></script>
    <script nonce="<?= csp_nonce() ?>" src="js/ibok.js"></script>
    <script nonce="<?= csp_nonce() ?>">
    window.IBOK_SESSION_TIMEOUT = <?= defined('IBOK_SESSION_TIMEOUT_MINUTES') ? IBOK_SESSION_TIMEOUT_MINUTES * 60 : 1800 ?>;
    window.IBOK_SESSION_PING_URL = 'session_ping.php';
    window.IBOK_LOGOUT_URL = 'index.php?action=logout';
    </script>
</body>
</html>
<?php
}

function render_2fa_verification($error = '') {
    global $nazwa_firmy, $site_title;
    $theme = 'default';
    $theme_file = IBOK_CFG_DIR . '/theme.cfg';
    if (file_exists($theme_file)) {
        $td = @json_decode(file_get_contents($theme_file), true);
        if (!empty($td['theme'])) $theme = $td['theme'];
    }
?>
<!DOCTYPE html>
<html lang="<?= get_current_language() ?>">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><?= e($site_title) ?> - <?= __('2fa.login_title') ?></title>
    <link href="css/nunito-sans.css" rel="stylesheet">
    <link rel="stylesheet" href="css/bootstrap.min.css" integrity="sha384-fL9V/bsikv3LKbNkFSb61GgLP+DTHbCcG2xHBYToSgBPxbg1+pAT6RnFkH+IgnA4" crossorigin="anonymous">
    <link rel="stylesheet" href="css/bootstrap-icons.min.css" integrity="sha384-Bca1ixhIOt81mB6hA19Aw4tW6VlVOpe+GFzuxikssw8pDFyAzEkFnXrFIptwniGC" crossorigin="anonymous">
    <link rel="stylesheet" href="css/ibok.css">
</head>
<body class="login-page<?= $theme !== 'default' ? ' theme-' . $theme : '' ?>">
    <div id="particles-login"></div>
    <div class="login-container">
        <div class="login-card card shadow-lg">
            <div class="card-body p-4 p-md-5">
                <div class="text-center mb-4">
                    <div class="login-icon mb-3">
                        <i class="bi bi-shield-lock"></i>
                    </div>
                    <h4 class="fw-bold"><?= __('2fa.login_title') ?></h4>
                    <p class="text-muted mb-0"><?= __('2fa.login_desc') ?></p>
                </div>

                <?php if ($error): ?>
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
                        <i class="bi bi-exclamation-triangle me-1"></i> <?= e($error) ?>
                        <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
                    </div>
                <?php endif; ?>

                <form method="post" action="index.php?action=verify2fa" autocomplete="off">
                    <?= csrf_field() ?>
                    <input type="hidden" name="verify_2fa" value="1">

                    <div class="mb-4">
                        <label for="code" class="form-label">
                            <i class="bi bi-key me-1"></i> <?= __('2fa.enter_code') ?>
                        </label>
                        <input type="text" class="form-control form-control-lg text-center font-monospace"
                               id="code" name="code" placeholder="000000"
                               maxlength="8" autocomplete="off" inputmode="numeric" required autofocus>
                        <small class="form-text text-muted"><?= __('2fa.or_backup_code') ?></small>
                    </div>

                    <button type="submit" class="btn btn-primary btn-lg w-100 mb-3">
                        <i class="bi bi-check-lg me-1"></i> <?= __('2fa.btn_verify') ?>
                    </button>
                </form>

                <div class="text-center">
                    <a href="index.php?action=logout" class="text-muted small">
                        <i class="bi bi-arrow-left me-1"></i> <?= __('common.back') ?>
                    </a>
                </div>
            </div>
        </div>
    </div>

    <script nonce="<?= csp_nonce() ?>" src="js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
    <?php include __DIR__ . '/inc/particles_login.php'; ?>
</body>
</html>
<?php
}
