<?php
namespace App\Middleware;

use App\Services\AuditService;

class RequestLogger
{
    private $auditService;

    public function __construct(AuditService $auditService)
    {
        $this->auditService = $auditService;
    }

    public function handle()
    {
        if (getenv('REQUEST_LOG_ENABLED') === '0') {
            return;
        }

        // Skip CLI
        if (php_sapi_name() === 'cli') {
            return;
        }

        $uri = $_SERVER['REQUEST_URI'] ?? '/';
        $method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
        
        // Skip assets
        if (preg_match('/\.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$/i', $uri)) {
            return;
        }

        // Get API action if exists
        $action = $_GET['api'] ?? null;

        // By default, skip GET request logging to reduce DB/log I/O noise.
        // Enable explicitly with REQUEST_LOG_GET=1
        if (strtoupper($method) === 'GET' && getenv('REQUEST_LOG_GET') !== '1') {
            return;
        }
        
        // Skip frequent polling or logging actions to prevent loop/noise
        $ignoredActions = [
            'get_audit_logs', 
            'get_notifications', 
            'get_notification_count', 
            'notification_count',
            'check_reminders',
            'test_notification',
            'test_polling',
            'log_client_event' // Don't double log the client log request itself
        ];

        if ($action && in_array($action, $ignoredActions)) {
            return;
        }

        // Determine Action Name
        $logAction = "HTTP $method";
        $details = ['uri' => $uri];

        if ($action) {
            $logAction = "API: $action";
        } elseif ($uri === '/' || $uri === '/index.php') {
            $logAction = "Page View: Home";
        } else {
            $logAction = "Page Request";
        }

        // Capture Request Body for non-GET (be careful with passwords)
        if ($method !== 'GET') {
            $input = $_POST;
            // Redact sensitive fields
            foreach (['password', 'new_password', 'confirm_password', 'current_password', 'api_key'] as $sensitive) {
                if (isset($input[$sensitive])) {
                    $input[$sensitive] = '***REDACTED***';
                }
            }
            // Avoid logging extremely large payloads
            foreach ($input as $key => $value) {
                if (is_string($value) && strlen($value) > 2000) {
                    $input[$key] = mb_substr($value, 0, 2000) . '... [truncated]';
                }
            }
            $details['input'] = $input;
        }

        // Log it
        // We use 'system' as entity type for generic requests, or infer from context if possible
        // For now, keep it simple.
        try {
            $this->auditService->log(
                $logAction,
                'system',
                null,
                $details
            );
        } catch (\Exception $e) {
            // Fail silently to not break the app
            error_log("Audit Log Failed: " . $e->getMessage());
        }
    }
}
