<?php
declare(strict_types=1);

function loginThrottleKey(string $email): string
{
    $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
    return hash('sha256', strtolower(trim($email)) . '|' . $ip);
}

function loginThrottleStatus(PDO $pdo, string $email): array
{
    $key = loginThrottleKey($email);
    try {
        $stmt = $pdo->prepare("
            SELECT failed_count, locked_until
            FROM auth_login_attempts
            WHERE throttle_key = ?
            LIMIT 1
        ");
        $stmt->execute([$key]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$row) {
            return ['locked' => false, 'failed_count' => 0];
        }

        $lockedUntil = $row['locked_until'] ?? null;
        return [
            'locked' => $lockedUntil !== null && strtotime((string)$lockedUntil) > time(),
            'failed_count' => (int)$row['failed_count'],
            'locked_until' => $lockedUntil,
        ];
    } catch (Throwable) {
        $until = $_SESSION['_login_locked_until'][$key] ?? 0;
        return ['locked' => $until > time(), 'failed_count' => (int)($_SESSION['_login_failures'][$key] ?? 0)];
    }
}

function recordFailedLogin(PDO $pdo, string $email): void
{
    $key = loginThrottleKey($email);
    $ip = $_SERVER['REMOTE_ADDR'] ?? null;
    $agent = substr((string)($_SERVER['HTTP_USER_AGENT'] ?? ''), 0, 255);

    try {
        $stmt = $pdo->prepare("
            INSERT INTO auth_login_attempts (
                throttle_key, email, ip_address, user_agent, failed_count, first_failed_at,
                last_failed_at, locked_until
            ) VALUES (
                :throttle_key, :email, :ip_address, :user_agent, 1, NOW(), NOW(), NULL
            )
            ON DUPLICATE KEY UPDATE
                email = VALUES(email),
                ip_address = VALUES(ip_address),
                user_agent = VALUES(user_agent),
                failed_count = IF(last_failed_at < DATE_SUB(NOW(), INTERVAL 15 MINUTE), 1, failed_count + 1),
                first_failed_at = IF(last_failed_at < DATE_SUB(NOW(), INTERVAL 15 MINUTE), NOW(), first_failed_at),
                last_failed_at = NOW(),
                locked_until = IF(
                    IF(last_failed_at < DATE_SUB(NOW(), INTERVAL 15 MINUTE), 1, failed_count + 1) >= 5,
                    DATE_ADD(NOW(), INTERVAL 15 MINUTE),
                    locked_until
                )
        ");
        $stmt->execute([
            'throttle_key' => $key,
            'email' => substr($email, 0, 255),
            'ip_address' => $ip,
            'user_agent' => $agent,
        ]);
    } catch (Throwable) {
        $_SESSION['_login_failures'][$key] = (int)($_SESSION['_login_failures'][$key] ?? 0) + 1;
        if ($_SESSION['_login_failures'][$key] >= 5) {
            $_SESSION['_login_locked_until'][$key] = time() + 900;
        }
    }
}

function clearFailedLogins(PDO $pdo, string $email): void
{
    $key = loginThrottleKey($email);
    try {
        $stmt = $pdo->prepare("DELETE FROM auth_login_attempts WHERE throttle_key = ?");
        $stmt->execute([$key]);
    } catch (Throwable) {
        unset($_SESSION['_login_failures'][$key], $_SESSION['_login_locked_until'][$key]);
    }
}
