<?php

declare(strict_types=1);

/**
 * 命令行模拟商城服务端调用 PLAYX_TOKEN_VERIFY_URL（回调 verify-token）。
 *
 * 用法（在项目根目录执行）：
 *   php scripts/playx-verify-token-callback-test.php "<playx_token>"
 *
 * 可选环境变量（未设置则从项目根 .env 读取）：
 *   PLAYX_TOKEN_VERIFY_URL  默认 https://callback-mallsys.superior3.net/callback/api/mallsys/plx/auth/verify-token
 *   PLAYX_ANGPOW_MERCHANT_CODE    回调 Body merchant_code（必填）
 *   PLAYX_ANGPOW_IMPORT_AUTH_KEY  与 angpow-imports 相同的 HMAC 密钥
 */

$root = dirname(__DIR__);

function loadDotEnv(string $path): void
{
    if (!is_file($path)) {
        return;
    }
    foreach (file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: [] as $line) {
        $line = trim($line);
        if ($line === '' || str_starts_with($line, '#')) {
            continue;
        }
        if (!str_contains($line, '=')) {
            continue;
        }
        $pos = strpos($line, '=');
        $name = trim(substr($line, 0, $pos));
        $value = trim(substr($line, $pos + 1));
        if ($name !== '') {
            $_ENV[$name] = $value;
            putenv($name . '=' . $value);
        }
    }
}

function resolveKeyBytes(string $authKey): string
{
    $maybeBase64 = base64_decode($authKey, true);
    if (is_string($maybeBase64) && $maybeBase64 !== '') {
        return $maybeBase64;
    }
    $isHex = ctype_xdigit($authKey) && (strlen($authKey) % 2 === 0);
    if ($isHex) {
        $hex = hex2bin($authKey);
        if (is_string($hex) && $hex !== '') {
            return $hex;
        }
    }

    return $authKey;
}

function buildSignature(string $input, string $authKey): string
{
    $raw = hash_hmac('sha1', $input, resolveKeyBytes($authKey), true);

    return base64_encode($raw);
}

loadDotEnv($root . DIRECTORY_SEPARATOR . '.env');

$token = $argv[1] ?? '';
if ($token === '') {
    fwrite(STDERR, "用法: php scripts/playx-verify-token-callback-test.php \"<playx_token>\"\n");
    exit(1);
}

$url = strval($_ENV['PLAYX_TOKEN_VERIFY_URL'] ?? getenv('PLAYX_TOKEN_VERIFY_URL') ?: '');
if ($url === '') {
    $url = 'https://callback-mallsys.superior3.net/callback/api/mallsys/plx/auth/verify-token';
}

$merchantCode = strval($_ENV['PLAYX_ANGPOW_MERCHANT_CODE'] ?? getenv('PLAYX_ANGPOW_MERCHANT_CODE') ?: '');
$authKey = strval($_ENV['PLAYX_ANGPOW_IMPORT_AUTH_KEY'] ?? getenv('PLAYX_ANGPOW_IMPORT_AUTH_KEY') ?: '');
if ($merchantCode === '') {
    fwrite(STDERR, "缺少 PLAYX_ANGPOW_MERCHANT_CODE（请在 .env 配置或导出环境变量）\n");
    exit(1);
}
if ($authKey === '') {
    fwrite(STDERR, "缺少 PLAYX_ANGPOW_IMPORT_AUTH_KEY（请在 .env 配置或导出环境变量）\n");
    exit(1);
}

$requestId = 'mall_cli_' . uniqid();
$requestDate = strval(time());
$canonical = 'merchant_code=' . $merchantCode
    . '&request_date=' . $requestDate
    . '&request_id=' . $requestId
    . '&token=' . $token;
$signature = buildSignature($canonical, $authKey);

$payload = json_encode([
    'merchant_code' => $merchantCode,
    'request_date'  => $requestDate,
    'request_id'    => $requestId,
    'token'         => $token,
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if ($payload === false) {
    fwrite(STDERR, "JSON 编码失败\n");
    exit(1);
}

echo "--- 等价 curl（Linux / macOS / Git Bash）---\n";
echo "curl -sS -X POST '" . $url . "' \\\n";
echo "  -H 'Content-Type: application/json' \\\n";
echo "  -H 'X-Request-Signature: " . $signature . "' \\\n";
echo "  -d '" . $payload . "'\n\n";

echo "--- 本机直接请求（PHP stream）---\n";
echo "request_id={$requestId}\n";
echo "request_date={$requestDate}\n";
echo "canonical={$canonical}\n\n";

$body = $payload;
$ctx = stream_context_create([
    'http' => [
        'method'        => 'POST',
        'header'        => "Content-Type: application/json\r\nX-Request-Signature: {$signature}\r\n",
        'content'       => $body,
        'timeout'       => 15,
        // 4xx/5xx 仍返回响应体，便于查看对端错误说明（否则 file_get_contents 直接 false）
        'ignore_errors' => true,
    ],
    'ssl' => [
        'verify_peer'      => true,
        'verify_peer_name' => true,
    ],
]);

$result = @file_get_contents($url, false, $ctx);
if ($result === false) {
    $err = error_get_last();
    fwrite(STDERR, "请求失败: " . ($err['message'] ?? 'unknown') . "\n");
    exit(1);
}

$statusLine = isset($http_response_header[0]) ? $http_response_header[0] : '';
echo "--- HTTP 响应行 ---\n";
echo $statusLine . "\n";
if (isset($http_response_header[1])) {
    echo "--- 响应头（节选）---\n";
    $max = min(12, count($http_response_header));
    for ($i = 1; $i < $max; $i++) {
        echo $http_response_header[$i] . "\n";
    }
}
echo "--- 响应体 ---\n";
echo $result . "\n";

if (!preg_match('/\b200\b/', $statusLine)) {
    fwrite(STDERR, "\n提示：非 2xx 时请根据响应体与对端核对签名字符串、Body 字段是否与回调网关约定一致。\n");
    exit(2);
}
