<?php

namespace App\Http\Middleware;

use Closure;
use App\Models\Usuario;
use Auth0\SDK\Exception\InvalidTokenException;
use Auth0\SDK\Helpers\JWKFetcher;
use Auth0\SDK\Helpers\Tokens\AsymmetricVerifier;
use Auth0\SDK\Helpers\Tokens\TokenVerifier;
use Illuminate\Support\Facades\Log;


class Auth0Middleware {

    public function handle($request, Closure $next) {
        $token = $request->bearerToken();

        if (!$token) {
            Log::warning('Se intento acceder a una ruta protegida sin un token', [
                'path' => $request->getPathInfo()
            ]);
            return response()->json(['error' => 'no_token', 'message' => 'No se envío el token'], 401);
        }

        try {
            $validated = $this->validateToken($token);
        } catch (InvalidTokenException $e) {
            Log::warning('Se intento acceder a una ruta protegida con un token invalido', [
                'path' => $request->getPathInfo(),
                'message' => $e->getMessage(),
                'token' => $token
            ]);
            return response()->json([
                'error' => 'auth0_invalid_token',
                'message' => $e->getMessage()
            ]);
        }

        $user = Usuario::where('auth0_id', $validated['sub'])->first();
        Log::debug('Se identifico al usuario', ['id' => $user->id, 'auth0_id' => $user->auth0_id]);

        return $next($request->merge(['user' => $user]));
    }

    /**
     * @throws InvalidTokenException
     */
    public function validateToken($token) {
        try {
            $jwksUri = env('AUTH0_DOMAIN') . '.well-known/jwks.json';
            $jwksFetcher = new JWKFetcher(null, ['base_uri' => $jwksUri]);
            $signatureVerifier = new AsymmetricVerifier($jwksFetcher);
            $tokenVerifier = new TokenVerifier(env('AUTH0_DOMAIN'), env('AUTH0_AUD'), $signatureVerifier);

            return $tokenVerifier->verify($token);
        } catch (InvalidTokenException $e) {
            throw $e;
        }
    }
}
