<?php

namespace App\Util;

use Psr\Http\Message\ServerRequestInterface as Request;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\BeforeValidException;
use Firebase\JWT\SignatureInvalidException;
use Exception;
use DateTime;

class TokenManager {

    private $secretKey;

    public function __construct() {

        $this->$secretKey = 'Blanca@2023.';
    }

    public function ValidateToken(Request $request, string $email, string $name): string {

        $userToken = $this->GetTokenFromHeaders($request);

        try {

            if (!empty($userToken)) {

                $decoded = JWT::decode($userToken, new Key($this->$secretKey, 'HS256'));
                $date = time();

                if($decoded->exp < $date){
                    return $this->GenerateToken($email, $name);
                }

                return $userToken;
            }
        } catch (ExpiredException | JsonException | SignatureInvalidException | Exception $e) {
            return $this->GenerateToken($email, $name);
        }

        return $this->GenerateToken($email, $name);
    }

    private function GenerateToken(String $email, String $name): ?string {

        $algorithm = 'HS256';

        $issuedAt = time();
        $expirationTime = $issuedAt + 5400;

        $payload = [
            'email' => $email,
            'name' => $name,
            'exp' => $expirationTime
        ];

        $token = JWT::encode($payload, $this->$secretKey, $algorithm);
        return $token;
    }

    private function GetTokenFromHeaders(Request $request): ?string {

        $header = $request->getHeaderLine('Authorization');

        if(preg_match('/Bearer\s(\S+)/', $header, $matches)) {
            return $matches[1];
        }

        return null;
    }
}