<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;

class ApiKeyAuthenticationMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        // Check if API key authentication is enabled
        if (!config('api_security.enable_api_key_auth', true)) {
            return $next($request);
        }

        // Get API key from request
        $apiKey = $this->extractApiKey($request);

        if (!$apiKey) {
            return response()->json([
                'success' => false,
                'message' => 'API key is required for external system access.',
                'error' => 'API_KEY_REQUIRED'
            ], 401);
        }

        // Validate API key
        if (!$this->isValidApiKey($apiKey)) {
            // Log invalid API key attempt
            if (config('api_security.log_api_key_usage', true)) {
                Log::warning('Invalid API key attempt', [
                    'ip' => $request->ip(),
                    'user_agent' => $request->header('User-Agent'),
                    'endpoint' => $request->fullUrl(),
                    'method' => $request->method(),
                    'api_key_prefix' => substr($apiKey, 0, 8) . '...',
                ]);
            }

            return response()->json([
                'success' => false,
                'message' => 'Invalid API key provided.',
                'error' => 'API_KEY_INVALID'
            ], 401);
        }

        // Log successful API key usage
        if (config('api_security.log_api_key_usage', true)) {
            Log::info('API key authenticated', [
                'ip' => $request->ip(),
                'user_agent' => $request->header('User-Agent'),
                'endpoint' => $request->fullUrl(),
                'method' => $request->method(),
                'api_key_prefix' => substr($apiKey, 0, 8) . '...',
            ]);
        }

        // Add API key info to request for downstream use
        $request->merge(['_api_key' => $apiKey]);

        return $next($request);
    }

    /**
     * Extract API key from request headers
     */
    private function extractApiKey(Request $request): ?string
    {
        // Check multiple header formats
        $apiKeyHeaders = config('api_security.api_key_headers', [
            'X-API-Key',
            'API-Key',
            'Authorization'
        ]);

        foreach ($apiKeyHeaders as $header) {
            $value = $request->header($header);
            
            if ($value) {
                // Handle Bearer token format
                if ($header === 'Authorization' && preg_match('/Bearer\s+(.*)$/i', $value, $matches)) {
                    return $matches[1];
                }
                
                // Direct API key
                return $value;
            }
        }

        return null;
    }

    /**
     * Validate API key against configured valid keys
     */
    private function isValidApiKey(string $apiKey): bool
    {
        $validApiKeys = config('api_security.valid_api_keys', []);
        
        if (empty($validApiKeys)) {
            return false;
        }

        return in_array($apiKey, $validApiKeys);
    }
}
