<?php
// login.php - COMPLETE MEMBER LOGIN API WITH KYC → 2FA FLOW
//After KYC verification, you will be prompted for 2FA
// ============================================
// INITIALIZATION
// ============================================

// Load CORS configuration FIRST
require_once __DIR__ . '/includes/cors.php';
configureCors();

// Load environment variables
require_once __DIR__ . '../../backend-main/includes/config_loader.php';

// Load dependencies
require_once __DIR__ . '../../backend-main/includes/config.php';
require_once __DIR__ . '/includes/auth_functions.php';
require_once __DIR__ . '/includes/sms_helper.php';
require_once __DIR__ . '/includes/email_helper.php';
require_once __DIR__ . '../../backend-main/auth/AuditLogger.php';
require_once './auth/JWTManager.php';

// Set response headers
header('Content-Type: application/json');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');

// Add security headers
header('X-Frame-Options: DENY');
header('X-Content-Type-Options: nosniff');
header('X-XSS-Protection: 1; mode=block');
header('Referrer-Policy: strict-origin-when-cross-origin');

// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    header('Access-Control-Max-Age: 86400');
    header('Content-Length: 0');
    http_response_code(200);
    exit();
}

// Start session
if (session_status() === PHP_SESSION_NONE) {
    session_name('MEMBER_PORTAL_SESSION');
    session_set_cookie_params([
        'lifetime' => 0,
        'path' => '/',
        'domain' => $_SERVER['HTTP_HOST'],
        'secure' => true,
        'httponly' => true,
        'samesite' => 'Lax'
    ]);
    
    session_start();
    
    // Regenerate ID on new session
    if (empty($_SESSION['created'])) {
        session_regenerate_id(true);
        $_SESSION['created'] = time();
    }
}

// Add request deduplication
$requestId = uniqid('req_', true);
error_log("[$requestId] === LOGIN REQUEST START ===");

// Initialize session tracking
if (!isset($_SESSION['session_id'])) {
    $_SESSION['session_id'] = session_id();
}
if (!isset($_SESSION['last_activity'])) {
    $_SESSION['last_activity'] = time();
}
if (!isset($_SESSION['ip_address'])) {
    $_SESSION['ip_address'] = $_SERVER['REMOTE_ADDR'];
}

// Request deduplication check
$dedupeKey = 'last_login_request_' . session_id();
if (isset($_SESSION[$dedupeKey]) && (time() - $_SESSION[$dedupeKey]) < 2) {
    error_log("[$requestId] Duplicate request detected");
    http_response_code(429);
    echo json_encode(['error' => 'Please wait before trying again.']);
    exit;
}
$_SESSION[$dedupeKey] = time();

// Initialize Audit Logger
try {
    $auditLogger = new AuditLogger($pdo, null, 'LoginSystem');
} catch (Exception $e) {
    error_log("[$requestId] Audit Logger initialization failed: " . $e->getMessage());
    $auditLogger = null;
}

// Initialize JWT Manager
$jwtManager = null;
try {
    $jwtSecretKey = getenv('JWT_SECRET_KEY');
    if (!empty($jwtSecretKey) && strlen($jwtSecretKey) >= 32) {
        $jwtManager = new JWTManager($pdo);
    }
} catch (Exception $e) {
    error_log("[$requestId] JWT Manager initialization failed: " . $e->getMessage());
}

// ============================================
// HELPER FUNCTIONS
// ============================================

function sendResponse($data, $statusCode = 200) {
    http_response_code($statusCode);
    echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
    exit();
}

function getJsonInput() {
    $input = json_decode(file_get_contents('php://input'), true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        return null;
    }
    return $input;
}

function checkIpRateLimit($ip, $pdo, $requestId) {
    try {
        $pdo->prepare("DELETE FROM login_attempts WHERE attempted_at < (NOW() - INTERVAL 10 MINUTE)")->execute();
        
        $stmt = $pdo->prepare("
            SELECT COUNT(*) FROM login_attempts 
            WHERE ip_address = ? 
            AND attempted_at > (NOW() - INTERVAL 10 MINUTE)
        ");
        $stmt->execute([$ip]);
        return (int)$stmt->fetchColumn();
    } catch (Exception $e) {
        error_log("[$requestId] IP rate limit check failed: " . $e->getMessage());
        return 0;
    }
}

function getCsrfToken() {
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        $_SESSION['csrf_token_time'] = time();
    }
    return $_SESSION['csrf_token'];
}

function validateCsrfToken($token) {
    if (empty($token) || empty($_SESSION['csrf_token'])) {
        return false;
    }
    
    if (!hash_equals($_SESSION['csrf_token'], $token)) {
        return false;
    }
    
    $tokenAge = time() - ($_SESSION['csrf_token_time'] ?? 0);
    if ($tokenAge > 86400) {
        unset($_SESSION['csrf_token']);
        return false;
    }
    
    return true;
}

function validateLoginIdentifier($login) {
    $login = trim($login);
    
    if (empty($login)) {
        return ['type' => 'invalid', 'valid' => false];
    }
    
    // Check email
    if (filter_var($login, FILTER_VALIDATE_EMAIL)) {
        return ['type' => 'email', 'valid' => true];
    }
    
    // Check phone number
    $normalizedPhone = normalizePhoneNumber($login);
    if ($normalizedPhone && validateKenyanPhoneNumber($normalizedPhone)) {
        return ['type' => 'phone', 'valid' => true, 'normalized' => $normalizedPhone];
    }
    
    // Check ID number (Kenyan 8-digit)
    if (preg_match('/^\d{8}$/', $login)) {
        return ['type' => 'id_number', 'valid' => true];
    }
    
    // Check username
    if (preg_match('/^[a-zA-Z0-9._-]{3,50}$/', $login)) {
        return ['type' => 'username', 'valid' => true];
    }
    
    return ['type' => 'invalid', 'valid' => false];
}

function normalizePhoneNumber($phone) {
    if (empty($phone)) return '';
    
    $digits = preg_replace('/[^0-9]/', '', $phone);
    $digits = ltrim($digits, '0');
    
    if (strlen($digits) === 12 && substr($digits, 0, 3) === '254') {
        return $digits;
    }
    
    if (strlen($digits) === 10 && substr($digits, 0, 1) === '7') {
        return '254' . substr($digits, 1);
    }
    
    if (strlen($digits) === 9 && substr($digits, 0, 1) === '7') {
        return '254' . $digits;
    }
    
    if (strlen($digits) === 9 && substr($digits, 0, 1) === '1') {
        return '254' . $digits;
    }
    
    return $digits;
}

function validateKenyanPhoneNumber($phone) {
    $phone = preg_replace('/[^0-9]/', '', $phone);
    
    if (strlen($phone) !== 12 || substr($phone, 0, 3) !== '254') {
        return false;
    }
    
    $mobilePart = substr($phone, 3);
    $validPrefixes = [
        '70', '71', '72', '74', '75', '76', '77', '78', '79',
        '10', '11'
    ];
    
    $prefix = substr($mobilePart, 0, 2);
    return in_array($prefix, $validPrefixes) && strlen($mobilePart) === 9;
}
function sendMemberLoginNotification(array $account, array $member, string $ip, string $requestId): array {
    global $pdo;
    
    $result = [
        'email_sent' => false,
        'sms_sent' => false,
        'errors' => []
    ];
    
    try {
        // Get member settings to check notification preferences
        $stmt = $pdo->prepare("
            SELECT login_notifications, notification_methods 
            FROM member_settings 
            WHERE member_id = ?
        ");
        $stmt->execute([$account['member_id']]);
        $settings = $stmt->fetch(PDO::FETCH_ASSOC);
        
        $loginNotifications = $settings['login_notifications'] ?? 'all';
        $notificationMethods = $settings['notification_methods'] ?? 'email';
        
        // Check if notifications are enabled
        if ($loginNotifications === 'none') {
            error_log("[$requestId] Login notifications disabled for member " . $account['member_id']);
            $result['message'] = 'Notifications disabled by user preference';
            return $result;
        }
        
        // Prepare notification data
        $notificationData = [
            'member_id' => $account['member_id'],
            'username' => $account['username'],
            'first_name' => $member['first_name'],
            'last_name' => $member['last_name'],
            'email' => $account['email'],
            'phone' => $member['phone_number'] ?? '',
            'login_time' => date('Y-m-d H:i:s'),
            'ip_address' => $ip,
            'device_info' => $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown',
            'location' => getLocationFromIP($ip) // Optional function
        ];
        
        // Send email notification if enabled
        if (strpos($notificationMethods, 'email') !== false && 
            filter_var($account['email'], FILTER_VALIDATE_EMAIL)) {
            
            try {
                $emailResult = sendLoginEmailNotification($notificationData, $requestId);
                $result['email_sent'] = $emailResult['success'] ?? false;
                if (isset($emailResult['error'])) {
                    $result['errors']['email'] = $emailResult['error'];
                }
            } catch (Exception $e) {
                error_log("[$requestId] Email notification failed: " . $e->getMessage());
                $result['errors']['email'] = $e->getMessage();
            }
        }
        
        // Send SMS notification if enabled
        if (strpos($notificationMethods, 'sms') !== false && 
            !empty($member['phone_number'])) {
            
            try {
                $smsResult = sendLoginSMSNotification($notificationData, $requestId);
                $result['sms_sent'] = $smsResult['success'] ?? false;
                if (isset($smsResult['error'])) {
                    $result['errors']['sms'] = $smsResult['error'];
                }
            } catch (Exception $e) {
                error_log("[$requestId] SMS notification failed: " . $e->getMessage());
                $result['errors']['sms'] = $e->getMessage();
            }
        }
        
        // Log the notification attempt
        logSecurityEvent($account['member_id'], 'login_notification_sent', [
            'email_sent' => $result['email_sent'],
            'sms_sent' => $result['sms_sent'],
            'ip' => $ip,
            'request_id' => $requestId
        ]);
        
        // Return success if at least one notification was sent or notifications are disabled
        if ($result['email_sent'] || $result['sms_sent'] || $loginNotifications === 'none') {
            $result['success'] = true;
        } else {
            $result['success'] = false;
            $result['message'] = 'Failed to send notifications';
        }
        
        return $result;
        
    } catch (Exception $e) {
        error_log("[$requestId] Login notification error: " . $e->getMessage());
        $result['success'] = false;
        $result['errors']['system'] = $e->getMessage();
        return $result;
    }
}

function sendLoginEmailNotification(array $data, string $requestId): array {
    try {
        // Load email helper if not already loaded
        if (!function_exists('sendEmail')) {
            require_once __DIR__ . '/includes/email_helper.php';
        }
        
        $subject = "Login Notification - Creative SACCO";
        
        $htmlContent = "
            <!DOCTYPE html>
            <html>
            <head>
                <style>
                    body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
                    .container { max-width: 600px; margin: 0 auto; padding: 20px; }
                    .header { background-color: #007bff; color: white; padding: 20px; text-align: center; }
                    .content { padding: 30px; background-color: #f8f9fa; border-radius: 5px; }
                    .info-box { background-color: white; padding: 20px; border-radius: 5px; border-left: 4px solid #007bff; margin: 20px 0; }
                    .warning { color: #856404; background-color: #fff3cd; border-color: #ffeaa7; padding: 10px; border-radius: 4px; margin: 15px 0; }
                    .footer { text-align: center; margin-top: 30px; color: #6c757d; font-size: 12px; }
                    .login-details { margin: 15px 0; }
                    .detail-item { margin: 8px 0; }
                </style>
            </head>
            <body>
                <div class='container'>
                    <div class='header'>
                        <h2>Creative SACCO</h2>
                        <h3>Login Notification</h3>
                    </div>
                    
                    <div class='content'>
                        <p>Hello {$data['first_name']},</p>
                        
                        <p>A successful login was detected on your account:</p>
                        
                        <div class='info-box'>
                            <div class='login-details'>
                                <div class='detail-item'><strong>Account:</strong> {$data['username']}</div>
                                <div class='detail-item'><strong>Time:</strong> {$data['login_time']}</div>
                                <div class='detail-item'><strong>IP Address:</strong> {$data['ip_address']}</div>
                                <div class='detail-item'><strong>Device:</strong> " . substr($data['device_info'], 0, 100) . "</div>
                            </div>
                        </div>
                        
                        <div class='warning'>
                            <strong>If this was not you:</strong>
                            <ol>
                                <li>Change your password immediately</li>
                                <li>Contact support at support@creativesacco.com</li>
                                <li>Review your recent account activity</li>
                            </ol>
                        </div>
                        
                        <p>Thank you for using Creative SACCO!</p>
                    </div>
                    
                    <div class='footer'>
                        <p>This is an automated message. Please do not reply to this email.</p>
                        <p>&copy; " . date('Y') . " Creative SACCO. All rights reserved.</p>
                    </div>
                </div>
            </body>
            </html>
        ";
        
        $plainContent = "Login Notification - Creative SACCO\n\n" .
                       "Hello {$data['first_name']},\n\n" .
                       "A successful login was detected on your account:\n\n" .
                       "Account: {$data['username']}\n" .
                       "Time: {$data['login_time']}\n" .
                       "IP Address: {$data['ip_address']}\n" .
                       "Device: " . substr($data['device_info'], 0, 100) . "\n\n" .
                       "If this was not you:\n" .
                       "1. Change your password immediately\n" .
                       "2. Contact support at support@creativesacco.com\n" .
                       "3. Review your recent account activity\n\n" .
                       "Thank you for using Creative SACCO!";
        
        // Send email using your existing email helper
        $emailResult = sendEmail(
            $data['email'],
            $subject,
            $htmlContent,
            $plainContent,
            ['request_id' => $requestId, 'type' => 'login_notification']
        );
        
        return [
            'success' => $emailResult['success'] ?? false,
            'message' => $emailResult['message'] ?? 'Email sent',
            'error' => $emailResult['error'] ?? null
        ];
        
    } catch (Exception $e) {
        error_log("[$requestId] Email notification error: " . $e->getMessage());
        return [
            'success' => false,
            'error' => $e->getMessage()
        ];
    }
}

function sendLoginSMSNotification(array $data, string $requestId): array {
    try {
        // Load SMS helper if not already loaded
        if (!function_exists('sendSMS')) {
            require_once __DIR__ . '/includes/sms_helper.php';
        }
        
        // Prepare SMS content
        $smsContent = "Login Alert: Hi {$data['first_name']}, login detected on your " .
                     "Creative SACCO account at {$data['login_time']}. " .
                     "IP: {$data['ip_address']}. " .
                     "If this wasn't you, contact support immediately.";
        
        // Truncate if too long (SMS character limit)
        if (strlen($smsContent) > 160) {
            $smsContent = substr($smsContent, 0, 157) . '...';
        }
        
        // Send SMS using your existing SMS helper
        $smsResult = sendSMS(
            $data['phone'],
            $smsContent,
            ['request_id' => $requestId, 'type' => 'login_notification']
        );
        
        return [
            'success' => $smsResult['success'] ?? false,
            'message' => $smsResult['message'] ?? 'SMS sent',
            'error' => $smsResult['error'] ?? null
        ];
        
    } catch (Exception $e) {
        error_log("[$requestId] SMS notification error: " . $e->getMessage());
        return [
            'success' => false,
            'error' => $e->getMessage()
        ];
    }
}

// Optional: Function to get location from IP
function getLocationFromIP(string $ip): string {
    if (empty($ip) || $ip === '127.0.0.1' || $ip === '::1') {
        return 'Localhost';
    }
    
    // You can use a service like ipinfo.io or implement your own IP geolocation
    // For simplicity, we'll return just the IP
    return $ip;
    
    /* 
    // Example with ipinfo.io (requires API token)
    $token = getenv('IPINFO_TOKEN');
    if ($token) {
        try {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, "https://ipinfo.io/{$ip}/json?token={$token}");
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 2);
            $response = curl_exec($ch);
            curl_close($ch);
            
            $data = json_decode($response, true);
            if (isset($data['city']) && isset($data['region'])) {
                return $data['city'] . ', ' . $data['region'] . ', ' . $data['country'];
            }
        } catch (Exception $e) {
            error_log("IP location lookup failed: " . $e->getMessage());
        }
    }
    return $ip;
    */
}
function completeLogin(
    array $account,
    array $member,
    ?AuditLogger $auditLogger,
    ?JWTManager $jwtManager,
    string $loginMethod,
    bool $rememberMe,
    string $authType,
    string $deviceId = '',
    string $requestId = ''
) {
    global $pdo;

    if (!isset($account['member_id']) || empty($account['member_id'])) {
        error_log("[$requestId] ERROR: Missing member_id");
        throw new Exception('Missing member_id');
    }

    /* ===============================
     * SESSION SETUP
     * =============================== */
    if ($authType === 'session' || $authType === 'hybrid') {
        session_regenerate_id(true);
        error_log("[$requestId] SESSION REGENERATED: New session ID: " . session_id());

        $newSessionData = [
            'member_id'         => $account['member_id'],
            'username'          => $account['username'],
            'email'             => $account['email'],
            'first_name'        => $member['first_name'],
            'last_name'         => $member['last_name'],
            'phone'             => $member['phone_number'],
            'id_number'         => $member['id_number'],
            'authenticated'     => true,
            'auth_type'         => $authType,
            'login_time'        => time(),
            'last_activity'     => time(),
            'ip_address'        => $_SERVER['REMOTE_ADDR'],
            'user_agent_hash'   => hash('sha256', $_SERVER['HTTP_USER_AGENT'] ?? ''),
            'session_id'        => session_id(),
            'kyc_verified'      => $member['kyc_verified'],
            'preference'        => $member['communication_preference'] ?? 'email'
        ];
        
        foreach ($newSessionData as $key => $value) {
            $_SESSION[$key] = $value;
        }
        
        error_log("[$requestId] SESSION UPDATED: Member ID " . $account['member_id'] . " logged in");
    }

    /* ===============================
     * JWT TOKENS (OPTIONAL)
     * =============================== */
    $tokens = null;

    if (($authType === 'jwt' || $authType === 'hybrid') && $jwtManager) {
        try {
            $jwtPayload = [
                'mid'   => $account['member_id'],
                'sid'   => session_id() ?: null,
                'did'   => $deviceId ?: hash('sha256', ($_SERVER['HTTP_USER_AGENT'] ?? '') . $_SERVER['REMOTE_ADDR']),
                'iat'   => time(),
                'atype' => $authType,
                'role'  => 'member'
            ];

            $accessToken = $jwtManager->generateAccessToken($jwtPayload);
            $refreshToken = $jwtManager->generateRefreshToken($account['member_id'], $deviceId, 'member');

            $jwtManager->storeAccessToken(
                $account['member_id'],
                $accessToken,
                hash('sha256', ($_SERVER['HTTP_USER_AGENT'] ?? '') . $_SERVER['REMOTE_ADDR']),
                'member'
            );

            if ($rememberMe) {
                setcookie(
                    'refresh_token',
                    $refreshToken,
                    [
                        'expires'  => time() + $jwtManager->getRefreshTokenExpiry(),
                        'path'     => '/',
                        'secure'   => true,
                        'httponly' => true,
                        'samesite' => 'Strict'
                    ]
                );
            }

            $tokens = [
                'access_token'  => $accessToken,
                'refresh_token' => $rememberMe ? null : $refreshToken,
                'token_type'    => 'Bearer',
                'expires_in'    => $jwtManager->getAccessTokenExpiry()
            ];
            
        } catch (Exception $e) {
            error_log("[$requestId] ERROR generating JWT tokens: " . $e->getMessage());
        }
    }

    /* ===============================
     * AUDIT LOG
     * =============================== */
    if ($auditLogger) {
        try {
            $auditLogger->log($account['member_id'], 'login_successful', [
                'auth_type'    => $authType,
                'session_id'   => session_id() ?: null,
                'device_id'    => $deviceId,
                'ip'           => $_SERVER['REMOTE_ADDR'],
                'request_id'   => $requestId,
                'login_method' => $loginMethod,
                'user_type'    => 'member'
            ]);
        } catch (Exception $e) {
            error_log("[$requestId] ERROR logging audit: " . $e->getMessage());
        }
    }

    /* ===============================
     * RESPONSE
     * =============================== */
    $response = [
        'success'      => true,
        'auth_type'    => $authType,
        'requires_2fa' => false,
        'requires_kyc' => false,
        'user'         => [
            'member_id'   => $account['member_id'],
            'username'    => $account['username'],
            'email'       => $account['email'],
            'first_name'  => $member['first_name'],
            'last_name'   => $member['last_name'],
            'phone'       => $member['phone_number'],
            'kyc_verified'=> $member['kyc_verified'],
            'kyc_verified_at' => $member['kyc_verified_at'] ?? null,
            'preference'  => $member['communication_preference'] ?? 'email',
            'id_number'   => $member['id_number'] ?? null,
            'account_status' => $account['status'] ?? 'active'
        ],
        'session'      => [
            'session_id' => session_id(),
            'created_at' => date('Y-m-d H:i:s'),
            'expires_at' => date('Y-m-d H:i:s', time() + 1800) // 30 minutes
        ],
        'meta'         => [
            'request_id'   => $requestId,
            'timestamp'    => time(),
            'server_time'  => date('Y-m-d H:i:s'),
            'login_method' => $loginMethod,
            'ip_address'   => $_SERVER['REMOTE_ADDR']
        ]
    ];
    
    if ($tokens) {
        $response['tokens'] = $tokens;
    }
    
    return $response;
}

function handleTwoFactorAuth($account, $authType, $jwtManager, $auditLogger, $requestId) {
    global $pdo;
    
    try {
        $stmt = $pdo->prepare("
            SELECT two_factor_enabled, two_factor_method 
            FROM member_settings 
            WHERE member_id = ?
        ");
        $stmt->execute([$account['member_id']]);
        $securitySettings = $stmt->fetch(PDO::FETCH_ASSOC);
        
        $twoFactorEnabled = $securitySettings['two_factor_enabled'] ?? false;
        $twoFactorMethod = $securitySettings['two_factor_method'] ?? 'email';
        
        if (!$twoFactorEnabled) {
            return [
                'requires_2fa' => false,
                'two_factor_enabled' => false,
                'message' => 'Two-factor authentication is not enabled'
            ];
        }
        
        // Use existing sendOTPByPreference function
        $memberData = [
            'member_id' => $account['member_id'],
            'username' => $account['username'],
            'email' => $account['email'],
            'phone_number' => $account['phone_number'] ?? '',
            'communication_preference' => $account['communication_preference'] ?? 'email',
            'first_name' => $account['first_name'] ?? '',
            'last_name' => $account['last_name'] ?? ''
        ];
        
        // Set preference based on 2FA method
        if ($twoFactorMethod === 'email') {
            $memberData['communication_preference'] = 'email';
        } elseif ($twoFactorMethod === 'sms') {
            $memberData['communication_preference'] = 'sms';
        }
        
        error_log("[$requestId] Sending OTP via method: " . $twoFactorMethod);
        
        // Call existing sendOTPByPreference function
        $otpSent = sendOTPByPreference($memberData, 'login');
        
        error_log("[$requestId] OTP SEND RESULT: " . ($otpSent ? "SUCCESS" : "FAILED"));
        
        if (!$otpSent) {
            throw new Exception('Failed to send OTP via preferred method');
        }
        
        // Store OTP verification data
        if ($authType === 'session' || $authType === 'hybrid') {
            $_SESSION['2fa_member_id'] = $account['member_id'];
            $_SESSION['2fa_method'] = $twoFactorMethod;
            $_SESSION['2fa_verified'] = false;
            $_SESSION['2fa_sent_time'] = time();
            $_SESSION['2fa_attempts'] = 0;
            
            error_log("[$requestId] OTP SUCCESS: Session data set for member " . $account['member_id']);
        }
        
        // For JWT auth, store in temporary table
        $tempToken = null;
        if (($authType === 'jwt' || $authType === 'hybrid') && $jwtManager) {
            $tempToken = $jwtManager->createPreAuthToken($account['member_id'], [
                '2fa_required' => true,
                '2fa_method' => $twoFactorMethod,
                'auth_type' => $authType,
                'user_type' => 'member',
                'timestamp' => time()
            ], '2fa_verification');
        }
        
        if (isset($auditLogger)) {
            $auditLogger->log($account['member_id'], 'login_2fa_initiated', [
                'login_method' => 'login',
                '2fa_method' => $twoFactorMethod,
                'ip' => $_SERVER['REMOTE_ADDR'],
                'auth_type' => $authType,
                'user_type' => 'member',
                'request_id' => $requestId
            ]);
        }
        
        $newCsrfToken = getCsrfToken();
        
        return [
            'requires_2fa' => true,
            'two_factor_enabled' => true,
            'two_factor_method' => $twoFactorMethod,
            'message' => 'Two-factor authentication required. Please verify your identity.',
            'data' => [
                'member_id' => $account['member_id'],
                'first_name' => $account['first_name'] ?? '',
                'last_name' => $account['last_name'] ?? '',
                'redirect_to' => 'verify_2fa.php',
                'csrf_token' => $newCsrfToken,
                'session_id' => session_id(),
                'otp_sent_via' => $twoFactorMethod,
                'otp_sent_at' => date('Y-m-d H:i:s'),
                'auth_type' => $authType,
                'pre_auth_token' => $tempToken,
                'request_id' => $requestId,
                'timestamp' => time(),
                'expires_in' => 300, // OTP valid for 5 minutes
                'security' => [
                    'requires_2fa' => true,
                    'method' => $twoFactorMethod,
                    'retry_attempts' => 3
                ]
            ]
        ];
        
    } catch (Exception $e) {
        error_log("[$requestId] 2FA handling error: " . $e->getMessage());
        
        if (isset($auditLogger)) {
            $auditLogger->log($account['member_id'] ?? 0, 'login_2fa_error', [
                'ip' => $_SERVER['REMOTE_ADDR'],
                'error' => $e->getMessage(),
                'auth_type' => $authType,
                'request_id' => $requestId
            ]);
        }
        
        return [
            'requires_2fa' => false,
            'two_factor_enabled' => false,
            'error' => '2FA configuration error, proceeding without 2FA',
            'message' => 'Two-factor authentication is temporarily unavailable'
        ];
    }
}

function handlePostKycLogin($input, $requestId) {
    global $pdo, $jwtManager, $auditLogger;
    
    try {
        $memberId = $input['member_id'] ?? 0;
        $pendingLoginToken = $input['pending_login_token'] ?? '';
        $authType = $input['auth_type'] ?? 'hybrid';
        $deviceId = $input['device_id'] ?? '';
        $rememberMe = $input['remember_me'] ?? false;
        
        // Validate pending login token or session
        $pendingLoginData = null;
        
        if ($jwtManager && !empty($pendingLoginToken)) {
            $pendingLoginData = $jwtManager->validatePendingLoginToken($pendingLoginToken);
        }
        
        if (!$pendingLoginData) {
            // Check session
            if (isset($_SESSION['pending_kyc_login']) && 
                $_SESSION['pending_kyc_login']['expires'] > time()) {
                $pendingLoginData = $_SESSION['pending_kyc_login'];
            } else {
                sendResponse([
                    'success' => false,
                    'message' => 'Login session expired. Please login again.',
                    'requires_kyc' => false,
                    'requires_2fa' => false,
                    'data' => [
                        'redirect_to' => 'login.php',
                        'reason' => 'session_expired'
                    ],
                    'meta' => [
                        'request_id' => $requestId,
                        'timestamp' => time()
                    ]
                ], 401);
            }
        }
        
        // Verify member exists and KYC is now verified
        $stmt = $pdo->prepare("
            SELECT a.member_id, a.username, a.email, a.status, a.last_login,
                   m.first_name, m.last_name, m.kyc_verified, m.kyc_verified_at,
                   m.communication_preference, m.phone_number, m.id_number
            FROM member_portal_accounts a
            JOIN members m ON m.id = a.member_id
            WHERE a.member_id = ? AND a.status = 'active' AND m.kyc_verified = 1
        ");
        $stmt->execute([$memberId]);
        $account = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$account) {
            error_log("[$requestId] Post-KYC login failed: Member not found or KYC not verified");
            
            if (isset($auditLogger)) {
                $auditLogger->log($memberId, 'post_kyc_login_failed', [
                    'reason' => 'member_not_found_or_kyc_not_verified',
                    'ip' => $_SERVER['REMOTE_ADDR'],
                    'request_id' => $requestId
                ]);
            }
            
            sendResponse([
                'success' => false,
                'message' => 'KYC verification not completed or member not found',
                'requires_kyc' => true,
                'requires_2fa' => false,
                'data' => [
                    'redirect_to' => 'kyc_verification.php',
                    'member_id' => $memberId,
                    'reason' => 'kyc_not_verified'
                ],
                'meta' => [
                    'request_id' => $requestId,
                    'timestamp' => time()
                ]
            ], 400);
        }
        
        $member = [
            'member_id' => $account['member_id'],
            'first_name' => $account['first_name'],
            'last_name' => $account['last_name'],
            'phone_number' => $account['phone_number'],
            'id_number' => $account['id_number'],
            'kyc_verified' => $account['kyc_verified'],
            'kyc_verified_at' => $account['kyc_verified_at'],
            'communication_preference' => $account['communication_preference']
        ];
        
        // Check if 2FA is required
        $requires2FA = false;
        $twoFactorMethod = 'email';
        
        try {
            $stmt = $pdo->prepare("
                SELECT two_factor_enabled, two_factor_method 
                FROM member_settings 
                WHERE member_id = ?
            ");
            $stmt->execute([$memberId]);
            $securitySettings = $stmt->fetch(PDO::FETCH_ASSOC);
            
            $requires2FA = $securitySettings['two_factor_enabled'] ?? false;
            $twoFactorMethod = $securitySettings['two_factor_method'] ?? 'email';
            
        } catch (Exception $e) {
            error_log("[$requestId] Error checking 2FA for post-KYC: " . $e->getMessage());
        }
        
        // If 2FA is required, initiate it
        if ($requires2FA) {
            $account['two_factor_enabled'] = true;
            $account['two_factor_method'] = $twoFactorMethod;
            $account['communication_preference'] = $twoFactorMethod === 'sms' ? 'sms' : 'email';
            
            $twoFactorResult = handleTwoFactorAuth($account, $authType, $jwtManager, $auditLogger, $requestId);
            
            if ($twoFactorResult['requires_2fa']) {
                // Clean up pending data
                if (isset($_SESSION['pending_kyc_login'])) {
                    unset($_SESSION['pending_kyc_login']);
                }
                
                sendResponse([
                    'success' => true,
                    'requires_kyc' => false,
                    'requires_2fa' => true,
                    'message' => 'KYC verified successfully. Two-factor authentication required.',
                    'data' => array_merge($twoFactorResult['data'], [
                        'post_kyc' => true,
                        'kyc_verified' => true,
                        'kyc_verified_at' => $member['kyc_verified_at']
                    ]),
                    'user' => [
                        'member_id' => $account['member_id'],
                        'username' => $account['username'],
                        'email' => $account['email'],
                        'first_name' => $member['first_name'],
                        'last_name' => $member['last_name'],
                        'kyc_verified' => true,
                        'kyc_verified_at' => $member['kyc_verified_at']
                    ],
                    'meta' => [
                        'request_id' => $requestId,
                        'timestamp' => time(),
                        'flow' => 'kyc → 2fa',
                        'stage' => '2fa_required'
                    ]
                ], 200);
            }
        }
        
        // If no 2FA required, complete login immediately
        error_log("[$requestId] Completing post-KYC login for ID: " . $account['member_id']);
        
        // Update last login
        $pdo->prepare("UPDATE member_portal_accounts SET last_login = NOW() WHERE member_id = ?")
            ->execute([$account['member_id']]);
        
        // Clean up pending data
        if (isset($_SESSION['pending_kyc_login'])) {
            unset($_SESSION['pending_kyc_login']);
        }
        
        $loginResult = completeLogin($account, $member, $auditLogger, $jwtManager, 'post_kyc', $rememberMe, $authType, $deviceId, $requestId);
        
        // Enhance response for post-KYC flow
        $loginResult['message'] = 'KYC verified and login successful';
        $loginResult['flow'] = 'kyc → login';
        $loginResult['kyc_details'] = [
            'verified' => true,
            'verified_at' => $member['kyc_verified_at'],
            'method' => 'post_verification'
        ];
        
        sendResponse($loginResult);
        
    } catch (Exception $e) {
        error_log("[$requestId] Post-KYC login error: " . $e->getMessage());
        
        sendResponse([
            'success' => false,
            'message' => 'Failed to complete post-KYC login',
            'requires_kyc' => false,
            'requires_2fa' => false,
            'data' => [
                'redirect_to' => 'login.php',
                'error' => $e->getMessage()
            ],
            'meta' => [
                'request_id' => $requestId,
                'timestamp' => time()
            ]
        ], 500);
    }
}

// ============================================
// API ENDPOINTS
// ============================================

// GET: Initialize session
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    try {
        if (!isset($_SESSION['login_attempts'])) {
            $_SESSION['login_attempts'] = 0;
            $_SESSION['last_login_attempt'] = 0;
        }
        
        // Fetch company name
        $companyName = 'Creative SACCO';
        try {
            $stmt = $pdo->query("SELECT company_name FROM company_settings LIMIT 1");
            $companyName = $stmt->fetchColumn() ?: 'Creative SACCO';
            $_SESSION['company_name'] = $companyName;
        } catch (Exception $e) {
            error_log("[$requestId] Failed to fetch company name: " . $e->getMessage());
        }
        
        $csrfToken = getCsrfToken();
        
        sendResponse([
            'success' => true,
            'requires_kyc' => false,
            'requires_2fa' => false,
            'data' => [
                'csrf_token' => $csrfToken,
                'company_name' => $companyName,
                'session_id' => session_id(),
                'timestamp' => time(),
                'server_time' => date('Y-m-d H:i:s'),
                'login_options' => ['Email', 'Username', 'Phone', 'ID Number'],
                'security_features' => [
                    'kyc_required' => true,
                    '2fa_supported' => true,
                    'rate_limiting' => true,
                    'session_management' => true
                ]
            ],
            'meta' => [
                'request_id' => $requestId,
                'api_version' => '1.0',
                'endpoint' => 'login_initialization'
            ]
        ]);
        
    } catch (Exception $e) {
        error_log("[$requestId] GET endpoint error: " . $e->getMessage());
        sendResponse([
            'success' => false,
            'message' => 'Initialization failed',
            'requires_kyc' => false,
            'requires_2fa' => false,
            'meta' => [
                'request_id' => $requestId,
                'timestamp' => time()
            ]
        ], 500);
    }
}

// POST: Handle login (including post-KYC login)
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    try {
        $input = getJsonInput();
        
        if (!$input) {
            sendResponse([
                'success' => false,
                'message' => 'Invalid JSON input',
                'requires_kyc' => false,
                'requires_2fa' => false,
                'meta' => [
                    'request_id' => $requestId,
                    'timestamp' => time()
                ]
            ], 400);
        }
        
        // Check if this is a post-KYC login attempt
        $isPostKycLogin = isset($input['post_kyc_login']) && $input['post_kyc_login'] === true;
        
        if ($isPostKycLogin) {
            handlePostKycLogin($input, $requestId);
            return;
        }
        
        // Regular login flow
        $login = isset($input['username']) ? trim($input['username']) : '';
        $password = $input['password'] ?? '';
        $csrf_token = $input['csrf_token'] ?? '';
        $remember_me = isset($input['remember_me']) && $input['remember_me'] === true;
        $auth_type = isset($input['auth_type']) ? $input['auth_type'] : 'hybrid';
        $device_id = isset($input['device_id']) ? $input['device_id'] : '';
        $honeypot = $input['honeypot'] ?? '';

        error_log("[$requestId] Login attempt for: " . (empty($login) ? 'EMPTY' : substr($login, 0, 3) . "***"));

        // Honeypot check
        if (!empty($honeypot)) {
            error_log("[$requestId] SECURITY: Honeypot triggered");
            logSecurityEvent(null, 'bot_detected', ['reason' => 'honeypot_triggered']);
            sendResponse([
                'success' => false,
                'message' => 'Invalid request',
                'requires_kyc' => false,
                'requires_2fa' => false,
                'meta' => [
                    'request_id' => $requestId,
                    'timestamp' => time()
                ]
            ], 403);
        }

        // Fallback to session if JWT unavailable
        if (($auth_type === 'jwt' || $auth_type === 'hybrid') && !$jwtManager) {
            if ($auth_type === 'hybrid') {
                $auth_type = 'session';
                error_log("[$requestId] Falling back to session authentication");
            } else if ($auth_type === 'jwt') {
                sendResponse([
                    'success' => false,
                    'message' => 'JWT authentication unavailable',
                    'requires_kyc' => false,
                    'requires_2fa' => false,
                    'meta' => [
                        'request_id' => $requestId,
                        'timestamp' => time()
                    ]
                ], 503);
            }
        }

        // Validate required fields
        if (empty($login) || empty($password)) {
            if (isset($auditLogger)) {
                $auditLogger->log(0, 'login_failed_missing_credentials', [
                    'attempted_login' => substr($login, 0, 3) . '***',
                    'ip' => $_SERVER['REMOTE_ADDR'],
                    'auth_type' => $auth_type,
                    'request_id' => $requestId
                ]);
            }
            sendResponse([
                'success' => false,
                'message' => 'Login identifier and password are required',
                'requires_kyc' => false,
                'requires_2fa' => false,
                'meta' => [
                    'request_id' => $requestId,
                    'timestamp' => time()
                ]
            ], 400);
        }

        // Validate login identifier
        $identifierValidation = validateLoginIdentifier($login);
        if (!$identifierValidation['valid']) {
            if (isset($auditLogger)) {
                $auditLogger->log(0, 'login_failed_invalid_format', [
                    'attempted_login' => substr($login, 0, 3) . '***',
                    'ip' => $_SERVER['REMOTE_ADDR'],
                    'auth_type' => $auth_type,
                    'request_id' => $requestId
                ]);
            }
            sendResponse([
                'success' => false,
                'message' => 'Invalid login format. Use email, username, phone, or ID number',
                'requires_kyc' => false,
                'requires_2fa' => false,
                'data' => [
                    'supported_formats' => [
                        'email' => 'user@example.com',
                        'username' => '3-50 alphanumeric characters',
                        'phone' => 'Kenyan phone number',
                        'id_number' => '8-digit Kenyan ID'
                    ]
                ],
                'meta' => [
                    'request_id' => $requestId,
                    'timestamp' => time()
                ]
            ], 400);
        }

        // CSRF validation for web logins
        if ($auth_type === 'session' || $auth_type === 'hybrid') {
            if (empty($csrf_token)) {
                if (isset($auditLogger)) {
                    $auditLogger->log(0, 'login_failed_missing_csrf', [
                        'attempted_login' => substr($login, 0, 3) . '***',
                        'ip' => $_SERVER['REMOTE_ADDR'],
                        'auth_type' => $auth_type,
                        'request_id' => $requestId
                    ]);
                }
                sendResponse([
                    'success' => false,
                    'message' => 'Security token required',
                    'requires_kyc' => false,
                    'requires_2fa' => false,
                    'meta' => [
                        'request_id' => $requestId,
                        'timestamp' => time()
                    ]
                ], 400);
            }

            // Enhanced CSRF check
            $postToken = $csrf_token;
            $sessionToken = $_SESSION['csrf_token'] ?? '';
            
            if (empty($sessionToken) || !hash_equals($sessionToken, $postToken)) {
                if (isset($auditLogger)) {
                    $auditLogger->log(0, 'csrf_validation_failed', [
                        'attempted_login' => substr($login, 0, 3) . '***',
                        'ip' => $_SERVER['REMOTE_ADDR'],
                        'auth_type' => $auth_type,
                        'request_id' => $requestId
                    ]);
                }
                
                $newToken = getCsrfToken();
                sendResponse([
                    'success' => false,
                    'message' => 'Invalid or expired security token',
                    'requires_kyc' => false,
                    'requires_2fa' => false,
                    'data' => ['new_csrf_token' => $newToken],
                    'meta' => [
                        'request_id' => $requestId,
                        'timestamp' => time()
                    ]
                ], 403);
            }

            // Clear CSRF token after use
            unset($_SESSION['csrf_token']);
            unset($_SESSION['csrf_token_time']);
        }

        $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
        error_log("[$requestId] IP Address: $ip");

        // Rate limiting
        $currentTime = time();
        $rateLimitKey = 'login_attempts_' . md5($login . $ip);
        
        if (!isset($_SESSION[$rateLimitKey])) {
            $_SESSION[$rateLimitKey] = [
                'attempts' => 0,
                'reset_time' => $currentTime,
                'last_attempt' => 0
            ];
        }
        
        $rateData = $_SESSION[$rateLimitKey];
        
        if (($currentTime - $rateData['reset_time']) > 3600) {
            $rateData['attempts'] = 0;
            $rateData['reset_time'] = $currentTime;
        }
        
        if ($rateData['attempts'] >= 5 && ($currentTime - $rateData['last_attempt']) < 300) {
            $waitTime = 300 - ($currentTime - $rateData['last_attempt']);
            
            if (isset($auditLogger)) {
                $auditLogger->log(0, 'rate_limit_exceeded', [
                    'attempted_login' => substr($login, 0, 3) . '***',
                    'ip' => $ip,
                    'attempts' => $rateData['attempts'],
                    'wait_time' => $waitTime,
                    'auth_type' => $auth_type,
                    'request_id' => $requestId
                ]);
            }
            
            sendResponse([
                'success' => false,
                'message' => "Too many attempts. Wait $waitTime seconds",
                'requires_kyc' => false,
                'requires_2fa' => false,
                'data' => [
                    'wait_time' => $waitTime,
                    'remaining_attempts' => 0,
                    'reset_at' => date('Y-m-d H:i:s', $currentTime + $waitTime)
                ],
                'meta' => [
                    'request_id' => $requestId,
                    'timestamp' => time()
                ]
            ], 429);
        }

        $rateData['attempts']++;
        $rateData['last_attempt'] = $currentTime;
        $_SESSION[$rateLimitKey] = $rateData;

        // IP-based rate limiting
        $ipAttempts = checkIpRateLimit($ip, $pdo, $requestId);
        if ($ipAttempts > 10) {
            if (isset($auditLogger)) {
                $auditLogger->log(0, 'ip_rate_limit_exceeded', [
                    'attempted_login' => substr($login, 0, 3) . '***',
                    'ip' => $ip,
                    'ip_attempts' => $ipAttempts,
                    'auth_type' => $auth_type,
                    'request_id' => $requestId
                ]);
            }
            sendResponse([
                'success' => false,
                'message' => 'Too many attempts from your IP',
                'requires_kyc' => false,
                'requires_2fa' => false,
                'data' => [
                    'ip_attempts' => $ipAttempts,
                    'reset_in' => '10 minutes'
                ],
                'meta' => [
                    'request_id' => $requestId,
                    'timestamp' => time()
                ]
            ], 429);
        }
        
        // Record IP attempt
        try {
            $pdo->prepare("INSERT INTO login_attempts (ip_address, attempted_at, login_type) VALUES (?, NOW(), 'member')")->execute([$ip]);
        } catch (Exception $e) {
            error_log("[$requestId] Failed to log IP attempt: " . $e->getMessage());
        }

        // Fetch member account
        $sql = "
            SELECT a.member_id, a.username, a.email, a.password_hash, a.status, a.password_last_changed,
                   a.lock_expires, a.last_login,
                   m.first_name, m.last_name, m.kyc_verified, m.kyc_verified_at,
                   m.kyc_attempts, m.kyc_locked, m.communication_preference, m.phone_number,
                   m.id_number
            FROM member_portal_accounts a
            JOIN members m ON m.id = a.member_id
            WHERE (a.username = :login OR a.email = :login";
        
        $queryParams = ['login' => $login];
        
        if ($identifierValidation['type'] === 'phone' && isset($identifierValidation['normalized'])) {
            $normalizedPhone = $identifierValidation['normalized'];
            $sql .= " OR REPLACE(REPLACE(REPLACE(m.phone_number, '+', ''), ' ', ''), '-', '') = :phone";
            $queryParams['phone'] = $normalizedPhone;
        }
        
        if ($identifierValidation['type'] === 'id_number') {
            $sql .= " OR m.id_number = :id_number";
            $queryParams['id_number'] = $login;
        }
        
        $sql .= ") AND a.status = 'active' LIMIT 1";
        
        $stmt = $pdo->prepare($sql);
        $stmt->execute($queryParams);
        $account = $stmt->fetch(PDO::FETCH_ASSOC);
        
        $member = [];
        if ($account) {
            $member = [
                'member_id' => $account['member_id'],
                'first_name' => $account['first_name'],
                'last_name' => $account['last_name'],
                'phone_number' => $account['phone_number'],
                'id_number' => $account['id_number'],
                'kyc_verified' => $account['kyc_verified'],
                'kyc_verified_at' => $account['kyc_verified_at'],
                'kyc_attempts' => $account['kyc_attempts'],
                'kyc_locked' => $account['kyc_locked'],
                'communication_preference' => $account['communication_preference']
            ];
        }
        
        error_log("[$requestId] ACCOUNT LOOKUP: " . ($account ? "FOUND - " . $account['username'] : "NOT FOUND"));
        
        // Timing attack protection
        usleep(500000);
        
        $validPassword = $account && password_verify($password, $account['password_hash']);
        // Dummy verification for timing protection
        password_verify('dummy_password', '$2y$10$dummyhashforprotection');

        error_log("[$requestId] PASSWORD VERIFICATION: " . ($validPassword ? "VALID" : "INVALID"));

        if (!$validPassword) {
            error_log("[$requestId] Login failed for $login");
            
            // Log security event
            logSecurityEvent($account['member_id'] ?? 0, 'login_failed', [
                'login_identifier' => substr($login, 0, 3) . '***',
                'ip' => $ip,
                'auth_type' => $auth_type,
                'request_id' => $requestId
            ]);
            
            if (isset($auditLogger)) {
                $memberId = $account['member_id'] ?? 0;
                $auditLogger->log($memberId, 'login_failed_invalid_credentials', [
                    'attempted_login' => substr($login, 0, 3) . '***',
                    'login_method' => $identifierValidation['type'],
                    'ip' => $ip,
                    'attempt_number' => $rateData['attempts'],
                    'member_exists' => !empty($account),
                    'auth_type' => $auth_type,
                    'request_id' => $requestId
                ]);
            }
            
            // Lock account after 5 failed attempts
            if ($rateData['attempts'] >= 5 && $account) {
                $lockExpires = date('Y-m-d H:i:s', time() + 300);
                $pdo->prepare("
                    UPDATE member_portal_accounts 
                    SET status = 'suspended', 
                        lock_expires = ?,
                        failed_attempts = failed_attempts + 1
                    WHERE member_id = ?
                ")->execute([$lockExpires, $account['member_id']]);
                
                // Log security event
                logSecurityEvent($account['member_id'], 'account_locked', [
                    'reason' => 'too_many_failed_attempts',
                    'attempts' => $rateData['attempts'],
                    'lock_duration' => '5 minutes'
                ]);
                
                if (isset($auditLogger)) {
                    $auditLogger->log($account['member_id'], 'account_auto_locked', [
                        'reason' => 'too_many_failed_attempts',
                        'attempts' => $rateData['attempts'],
                        'ip' => $ip,
                        'lock_duration' => '5 minutes',
                        'auth_type' => $auth_type,
                        'request_id' => $requestId
                    ]);
                }
            }
            
            $newCsrfToken = getCsrfToken();
            
            sendResponse([
                'success' => false,
                'message' => 'Invalid login or password',
                'requires_kyc' => false,
                'requires_2fa' => false,
                'data' => [
                    'login_attempts' => $rateData['attempts'],
                    'remaining_attempts' => max(0, 5 - $rateData['attempts']),
                    'csrf_token' => $newCsrfToken,
                    'rate_limit_info' => [
                        'attempts' => $rateData['attempts'],
                        'reset_in' => 3600 - ($currentTime - $rateData['reset_time']),
                        'locked' => $rateData['attempts'] >= 5
                    ]
                ],
                'meta' => [
                    'request_id' => $requestId,
                    'timestamp' => time()
                ]
            ], 401);
        }

        // VALID CREDENTIALS
        error_log("[$requestId] Valid credentials for member ID: " . $account['member_id']);
        
        // Check password rehashing
        if (password_needs_rehash($account['password_hash'], PASSWORD_DEFAULT)) {
            $newHash = password_hash($password, PASSWORD_DEFAULT);
            $pdo->prepare("UPDATE member_portal_accounts SET password_hash = ? WHERE member_id = ?")
                ->execute([$newHash, $account['member_id']]);
            error_log("[$requestId] PASSWORD REHASHED: Password upgraded to new algorithm");
        }

        // Check account status
        if ($account['status'] !== 'active') {
            $lockExpiresRaw = $account['lock_expires'] ?? null;
            $isLocked = false;
            $lockReason = '';
            
            if (!empty($lockExpiresRaw)) {
                $expiryTs = strtotime($lockExpiresRaw);
                
                if ($expiryTs === false) {
                    $isLocked = true;
                    $lockReason = 'suspended';
                } elseif ($expiryTs > time()) {
                    $isLocked = true;
                    $lockReason = 'locked_until';
                } else {
                    // Auto-unlock
                    $pdo->prepare("
                        UPDATE member_portal_accounts 
                        SET status = 'active', lock_expires = NULL
                        WHERE member_id = ?
                    ")->execute([$account['member_id']]);
                    
                    $account['status'] = 'active';
                    $account['lock_expires'] = null;
                    
                    logSecurityEvent($account['member_id'], 'account_auto_unlocked', [
                        'ip' => $ip
                    ]);
                    error_log("[$requestId] ACCOUNT AUTO-UNLOCKED: " . $account['member_id']);
                }
            } else {
                $isLocked = true;
                $lockReason = 'suspended';
            }
            
            if ($isLocked) {
                logSecurityEvent($account['member_id'], 'login_blocked', [
                    'reason' => $lockReason,
                    'account_status' => $account['status']
                ]);
                
                if (isset($auditLogger)) {
                    $auditLogger->log($account['member_id'], 'login_blocked_account_locked', [
                        'login_method' => $identifierValidation['type'],
                        'ip' => $ip,
                        'lock_reason' => $lockReason,
                        'auth_type' => $auth_type,
                        'request_id' => $requestId
                    ]);
                }
                
                sendResponse([
                    'success' => false,
                    'message' => $lockReason === 'suspended' 
                        ? 'Account suspended. Contact support.' 
                        : "Account locked until " . date('Y-m-d H:i:s', $expiryTs),
                    'requires_kyc' => false,
                    'requires_2fa' => false,
                    'data' => [
                        'account_status' => $account['status'],
                        'lock_reason' => $lockReason,
                        'lock_expires' => $lockExpiresRaw,
                        'support_contact' => 'support@creativesacco.com'
                    ],
                    'meta' => [
                        'request_id' => $requestId,
                        'timestamp' => time()
                    ]
                ], 423);
            }
        }

        // Check KYC lock
        if ($account['kyc_locked']) {
            logSecurityEvent($account['member_id'], 'login_blocked_kyc', [
                'kyc_verified' => $account['kyc_verified'],
                'kyc_locked' => true
            ]);
            
            if (isset($auditLogger)) {
                $auditLogger->log($account['member_id'], 'login_kyc_locked', [
                    'login_method' => $identifierValidation['type'],
                    'ip' => $ip,
                    'auth_type' => $auth_type,
                    'request_id' => $requestId
                ]);
            }
            
            sendResponse([
                'success' => false,
                'message' => 'KYC locked. Contact support.',
                'requires_kyc' => false,
                'requires_2fa' => false,
                'data' => [
                    'kyc_status' => 'locked',
                    'kyc_attempts' => $account['kyc_attempts'],
                    'support_contact' => 'support@creativesacco.com'
                ],
                'meta' => [
                    'request_id' => $requestId,
                    'timestamp' => time()
                ]
            ], 403);
        }

        // ============================================
        // KYC VERIFICATION CHECK (WITH 2FA INFO)
        // ============================================
        if (!$account['kyc_verified']) {
            // Check if 2FA will be required after KYC
            $requires_2fa_after_kyc = false;
            $two_factor_method = 'email';
            
            try {
                $stmt = $pdo->prepare("
                    SELECT two_factor_enabled, two_factor_method 
                    FROM member_settings 
                    WHERE member_id = ?
                ");
                $stmt->execute([$account['member_id']]);
                $securitySettings = $stmt->fetch(PDO::FETCH_ASSOC);
                
                $requires_2fa_after_kyc = $securitySettings['two_factor_enabled'] ?? false;
                $two_factor_method = $securitySettings['two_factor_method'] ?? 'email';
                
                // Store login credentials for post-KYC
                $pendingKycData = [
                    'member_id' => $account['member_id'],
                    'auth_type' => $auth_type,
                    'device_id' => $device_id,
                    'remember_me' => $remember_me,
                    'login_method' => $identifierValidation['type'],
                    'requires_2fa' => $requires_2fa_after_kyc,
                    '2fa_method' => $two_factor_method,
                    'timestamp' => time(),
                    'expires' => time() + 3600 // 1 hour
                ];
                
                // Store in session
                if ($auth_type === 'session' || $auth_type === 'hybrid') {
                    $_SESSION['pending_kyc_login'] = $pendingKycData;
                }
                
                // For JWT, create a pending login token
                if (($auth_type === 'jwt' || $auth_type === 'hybrid') && $jwtManager) {
                    $pendingToken = $jwtManager->createPreAuthToken(
                        $account['member_id'],
                        $pendingKycData,
                        'pending_kyc_login'
                    );
                    $pendingKycData['pending_token'] = $pendingToken;
                }
                
            } catch (Exception $e) {
                error_log("[$requestId] Error checking 2FA status for KYC: " . $e->getMessage());
            }
            
            // Log security event
            logSecurityEvent($account['member_id'], 'login_kyc_required', [
                'kyc_verified' => false,
                'requires_2fa_after_kyc' => $requires_2fa_after_kyc,
                '2fa_method' => $requires_2fa_after_kyc ? $two_factor_method : null
            ]);
            
            if (isset($auditLogger)) {
                $auditLogger->log($account['member_id'], 'login_kyc_required', [
                    'login_method' => $identifierValidation['type'],
                    'ip' => $ip,
                    'auth_type' => $auth_type,
                    'requires_2fa_after_kyc' => $requires_2fa_after_kyc,
                    'request_id' => $requestId
                ]);
            }
            
            // Prepare comprehensive response
            $responseData = [
                'redirect' => 'kyc_verification.php',
                'auth_type' => $auth_type,
                'member_id' => $account['member_id'],
                'requires_2fa_after_kyc' => $requires_2fa_after_kyc,
                'user_info' => [
                    'username' => $account['username'],
                    'email' => $account['email'],
                    'first_name' => $account['first_name'],
                    'last_name' => $account['last_name'],
                    'phone' => $account['phone_number']
                ],
                'request_id' => $requestId,
                'timestamp' => time()
            ];
            
            // Include pending token if available
            if (isset($pendingKycData['pending_token'])) {
                $responseData['pending_login_token'] = $pendingKycData['pending_token'];
            }
            
            if ($requires_2fa_after_kyc) {
                $responseData['post_kyc_2fa_method'] = $two_factor_method;
                $responseData['post_kyc_2fa_hint'] = 'After KYC verification, you will be prompted for 2FA';
                $responseData['flow'] = 'kyc → 2fa → login';
            } else {
                $responseData['flow'] = 'kyc → login';
            }
            
            sendResponse([
                'success' => false,
                'message' => 'KYC verification required',
                'requires_kyc' => true,
                'requires_2fa' => false,
                'requires_2fa_after_kyc' => $requires_2fa_after_kyc,
                'data' => $responseData,
                'user' => [
                    'member_id' => $account['member_id'],
                    'username' => $account['username'],
                    'email' => $account['email'],
                    'first_name' => $account['first_name'],
                    'last_name' => $account['last_name'],
                    'kyc_verified' => false,
                    'kyc_required' => true
                ],
                'meta' => [
                    'request_id' => $requestId,
                    'timestamp' => time(),
                    'flow' => 'kyc_required',
                    'stage' => 'kyc_verification'
                ]
            ]);
        }

        // ============================================
        // RESET LOGIN ATTEMPTS (KYC is verified)
        // ============================================
        unset($_SESSION[$rateLimitKey]);
        
        // Check password expiration
        if (!empty($account['password_last_changed'])) {
            $passwordLastChanged = strtotime($account['password_last_changed']);
            $expiryTime = $passwordLastChanged + (90 * 24 * 60 * 60);

            if (time() > $expiryTime) {
                if ($auth_type === 'session' || $auth_type === 'hybrid') {
                    $_SESSION['force_password_reset'] = true;
                    $_SESSION['member_id'] = $account['member_id'];
                }
                
                logSecurityEvent($account['member_id'], 'password_expired', [
                    'last_changed' => $account['password_last_changed']
                ]);
                
                if (isset($auditLogger)) {
                    $auditLogger->log($account['member_id'], 'login_password_reset_required', [
                        'login_method' => $identifierValidation['type'],
                        'ip' => $ip,
                        'auth_type' => $auth_type,
                        'request_id' => $requestId
                    ]);
                }
                
                sendResponse([
                    'success' => false,
                    'message' => 'Password reset required',
                    'requires_kyc' => false,
                    'requires_2fa' => false,
                    'data' => [
                        'redirect' => 'force_password_reset.php',
                        'auth_type' => $auth_type,
                        'member_id' => $account['member_id'],
                        'password_last_changed' => $account['password_last_changed'],
                        'expired_days_ago' => floor((time() - $expiryTime) / (24 * 60 * 60)),
                        'request_id' => $requestId
                    ],
                    'meta' => [
                        'request_id' => $requestId,
                        'timestamp' => time(),
                        'stage' => 'password_reset_required'
                    ]
                ]);
            }
        }

        // ============================================
        // 2FA CHECK (Only if KYC is verified)
        // ============================================
        $twoFactorResult = handleTwoFactorAuth($account, $auth_type, $jwtManager, $auditLogger, $requestId);
        
        if ($twoFactorResult['requires_2fa']) {
            // Send 2FA required response with full information
            sendResponse([
                'success' => true,
                'requires_kyc' => false,
                'requires_2fa' => true,
                'message' => $twoFactorResult['message'],
                'data' => $twoFactorResult['data'],
                'user' => [
                    'member_id' => $account['member_id'],
                    'username' => $account['username'],
                    'email' => $account['email'],
                    'first_name' => $member['first_name'],
                    'last_name' => $member['last_name'],
                    'kyc_verified' => true,
                    'kyc_verified_at' => $member['kyc_verified_at']
                ],
                'meta' => [
                    'request_id' => $requestId,
                    'timestamp' => time(),
                    'flow' => '2fa_required',
                    'stage' => '2fa_verification'
                ]
            ], 200);
        }

        // ============================================
        // COMPLETE LOGIN (No KYC or 2FA required)
        // ============================================
        error_log("[$requestId] Completing login for ID: " . $account['member_id']);
        
        // Update last login
        $pdo->prepare("UPDATE member_portal_accounts SET last_login = NOW() WHERE member_id = ?")
            ->execute([$account['member_id']]);
        error_log("[$requestId] LAST LOGIN UPDATED: " . $account['member_id']);
        
        // Send login notification
        try {
            $notificationResult = sendMemberLoginNotification($account, $member, $ip, $requestId);
            error_log("[$requestId] Login notification result: " . json_encode($notificationResult));
        } catch (Exception $e) {
            error_log("[$requestId] Login notification failed (non-critical): " . $e->getMessage());
        }
        
        // Log successful login
        logSecurityEvent($account['member_id'], 'login_successful', [
            'ip' => $ip,
            'auth_type' => $auth_type,
            'login_method' => $identifierValidation['type'],
            'kyc_verified' => true,
            '2fa_required' => false
        ]);
        
        $loginResult = completeLogin($account, $member, $auditLogger, $jwtManager, $identifierValidation['type'], $remember_me, $auth_type, $device_id, $requestId);
        
        sendResponse($loginResult);

    } catch (Exception $e) {
        error_log("[$requestId] Login processing error: " . $e->getMessage());
        
        // Log error
        logSecurityEvent(0, 'login_system_error', [
            'error' => $e->getMessage(),
            'ip' => $_SERVER['REMOTE_ADDR'],
            'request_id' => $requestId
        ]);
        
        if (isset($auditLogger)) {
            $auditLogger->log(0, 'login_processing_error', [
                'ip' => $_SERVER['REMOTE_ADDR'],
                'error' => $e->getMessage(),
                'request_id' => $requestId
            ]);
        }
        
        sendResponse([
            'success' => false,
            'message' => 'An error occurred. Please try again.',
            'requires_kyc' => false,
            'requires_2fa' => false,
            'data' => [
                'error_details' => 'Internal server error',
                'support_contact' => 'support@creativesacco.com'
            ],
            'meta' => [
                'request_id' => $requestId,
                'timestamp' => time()
            ]
        ], 500);
    }
}

// Invalid method
sendResponse([
    'success' => false,
    'message' => 'Method not allowed',
    'requires_kyc' => false,
    'requires_2fa' => false,
    'meta' => [
        'request_id' => $requestId,
        'timestamp' => time(),
        'allowed_methods' => ['GET', 'POST']
    ]
], 405);

error_log("[$requestId] === LOGIN REQUEST END ===");
?>