<?php
/**
 * Secure User Login API
 * Enhanced with comprehensive security measures against brute force and injection attacks
 */

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-API-Key, User-Agent');

// Handle preflight
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    exit(0);
}

require_once 'config.php';
require_once 'enhanced_security.php';

// Validate API access with enhanced security
validateApiAccess();

// Only allow POST requests
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    sendSecureResponse(false, 'Method not allowed', null, 405);
}

// Get and validate JSON input
$rawInput = file_get_contents('php://input');
if (empty($rawInput)) {
    sendSecureResponse(false, 'No input data provided', null, 400);
}

$input = json_decode($rawInput, true);
if (json_last_error() !== JSON_ERROR_NONE) {
    sendSecureResponse(false, 'Invalid JSON format', null, 400);
}

try {
    // Validate required fields
    if (empty($input['email'])) {
        sendSecureResponse(false, 'Email is required', null, 400);
    }
    
    if (empty($input['password'])) {
        sendSecureResponse(false, 'Password is required', null, 400);
    }
    
    // Validate and sanitize inputs
    $email = SecurityValidator::validateEmail($input['email']);
    $password = $input['password']; // Don't validate password format for login (only for registration)
    
    // Rate limiting for login attempts (more restrictive)
    $clientIP = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
    $rateLimitKey = "login_attempts_" . hash('sha256', $email . $clientIP);
    
    if (!RateLimiter::checkLimit($rateLimitKey, 5, 300)) { // 5 attempts per 5 minutes
        error_log("Login rate limit exceeded for email: $email from IP: $clientIP");
        sendSecureResponse(false, 'Too many login attempts. Please try again in 5 minutes.', null, 429);
    }
    
    // Database operations
    $conn = getDBConnection();
    if (!$conn) {
        sendSecureResponse(false, 'Database connection failed', null, 500);
    }
    
    // Get user information
    $stmt = $conn->prepare("
        SELECT id, user_name, password_hash, user_level, profile_picture, is_verified, is_deleted
        FROM users 
        WHERE email = ?
    ");
    
    if (!$stmt) {
        error_log("Database prepare error: " . $conn->errorInfo()[2]);
        sendSecureResponse(false, 'Database error occurred', null, 500);
    }
    
    $stmt->execute([$email]);
    $user = $stmt->fetch();
    
    // Always check password even if user doesn't exist (prevent timing attacks)
    $dummyHash = '$2y$10$dummyhashtopreventtimingattacks1234567890123456789012345678';
    $passwordToCheck = $user ? $user['password_hash'] : $dummyHash;
    $passwordValid = SecurityValidator::verifyPassword($password, $passwordToCheck);
    
    // Check if user exists and password is valid
    if (!$user || !$passwordValid) {
        // Log failed login attempt
        error_log("Failed login attempt for email: $email from IP: $clientIP");
        
        // Generic error message to prevent user enumeration
        sendSecureResponse(false, 'Invalid email or password', null, 401);
    }
    
    // Check if account is deleted
    if ($user['is_deleted']) {
        error_log("Login attempt for deleted account: $email from IP: $clientIP");
        sendSecureResponse(false, 'Account has been deleted. Please contact support.', null, 403);
    }
    
    // Check if account is verified
    if (!$user['is_verified']) {
        sendSecureResponse(false, 'Please verify your email address before logging in', [
            'requires_verification' => true,
            'email' => $email
        ], 403);
    }
    
    // Generate secure session token
    $sessionToken = SecurityValidator::generateSecureToken(32);
    $deviceInfo = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
    $expiryDate = date('Y-m-d H:i:s', time() + (30 * 24 * 60 * 60)); // 30 days
    
    // Begin transaction for session creation
    $conn->beginTransaction();
    
    try {
        // Clean up old sessions for this user (keep only last 5 sessions)
        $stmt = $conn->prepare("
            DELETE FROM user_sessions 
            WHERE user_id = ? AND id NOT IN (
                SELECT id FROM (
                    SELECT id FROM user_sessions 
                    WHERE user_id = ? 
                    ORDER BY created_at DESC 
                    LIMIT 5
                ) as recent_sessions
            )
        ");
        $stmt->execute([$user['id'], $user['id']]);
        
        // Insert new session
        $stmt = $conn->prepare("
            INSERT INTO user_sessions (user_id, token, device_info, ip_address, expires_at, created_at)
            VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
        ");
        $stmt->execute([$user['id'], $sessionToken, $deviceInfo, $clientIP, $expiryDate]);
        
        // Update user's last login timestamp (optional)
        $stmt = $conn->prepare("UPDATE users SET updated_at = CURRENT_TIMESTAMP WHERE id = ?");
        $stmt->execute([$user['id']]);
        
        // Commit transaction
        $conn->commit();
        
        // Prepare user data for response (exclude sensitive information)
        $userData = [
            'id' => (int)$user['id'],
            'email' => $email,
            'user_name' => $user['user_name'],
            'user_level' => $user['user_level'],
            'profile_picture' => $user['profile_picture'],
            'is_verified' => (bool)$user['is_verified']
        ];
        
        // Log successful login
        error_log("Successful login for user: {$user['user_name']} ({$email}) from IP: $clientIP");
        
        sendSecureResponse(true, 'Login successful', [
            'user' => $userData,
            'session_token' => $sessionToken,
            'expires_at' => $expiryDate
        ]);
        
    } catch (Exception $e) {
        // Rollback transaction on error
        $conn->rollback();
        error_log("Login session creation error: " . $e->getMessage());
        sendSecureResponse(false, 'Failed to create session. Please try again.', null, 500);
    }
    
} catch (InvalidArgumentException $e) {
    // Handle validation errors
    error_log("Login validation error: " . $e->getMessage());
    sendSecureResponse(false, $e->getMessage(), null, 400);
    
} catch (Exception $e) {
    // Handle unexpected errors
    error_log("Login unexpected error: " . $e->getMessage());
    sendSecureResponse(false, 'An unexpected error occurred. Please try again later.', null, 500);
}
?>