<?php

namespace App\Http\Middleware;

use Carbon\Carbon;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

class CheckAcessByAddr
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next)
    {

        $ip = $this->getRealIp($request);
        
        $path = $request->path();
        $mask = preg_replace('/\d+/', '[id]', $path);
        $urlHash = hash('sha256',  $request->method() . '|' . $mask);
        
        Log::channel('accesslog')->info(json_encode([
            'request_ip'        => $ip,
            'for_for'           => $request->header('X-Forwarded-For'),
            'real'              => $request->header('X-Real-IP'),
            'routeHash'         => $urlHash,
            'pess'              => $this->generate_secure_hex_string(5).Auth::id(),
            'date'              => Carbon::now()->format('d/m/Y H:i:s'),
        ], JSON_UNESCAPED_SLASHES));

        return $next($request);
    }

    private function getRealIp($request){
        $forwarded = $request->header('X-Forwarded-For');

        if ($forwarded){
            $parts = explode(',', $forwarded);
            $ipCliente = trim($parts[0]); // Se houver outro proxy, ele adiciona o IP do proxy anterior e o IP do cliente original (ex: X-Forwarded-For: <IP_Cliente>, <IP_Proxy_1>, <IP_Proxy_2>). Está diferente do outro cliente
            return $ipCliente;
        }

        // SEMPRE será o IP do LB/Proxy
        return $request->server->get('REMOTE_ADDR');
    }

    private function generate_secure_hex_string($length) {
        // random_bytes() generates cryptographically secure bytes
        // bin2hex() converts them to a hexadecimal string
        return bin2hex(random_bytes($length / 2));
    }
}
