<?php
/**
 * Simple JWT Implementation for Zen Zone Spa API
 * No external dependencies - works on any cPanel hosting
 */

class JWT {
    
    private static $secret_key = 'ZenZone_Spa_Secret_Key_2024_Change_In_Production';
    private static $algorithm = 'HS256';
    
    /**
     * Generate JWT token
     * @param array $payload
     * @param int $expiry_hours
     * @return string
     */
    public static function encode($payload, $expiry_hours = 24) {
        // Header
        $header = json_encode([
            'typ' => 'JWT',
            'alg' => self::$algorithm
        ]);
        
        // Add expiry to payload
        $payload['iat'] = time();
        $payload['exp'] = time() + ($expiry_hours * 3600);
        
        $payload_json = json_encode($payload);
        
        // Encode
        $header_encoded = self::base64url_encode($header);
        $payload_encoded = self::base64url_encode($payload_json);
        
        // Create signature
        $signature = hash_hmac('sha256', $header_encoded . "." . $payload_encoded, self::$secret_key, true);
        $signature_encoded = self::base64url_encode($signature);
        
        return $header_encoded . "." . $payload_encoded . "." . $signature_encoded;
    }
    
    /**
     * Decode JWT token
     * @param string $jwt
     * @return array|false
     */
    public static function decode($jwt) {
        $parts = explode('.', $jwt);
        if (count($parts) !== 3) {
            return false;
        }
        
        list($header_encoded, $payload_encoded, $signature_encoded) = $parts;
        
        // Verify signature
        $signature = self::base64url_decode($signature_encoded);
        $expected_signature = hash_hmac('sha256', $header_encoded . "." . $payload_encoded, self::$secret_key, true);
        
        if (!hash_equals($signature, $expected_signature)) {
            return false;
        }
        
        // Decode payload
        $payload = json_decode(self::base64url_decode($payload_encoded), true);
        
        // Check expiry
        if (isset($payload['exp']) && $payload['exp'] < time()) {
            return false;
        }
        
        return $payload;
    }
    
    /**
     * Validate token and return user data
     * @param string $token
     * @return array|false
     */
    public static function validateToken($token) {
        // Remove 'Bearer ' prefix if present
        if (strpos($token, 'Bearer ') === 0) {
            $token = substr($token, 7);
        }
        
        $payload = self::decode($token);
        if (!$payload) {
            return false;
        }
        
        return $payload;
    }
    
    /**
     * Base64 URL encode
     */
    private static function base64url_encode($data) {
        return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
    }
    
    /**
     * Base64 URL decode
     */
    private static function base64url_decode($data) {
        return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
    }
    
    /**
     * Generate secure random string for secrets
     */
    public static function generateSecret($length = 32) {
        return bin2hex(random_bytes($length));
    }
    
    /**
     * Get current user ID from JWT token
     * @return int|null
     */
    public static function getCurrentUserId() {
        $token = self::getTokenFromRequest();
        if (!$token) {
            return null;
        }
        
        $payload = self::validateToken($token);
        return $payload['user_id'] ?? null;
    }
    
    /**
     * Get current user role from JWT token
     * @return string|null
     */
    public static function getCurrentUserRole() {
        $token = self::getTokenFromRequest();
        if (!$token) {
            return null;
        }
        
        $payload = self::validateToken($token);
        return $payload['role'] ?? null;
    }
    
    /**
     * Get current username from JWT token
     * @return string|null
     */
    public static function getCurrentUsername() {
        $token = self::getTokenFromRequest();
        if (!$token) {
            return null;
        }
        
        $payload = self::validateToken($token);
        return $payload['username'] ?? null;
    }
    
    /**
     * Check if current user has specific role
     * @param string|array $requiredRoles
     * @return bool
     */
    public static function hasRole($requiredRoles) {
        $currentRole = self::getCurrentUserRole();
        if (!$currentRole) {
            return false;
        }
        
        if (is_array($requiredRoles)) {
            return in_array($currentRole, $requiredRoles);
        }
        
        return $currentRole === $requiredRoles;
    }
    
    /**
     * Get JWT token from request
     * @return string|null
     */
    private static function getTokenFromRequest() {
        // Try multiple methods to get the Authorization header
        $token = null;
        
        // Method 1: $_SERVER['HTTP_AUTHORIZATION']
        if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
            $token = $_SERVER['HTTP_AUTHORIZATION'];
        }
        // Method 2: $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] (cPanel specific)
        elseif (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
            $token = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
        }
        // Method 3: getallheaders()
        elseif (function_exists('getallheaders')) {
            $headers = getallheaders();
            if (isset($headers['Authorization'])) {
                $token = $headers['Authorization'];
            }
        }
        // Method 4: apache_request_headers()
        elseif (function_exists('apache_request_headers')) {
            $headers = apache_request_headers();
            if (isset($headers['Authorization'])) {
                $token = $headers['Authorization'];
            }
        }
        
        return $token;
    }
} 