<?php

class JWT {
    private static $secret = '';
    private static $algorithm = 'HS256';
    private static $tokenExpiration = 86400; // 24 horas en segundos

    private static function getSecret() {
        if (empty(self::$secret)) {
            if (defined('JWT_SECRET')) {
                self::$secret = JWT_SECRET;
            } else {
                self::$secret = 'ibiza_secret_key_change_in_production_2025';
            }
        }
        return self::$secret;
    }

    private static function getExpiration() {
        if (defined('JWT_EXPIRATION')) {
            return JWT_EXPIRATION;
        }
        return self::$tokenExpiration;
    }

    public static function encode($payload) {
        $header = json_encode([
            'typ' => 'JWT',
            'alg' => self::$algorithm
        ]);

        $payload = array_merge($payload, [
            'iat' => time(),
            'exp' => time() + self::getExpiration()
        ]);

        $base64UrlHeader = self::base64UrlEncode($header);
        $base64UrlPayload = self::base64UrlEncode(json_encode($payload));

        $signature = hash_hmac(
            'sha256',
            $base64UrlHeader . "." . $base64UrlPayload,
            self::getSecret(),
            true
        );

        $base64UrlSignature = self::base64UrlEncode($signature);

        return $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;
    }

    public static function decode($token) {
        $tokenParts = explode('.', $token);

        if (count($tokenParts) !== 3) {
            return null;
        }

        list($header, $payload, $signature) = $tokenParts;

        $validSignature = hash_hmac(
            'sha256',
            $header . "." . $payload,
            self::getSecret(),
            true
        );

        if (!hash_equals(self::base64UrlEncode($validSignature), $signature)) {
            return null;
        }

        $decoded = json_decode(self::base64UrlDecode($payload), true);

        if (isset($decoded['exp']) && $decoded['exp'] < time()) {
            return null;
        }

        return $decoded;
    }

    public static function getUserId($token) {
        $decoded = self::decode($token);
        return $decoded['user_id'] ?? null;
    }

    public static function getUserData($token) {
        return self::decode($token);
    }

    public static function refreshToken($token) {
        $decoded = self::decode($token);

        if (!$decoded) {
            return null;
        }

        // Verificar si está en el período de gracia (última hora)
        if ($decoded['exp'] - time() < 3600) {
            return self::encode([
                'user_id' => $decoded['user_id'],
                'username' => $decoded['username'],
                'role' => $decoded['role']
            ]);
        }

        return null;
    }

    private static function base64UrlEncode($data) {
        return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
    }

    private static function base64UrlDecode($data) {
        return base64_decode(strtr($data, '-_', '+/'));
    }
}
