<?php

namespace App\Http\Middleware;

use App\MongoDB\Mongo;
use Carbon\Carbon;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;

class MongoMiddleware
{
    private $startTime;

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string[]  ...$guards
     * @return mixed
     *
     * @throws \Illuminate\Auth\AuthenticationException
     */
    public function handle($request, Closure $next, ...$guards)
    {
        $this->startTime = microtime(true);
        return $next($request);
    }

    public function terminate($request, $response)
    {
        if (!env('LOCAL')) {
            $this->toMongo($request, $response);
        }
    }

    public function toMongo(Request $request, $response){
        if (!env('LOCAL')) {
            try {
                $url = $request->fullUrl();
                if (strpos($url, '/pwa/') !== false) {
                    $request_data = json_decode(base64_decode($request->get('data')));
                    $session_string = (isset($request_data->session_string)) ? base64_decode($request_data->session_string) : null;
                    $requestData = ($request->has('data')) ? json_decode(base64_decode($request->get('data'))) : $request->toArray();
                    $responseData = $response->getContent() ? json_decode(base64_decode($response->getContent())) : $response->getContent();
                } else {
                    $session_string = (Auth::user()) ? Auth::user()->getAuthIdentifier() : null;
                    $requestData = $request->toArray();
                    $responseData = $response->getContent();
                }
                $mongo = new Mongo($this->terminateData($request, $response, $responseData, $requestData, $session_string));
                $mongo->create();
            } catch (\Exception $exception) {

            }
        }
    }

    public function terminateData(Request $request, $response, $responseData, $requestData, $session_string){
        return new Request([
            'collection' => 'requests',
            'response' => $responseData,
            'request' => $requestData,
            'duration' => number_format(microtime(true) - $this->startTime, 3),
            'url' => $request->fullUrl(),
            'method' => $request->getMethod(),
            'ip_address' => $request->getClientIp(),
            'code' => $response->status(),
            'user_id' => $session_string,
            'created_at' => Carbon::now()->toDateTimeString()
        ]);
    }
}
