<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use App\Services\SystemLogService;
use Illuminate\Support\Facades\Auth;

class LogUserActivity
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        $response = $next($request);

        // Only log if user is authenticated
        if (Auth::check() && $this->shouldLogRequest($request)) {
            $this->logRequest($request, $response);
        }

        return $response;
    }

    /**
     * Determine if the request should be logged
     */
    private function shouldLogRequest(Request $request): bool
    {
        // Don't log GET requests for pages (only log actions)
        if ($request->isMethod('GET') && !$this->isActionRequest($request)) {
            return false;
        }

        // Don't log AJAX requests that are just data retrieval
        if ($request->ajax() && $request->isMethod('GET')) {
            return false;
        }

        // Don't log asset requests
        if ($request->is(['*/assets/*', '*/css/*', '*/js/*', '*/images/*'])) {
            return false;
        }

        return true;
    }

    /**
     * Check if this is an action request that should be logged even if it's GET
     */
    private function isActionRequest(Request $request): bool
    {
        $actionPaths = [
            '*/export/*',
            '*/download/*',
            '*/reports/*',
            '*/dashboard',
        ];

        foreach ($actionPaths as $path) {
            if ($request->is($path)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Log the request
     */
    private function logRequest(Request $request, Response $response): void
    {
        $action = $this->getActionFromRequest($request);
        $description = $this->getDescriptionFromRequest($request);
        $module = $this->getModuleFromRequest($request);

        // Only log if we have meaningful information
        if ($action && $description) {
            SystemLogService::log($action, $description, $module);
        }
    }

    /**
     * Extract action from request
     */
    private function getActionFromRequest(Request $request): ?string
    {
        $method = $request->method();
        $route = $request->route();

        if (!$route) {
            return null;
        }

        $routeName = $route->getName();
        if (!$routeName) {
            return null;
        }

        // Map HTTP methods to actions
        $methodActions = [
            'POST' => 'create',
            'PUT' => 'update',
            'PATCH' => 'update',
            'DELETE' => 'delete',
        ];

        if (isset($methodActions[$method])) {
            return $methodActions[$method];
        }

        // Special cases for GET requests
        if ($method === 'GET') {
            if (str_contains($routeName, 'export') || str_contains($routeName, 'download')) {
                return 'export';
            }
            if (str_contains($routeName, 'reports')) {
                return 'view_reports';
            }
        }

        return null;
    }

    /**
     * Extract description from request
     */
    private function getDescriptionFromRequest(Request $request): ?string
    {
        $route = $request->route();
        if (!$route) {
            return null;
        }

        $routeName = $route->getName();
        $method = $request->method();

        // Generate description based on route name and method
        if ($method === 'POST') {
            if (str_contains($routeName, 'store')) {
                return "Created new record via {$routeName}";
            }
        }

        if ($method === 'PUT' || $method === 'PATCH') {
            if (str_contains($routeName, 'update')) {
                $id = $request->route('id') ?? $request->route('user') ?? 'unknown';
                return "Updated record {$id} via {$routeName}";
            }
        }

        if ($method === 'DELETE') {
            $id = $request->route('id') ?? 'unknown';
            return "Deleted record {$id} via {$routeName}";
        }

        if ($method === 'GET') {
            if (str_contains($routeName, 'export') || str_contains($routeName, 'download')) {
                return "Exported data via {$routeName}";
            }
            if (str_contains($routeName, 'reports')) {
                return "Viewed reports via {$routeName}";
            }
        }

        return null;
    }

    /**
     * Extract module from request
     */
    private function getModuleFromRequest(Request $request): ?string
    {
        $path = $request->path();

        // Map URL patterns to modules
        $modulePatterns = [
            'admin' => 'admin',
            'component1' => 'component1',
            'component2' => 'component2',
            'component3' => 'component3',
            'component4' => 'component4',
            'c1' => 'component1',
            'c2' => 'component2',
            'c3' => 'component3',
            'c4' => 'component4',
            'grievances' => 'grievances',
            'ess' => 'component1',
        ];

        foreach ($modulePatterns as $pattern => $module) {
            if (str_contains($path, $pattern)) {
                return $module;
            }
        }

        return null;
    }
}
