<?php
require_once '../includes/config.php';
if (isAdminLoggedIn()) { header('Location: '.SITE_URL.'/admin/dashboard.php'); exit; }

// ── Brute-force protection settings ──────────────────────────────
const ADMIN_MAX_ACCOUNT_ATTEMPTS = 5;      // failed tries on one account before lockout
const ADMIN_ACCOUNT_LOCK_MINUTES = 15;     // how long that account stays locked
const ADMIN_MAX_IP_ATTEMPTS      = 15;     // failed tries from one IP (any email) before IP is throttled
const ADMIN_IP_WINDOW_MINUTES    = 15;     // window the IP attempts are counted over
const ADMIN_IP_BLOCK_MINUTES     = 30;     // how long the IP stays throttled

function adminClientIp() {
    return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}

function adminLogAttempt($pdo, $email, $success) {
    try {
        $pdo->prepare("INSERT INTO admin_login_attempts (ip_address, email, success) VALUES (?,?,?)")
            ->execute([adminClientIp(), $email ?: null, $success ? 1 : 0]);
    } catch (Exception $e) { /* table not migrated yet — don't break login */ }
}

function adminIpBlockedMinutes($pdo) {
    try {
        $stmt = $pdo->prepare(
            "SELECT COUNT(*) FROM admin_login_attempts
             WHERE ip_address = ? AND success = 0
               AND attempted_at > (NOW() - INTERVAL " . ADMIN_IP_WINDOW_MINUTES . " MINUTE)"
        );
        $stmt->execute([adminClientIp()]);
        $failed = (int)$stmt->fetchColumn();
        if ($failed >= ADMIN_MAX_IP_ATTEMPTS) {
            // Find the most recent failed attempt to base the remaining block time on
            $stmt2 = $pdo->prepare(
                "SELECT attempted_at FROM admin_login_attempts
                 WHERE ip_address = ? AND success = 0
                 ORDER BY attempted_at DESC LIMIT 1"
            );
            $stmt2->execute([adminClientIp()]);
            $last = $stmt2->fetchColumn();
            $unlockAt = strtotime($last) + ADMIN_IP_BLOCK_MINUTES * 60;
            $remaining = $unlockAt - time();
            if ($remaining > 0) return (int)ceil($remaining / 60);
        }
    } catch (Exception $e) { /* table not migrated yet — don't break login */ }
    return 0;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
    $email    = filter_var(trim($_POST['email']??''), FILTER_SANITIZE_EMAIL);
    $password = $_POST['password'] ?? '';
    if (!$email || !$password)
        jsonResponse(['success'=>false,'message'=>'Please enter your email and password.']);

    // ── IP-level throttle — blocks repeated guesses across any email ──
    $ipBlockMins = adminIpBlockedMinutes($pdo);
    if ($ipBlockMins > 0) {
        jsonResponse(['success'=>false,'message'=>"Too many failed login attempts from this connection. Please try again in {$ipBlockMins} minute(s)."]);
    }

    $stmt = $pdo->prepare("SELECT * FROM admins WHERE email=?");
    $stmt->execute([$email]);
    $admin = $stmt->fetch();

    // ── Account-level lockout ─────────────────────────────────────
    if ($admin && !empty($admin['locked_until']) && strtotime($admin['locked_until']) > time()) {
        $mins = (int)ceil((strtotime($admin['locked_until']) - time()) / 60);
        adminLogAttempt($pdo, $email, false);
        jsonResponse(['success'=>false,'message'=>"This account is temporarily locked due to too many failed attempts. Try again in {$mins} minute(s)."]);
    }
    if ($admin && password_verify($password, $admin['password'])) {
        // ── Success — clear any lockout state ───────────────────────
        try { $pdo->prepare("UPDATE admins SET failed_attempts=0, locked_until=NULL WHERE id=?")->execute([$admin['id']]); } catch (Exception $e) {}
        adminLogAttempt($pdo, $email, true);

        $_SESSION['admin_id']    = $admin['id'];
        $_SESSION['admin_name']  = $admin['name'];
        $_SESSION['admin_email'] = $admin['email'];
        $_SESSION['admin_login_time'] = time();

        // Save full session data into admins table on login
        $ip      = $_SERVER['REMOTE_ADDR'] ?? null;
        $ua      = isset($_SERVER['HTTP_USER_AGENT']) ? substr($_SERVER['HTTP_USER_AGENT'], 0, 512) : null;
        $sessId  = session_id();
        $loginAt = date('Y-m-d H:i:s');
        try {
            // Auto-add columns if missing (safe on any MySQL version)
            foreach ([
                "ALTER TABLE admins ADD COLUMN IF NOT EXISTS last_login_at  DATETIME     DEFAULT NULL",
                "ALTER TABLE admins ADD COLUMN IF NOT EXISTS last_login_ip  VARCHAR(45)  DEFAULT NULL",
                "ALTER TABLE admins ADD COLUMN IF NOT EXISTS last_login_ua  VARCHAR(512) DEFAULT NULL",
                "ALTER TABLE admins ADD COLUMN IF NOT EXISTS session_id     VARCHAR(128) DEFAULT NULL",
                "ALTER TABLE admins ADD COLUMN IF NOT EXISTS is_online      TINYINT(1)   DEFAULT 0",
                "ALTER TABLE admins ADD COLUMN IF NOT EXISTS logout_at      DATETIME     DEFAULT NULL",
                "ALTER TABLE admins ADD COLUMN IF NOT EXISTS last_active_at DATETIME     DEFAULT NULL",
                "ALTER TABLE admins ADD COLUMN IF NOT EXISTS current_page   VARCHAR(100) DEFAULT NULL",
            ] as $sql) {
                try { $pdo->exec($sql); } catch (Exception $e) {}
            }
            $pdo->prepare("
                UPDATE admins
                SET last_login_at  = ?,
                    last_login_ip  = ?,
                    last_login_ua  = ?,
                    session_id     = ?,
                    is_online      = 1,
                    logout_at      = NULL,
                    last_active_at = ?,
                    current_page   = 'login.php'
                WHERE id = ?
            ")->execute([$loginAt, $ip, $ua, $sessId, $loginAt, $admin['id']]);
        } catch (Exception $e) {}

        jsonResponse(['success'=>true,'redirect'=> SITE_URL.'/admin/dashboard.php']);
    }

    // ── Failed login — log + update lockout counters ─────────────────
    adminLogAttempt($pdo, $email, false);
    if ($admin) {
        try {
            $attempts = (int)($admin['failed_attempts'] ?? 0) + 1;
            if ($attempts >= ADMIN_MAX_ACCOUNT_ATTEMPTS) {
                $pdo->prepare("UPDATE admins SET failed_attempts=0, locked_until=(NOW() + INTERVAL " . ADMIN_ACCOUNT_LOCK_MINUTES . " MINUTE), last_failed_at=NOW() WHERE id=?")
                    ->execute([$admin['id']]);
                jsonResponse(['success'=>false,'message'=>'Too many failed attempts. This account has been locked for ' . ADMIN_ACCOUNT_LOCK_MINUTES . ' minutes.']);
            } else {
                $pdo->prepare("UPDATE admins SET failed_attempts=?, last_failed_at=NOW() WHERE id=?")
                    ->execute([$attempts, $admin['id']]);
            }
        } catch (Exception $e) { /* table not migrated yet — don't break login */ }
    }
    jsonResponse(['success'=>false,'message'=>'Invalid email or password.']);
}
?>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Admin Login - <?= SITE_NAME ?></title>
<link rel="stylesheet" href="<?= SITE_URL ?>/assets/css/style.css"></head>
<body>
<div class="auth-wrapper">
<div class="auth-card animate-in" id="authCard">
  <div class="auth-logo">
    <div class="logo-icon">⚙️</div>
    <h1>Admin Panel</h1>
    <p class="admin-badge" style="margin-top:4px">ADMINISTRATOR ACCESS</p>
  </div>

  <div id="msgBox" style="display:none" class="alert"></div>

  <form id="adminLoginForm" novalidate>
    <div class="form-group">
      <label class="form-label">Admin Email</label>
      <div class="input-icon"><span class="icon">✉️</span>
      <input type="email" name="email" class="form-control" required autofocus></div>
    </div>
    <div class="form-group">
      <label class="form-label">Password</label>
      <div class="input-icon"><span class="icon">🔒</span>
      <input type="password" name="password" class="form-control" required>
      <button type="button" class="toggle-password">👁️</button></div>
    </div>
    <button type="submit" id="adminBtn" class="btn btn-primary btn-full">Login as Admin →</button>
  </form>
  <p style="text-align:center;margin-top:16px;font-size:13px">
    <a href="<?= SITE_URL ?>/login.php" style="color:var(--text-muted)">← Student Login</a>
  </p>
</div>
</div>
<script src="<?= SITE_URL ?>/assets/js/app.js"></script>
<script>
(function(){
  const form   = document.getElementById('adminLoginForm');
  const msgBox = document.getElementById('msgBox');
  const btn    = document.getElementById('adminBtn');
  const card   = document.getElementById('authCard');
  function showMsg(msg,type){
    msgBox.className='alert alert-'+type;
    msgBox.innerHTML=(type==='error'?'⚠️ ':'✅ ')+msg;
    msgBox.style.display='flex';
    if(type==='error'){card.style.transition='transform 0.4s ease';card.style.transform='translateX(-8px)';setTimeout(()=>{card.style.transform='translateX(8px)'},80);setTimeout(()=>{card.style.transform=''},160);}
  }
  form.addEventListener('submit', async e => {
    e.preventDefault();
    if(!form.email.value||!form.password.value){showMsg('Please enter your email and password.','error');return;}
    btn.disabled=true; btn.innerHTML='<span class="spinner"></span>&nbsp; Logging in...'; msgBox.style.display='none';
    try {
      const res  = await fetch(window.location.href,{method:'POST',body:new FormData(form),headers:{'X-Requested-With':'XMLHttpRequest'}});
      const ct   = res.headers.get('content-type')||'';
      if(!ct.includes('application/json')) throw new Error('Server error '+res.status);
      const data = await res.json();
      if(data.success){showMsg('Login successful!','success');btn.innerHTML='✓';setTimeout(()=>window.location.href=data.redirect,800);}
      else{showMsg(data.message||'Login failed.','error');btn.disabled=false;btn.innerHTML='Login as Admin →';form.password.value='';form.password.focus();}
    }catch(err){showMsg('Connection error. Please try again.','error');btn.disabled=false;btn.innerHTML='Login as Admin →';}
  });
  form.querySelectorAll('input').forEach(i=>i.addEventListener('input',()=>msgBox.style.display='none'));
})();
</script>
</body></html>