<?php

const STOKPRO_JWT_ALGO = 'HS256';
const STOKPRO_JWT_TTL_SECONDS = 60 * 60 * 24 * 30;
const STOKPRO_JWT_FALLBACK_SECRET = 'stokpro_jwt_4m9Qp2Ls7Xv8Hd1Kr5Tw0Nc6Ba3Uf9Ye';

function stokpro_jwt_secret_path()
{
    return __DIR__ . '/jwt_secret.txt';
}

function stokpro_jwt_secret()
{
    $envSecret = getenv('JWT_SECRET');
    if (is_string($envSecret) && trim($envSecret) !== '') {
        return trim($envSecret);
    }

    $filePath = stokpro_jwt_secret_path();
    if (is_file($filePath)) {
        $fileSecret = trim((string)file_get_contents($filePath));
        if ($fileSecret !== '') {
            return $fileSecret;
        }
    }

    return STOKPRO_JWT_FALLBACK_SECRET;
}

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

function stokpro_jwt_base64url_decode($data)
{
    $remainder = strlen($data) % 4;
    if ($remainder > 0) {
        $data .= str_repeat('=', 4 - $remainder);
    }

    return base64_decode(strtr($data, '-_', '+/'));
}

function stokpro_jwt_normalize_payload(array $payload)
{
    if (empty($payload['user_id']) && !empty($payload['id'])) {
        $payload['user_id'] = (string)$payload['id'];
    }

    if (empty($payload['id']) && !empty($payload['user_id'])) {
        $payload['id'] = (string)$payload['user_id'];
    }

    if (empty($payload['company_id'])) {
        if (!empty($payload['companyId'])) {
            $payload['company_id'] = (string)$payload['companyId'];
        } elseif (!empty($payload['data']) && is_array($payload['data'])) {
            $payload['company_id'] = (string)($payload['data']['company_id'] ?? $payload['data']['companyId'] ?? '');
        } elseif (!empty($payload['user']) && is_array($payload['user'])) {
            $payload['company_id'] = (string)($payload['user']['company_id'] ?? $payload['user']['companyId'] ?? '');
        }
    }

    if (!empty($payload['company_id']) && empty($payload['companyId'])) {
        $payload['companyId'] = (string)$payload['company_id'];
    }

    return $payload;
}

function generateJWT(array $payload)
{
    $secret = stokpro_jwt_secret();
    $now = time();

    $normalizedPayload = stokpro_jwt_normalize_payload($payload);
    $normalizedPayload['iat'] = $normalizedPayload['iat'] ?? $now;
    $normalizedPayload['nbf'] = $normalizedPayload['nbf'] ?? $now;
    $normalizedPayload['exp'] = $normalizedPayload['exp'] ?? ($now + STOKPRO_JWT_TTL_SECONDS);

    $header = [
        'alg' => STOKPRO_JWT_ALGO,
        'typ' => 'JWT',
    ];

    $headerEncoded = stokpro_jwt_base64url_encode(json_encode($header, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
    $payloadEncoded = stokpro_jwt_base64url_encode(json_encode($normalizedPayload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
    $signature = hash_hmac('sha256', $headerEncoded . '.' . $payloadEncoded, $secret, true);
    $signatureEncoded = stokpro_jwt_base64url_encode($signature);

    return $headerEncoded . '.' . $payloadEncoded . '.' . $signatureEncoded;
}

function generate_jwt(array $payload)
{
    return generateJWT($payload);
}

function verifyJWT($jwt)
{
    if (!is_string($jwt) || trim($jwt) === '') {
        return false;
    }

    $parts = explode('.', trim($jwt));
    if (count($parts) !== 3) {
        return false;
    }

    list($headerEncoded, $payloadEncoded, $signatureEncoded) = $parts;

    $headerJson = stokpro_jwt_base64url_decode($headerEncoded);
    $payloadJson = stokpro_jwt_base64url_decode($payloadEncoded);
    $signature = stokpro_jwt_base64url_decode($signatureEncoded);

    if ($headerJson === false || $payloadJson === false || $signature === false) {
        return false;
    }

    $header = json_decode($headerJson, true);
    $payload = json_decode($payloadJson, true);

    if (!is_array($header) || !is_array($payload)) {
        return false;
    }

    if (($header['alg'] ?? '') !== STOKPRO_JWT_ALGO) {
        return false;
    }

    $expectedSignature = hash_hmac(
        'sha256',
        $headerEncoded . '.' . $payloadEncoded,
        stokpro_jwt_secret(),
        true
    );

    if (!hash_equals($expectedSignature, $signature)) {
        return false;
    }

    $now = time();
    if (!empty($payload['nbf']) && (int)$payload['nbf'] > $now) {
        return false;
    }

    if (!empty($payload['exp']) && (int)$payload['exp'] < $now) {
        return false;
    }

    return stokpro_jwt_normalize_payload($payload);
}

function verify_jwt($jwt)
{
    return verifyJWT($jwt);
}

function validateJWT($jwt)
{
    return verifyJWT($jwt);
}

function validate_jwt($jwt)
{
    return verifyJWT($jwt);
}

function decodeJWT($jwt)
{
    return verifyJWT($jwt);
}

function decode_jwt($jwt)
{
    return verifyJWT($jwt);
}
