<?php
/**
 * Admin Activity Logger
 * 
 * Logs all admin login sessions and password changes to a text file.
 * Tracks: IP address, device info, timestamp, action type.
 * 
 * Log file location: /admin/adminapi/logs/admin_activity.txt
 */

/**
 * Get the log file path
 */
function getAdminActivityLogPath() {
    $logDir = __DIR__ . '/../logs';
    if (!is_dir($logDir)) {
        @mkdir($logDir, 0755, true);
    }
    return $logDir . '/admin_activity.txt';
}

/**
 * Log an admin activity event
 * 
 * @param string $action - Type of action: LOGIN, LOGOUT, PASSWORD_CHANGE, LOGIN_FAILED
 * @param int $adminId - Admin user ID
 * @param string $email - Admin email
 * @param array $extra - Additional data to log
 */
function logAdminActivity($action, $adminId = 0, $email = '', $extra = []) {
    $logFile = getAdminActivityLogPath();
    
    $timestamp = date('Y-m-d H:i:s');
    $ip = getClientIP();
    $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
    $deviceInfo = parseUserAgent($userAgent);
    
    // Build log entry
    $separator = str_repeat('-', 80);
    $entry = "\n{$separator}\n";
    $entry .= "ACTION:     {$action}\n";
    $entry .= "TIMESTAMP:  {$timestamp}\n";
    $entry .= "ADMIN ID:   {$adminId}\n";
    $entry .= "EMAIL:      {$email}\n";
    $entry .= "IP ADDRESS: {$ip}\n";
    $entry .= "DEVICE:     {$deviceInfo}\n";
    $entry .= "USER AGENT: {$userAgent}\n";
    
    // Add extra info if provided
    if (!empty($extra)) {
        foreach ($extra as $key => $value) {
            $entry .= strtoupper($key) . ": " . $value . "\n";
        }
    }
    
    $entry .= "{$separator}\n";
    
    // Append to log file
    @file_put_contents($logFile, $entry, FILE_APPEND | LOCK_EX);
}

/**
 * Log a successful login
 */
function logLogin($adminId, $email, $deviceName = '') {
    // Count active sessions for this admin
    global $pdo;
    $activeDevices = 0;
    try {
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM admin_tokens WHERE admin_id = ? AND last_activity > DATE_SUB(NOW(), INTERVAL 1800 SECOND)");
        $stmt->execute([$adminId]);
        $activeDevices = (int)$stmt->fetchColumn();
    } catch (Exception $e) {
        // ignore
    }
    
    $extra = [
        'ACTIVE SESSIONS' => $activeDevices,
        'STATUS' => 'SUCCESS'
    ];
    
    if (!empty($deviceName)) {
        $extra['PHONE MODEL'] = $deviceName;
    }
    
    logAdminActivity('LOGIN', $adminId, $email, $extra);
}

/**
 * Log a failed login attempt
 */
function logLoginFailed($email, $reason = 'Invalid credentials') {
    logAdminActivity('LOGIN_FAILED', 0, $email, [
        'REASON' => $reason
    ]);
}

/**
 * Log a password change
 */
function logPasswordChange($adminId, $email = '') {
    // Get email from DB if not provided
    global $pdo;
    if (empty($email)) {
        try {
            $stmt = $pdo->prepare("SELECT email FROM admin WHERE id = ? LIMIT 1");
            $stmt->execute([$adminId]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            $email = $row['email'] ?? 'unknown';
        } catch (Exception $e) {
            $email = 'unknown';
        }
    }
    
    // Get device name from current token session
    $deviceName = '';
    $token = extractToken();
    if ($token) {
        try {
            $stmt = $pdo->prepare("SELECT device_name FROM admin_tokens WHERE token = ? LIMIT 1");
            $stmt->execute([$token]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            $deviceName = $row['device_name'] ?? '';
        } catch (Exception $e) {
            // ignore
        }
    }
    
    $extra = ['STATUS' => 'Password changed successfully'];
    if (!empty($deviceName)) {
        $extra['PHONE MODEL'] = $deviceName;
    }
    
    logAdminActivity('PASSWORD_CHANGE', $adminId, $email, $extra);
}

/**
 * Log a logout
 */
function logLogout($adminId, $email = '') {
    logAdminActivity('LOGOUT', $adminId, $email);
}

/**
 * Get the real client IP address
 */
function getClientIP() {
    $headers = [
        'HTTP_CF_CONNECTING_IP',     // Cloudflare
        'HTTP_X_REAL_IP',            // Nginx proxy
        'HTTP_X_FORWARDED_FOR',      // Standard proxy
        'HTTP_CLIENT_IP',            // Shared internet
        'REMOTE_ADDR'                // Direct connection
    ];
    
    foreach ($headers as $header) {
        if (!empty($_SERVER[$header])) {
            $ip = $_SERVER[$header];
            // X-Forwarded-For can contain multiple IPs, take the first
            if (strpos($ip, ',') !== false) {
                $ip = trim(explode(',', $ip)[0]);
            }
            // Validate it's a proper IP
            if (filter_var($ip, FILTER_VALIDATE_IP)) {
                return $ip;
            }
        }
    }
    
    return 'Unknown';
}

/**
 * Parse user agent to get readable device info
 */
function parseUserAgent($ua) {
    $device = 'Unknown Device';
    
    // Check if it's an Android app
    if (stripos($ua, 'okhttp') !== false) {
        $device = 'Android Admin App (OkHttp)';
    }
    // Android browser
    elseif (preg_match('/Android\s+([\d.]+)/', $ua, $matches)) {
        $device = 'Android ' . $matches[1];
        if (preg_match('/;\s*([^;)]+)\s*Build/', $ua, $model)) {
            $device .= ' - ' . trim($model[1]);
        }
    }
    // iPhone/iPad
    elseif (preg_match('/iPhone|iPad/', $ua)) {
        $device = 'iOS Device';
        if (preg_match('/OS\s+([\d_]+)/', $ua, $matches)) {
            $device .= ' (iOS ' . str_replace('_', '.', $matches[1]) . ')';
        }
    }
    // Windows
    elseif (preg_match('/Windows NT ([\d.]+)/', $ua, $matches)) {
        $versions = [
            '10.0' => 'Windows 10/11',
            '6.3' => 'Windows 8.1',
            '6.2' => 'Windows 8',
            '6.1' => 'Windows 7',
        ];
        $device = $versions[$matches[1]] ?? 'Windows';
        
        // Browser
        if (stripos($ua, 'Chrome') !== false && stripos($ua, 'Edg') !== false) {
            $device .= ' - Edge';
        } elseif (stripos($ua, 'Chrome') !== false) {
            $device .= ' - Chrome';
        } elseif (stripos($ua, 'Firefox') !== false) {
            $device .= ' - Firefox';
        }
    }
    // Mac
    elseif (preg_match('/Macintosh/', $ua)) {
        $device = 'macOS';
        if (stripos($ua, 'Chrome') !== false) {
            $device .= ' - Chrome';
        } elseif (stripos($ua, 'Safari') !== false) {
            $device .= ' - Safari';
        } elseif (stripos($ua, 'Firefox') !== false) {
            $device .= ' - Firefox';
        }
    }
    // Linux
    elseif (preg_match('/Linux/', $ua)) {
        $device = 'Linux';
        if (stripos($ua, 'Chrome') !== false) {
            $device .= ' - Chrome';
        } elseif (stripos($ua, 'Firefox') !== false) {
            $device .= ' - Firefox';
        }
    }
    
    return $device;
}

/**
 * Get all active login sessions (for admin viewing)
 * Returns array of active sessions with IP, device, last activity
 */
function getActiveLoginSessions($adminId = null) {
    global $pdo;
    
    try {
        if ($adminId) {
            $stmt = $pdo->prepare("
                SELECT admin_id, ip_address, user_agent, device_name, created_at, last_activity 
                FROM admin_tokens 
                WHERE admin_id = ? AND last_activity > DATE_SUB(NOW(), INTERVAL 1800 SECOND)
                ORDER BY last_activity DESC
            ");
            $stmt->execute([$adminId]);
        } else {
            $stmt = $pdo->query("
                SELECT admin_id, ip_address, user_agent, device_name, created_at, last_activity 
                FROM admin_tokens 
                WHERE last_activity > DATE_SUB(NOW(), INTERVAL 1800 SECOND)
                ORDER BY last_activity DESC
            ");
        }
        
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (Exception $e) {
        return [];
    }
}

/**
 * Get login history from the log file (last N entries)
 * 
 * @param int $limit - How many entries to return
 * @return string - Raw log text
 */
function getLoginHistory($limit = 50) {
    $logFile = getAdminActivityLogPath();
    
    if (!file_exists($logFile)) {
        return "No activity log found.";
    }
    
    $content = file_get_contents($logFile);
    
    // Split by separator and take last N entries
    $entries = explode(str_repeat('-', 80), $content);
    $entries = array_filter($entries, function($e) { return trim($e) !== ''; });
    $entries = array_slice($entries, -$limit);
    
    return implode(str_repeat('-', 80), $entries);
}
