<?php

namespace App\Http\Middleware;

use App\Models\AuditLog;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class AuditLogMiddleware
{
    /**
     * Actions to log
     */
    protected array $logMethods = ['POST', 'PUT', 'PATCH', 'DELETE'];

    /**
     * Handle an incoming request.
     */
    public function handle(Request $request, Closure $next): Response
    {
        $response = $next($request);

        // Only log for authenticated admin users and state-changing methods
        if (
            auth('sanctum')->check() &&
            in_array($request->method(), $this->logMethods)
        ) {
            $this->logRequest($request, $response);
        }

        return $response;
    }

    /**
     * Log the request
     */
    protected function logRequest(Request $request, Response $response): void
    {
        $user = auth('sanctum')->user();

        // Skip if not an admin user
        if (!$user || !method_exists($user, 'hasRole')) {
            return;
        }

        $routeName = $request->route()?->getName() ?? $request->path();
        $statusCode = $response->getStatusCode();

        // Only log successful operations
        if ($statusCode >= 200 && $statusCode < 300) {
            AuditLog::create([
                'admin_user_id' => $user->id,
                'action' => $this->getActionFromRoute($routeName, $request->method()),
                'entity_type' => $this->getEntityFromRoute($routeName),
                'entity_id' => $request->route('id') ?? null,
                'new_values' => $this->sanitizeRequestData($request->all()),
                'ip_address' => $request->ip(),
                'user_agent' => $request->userAgent(),
                'description' => "{$request->method()} {$request->path()}",
            ]);
        }
    }

    /**
     * Get action name from route
     */
    protected function getActionFromRoute(string $route, string $method): string
    {
        $methodActions = [
            'POST' => 'create',
            'PUT' => 'update',
            'PATCH' => 'update',
            'DELETE' => 'delete',
        ];

        return $methodActions[$method] ?? 'unknown';
    }

    /**
     * Get entity type from route
     */
    protected function getEntityFromRoute(string $route): ?string
    {
        $parts = explode('.', $route);
        return $parts[0] ?? null;
    }

    /**
     * Remove sensitive data from request
     */
    protected function sanitizeRequestData(array $data): array
    {
        $sensitiveKeys = ['password', 'password_confirmation', 'token', 'secret'];

        return array_filter($data, function ($key) use ($sensitiveKeys) {
            return !in_array($key, $sensitiveKeys);
        }, ARRAY_FILTER_USE_KEY);
    }
}
