<?php

namespace app\service;

/**
 * 签名验证服务
 * 完全按照 Python 版本实现
 */
class Signature
{
    /**
     * 生成API Key
     */
    public static function generateApiKey()
    {
        return bin2hex(random_bytes(6));
    }

    /**
     * 生成API Secret
     */
    public static function generateApiSecret()
    {
        return bin2hex(random_bytes(10));
    }

    /**
     * 对 API Secret 做 SHA256 哈希存储
     */
    public static function hashSecret($secret)
    {
        return hash('sha256', $secret);
    }

    /**
     * 验证签名（完全按照 Python 版本实现）
     * 
     * @param array $params 请求查询参数
     * @param string $timestamp X-Timestamp header 值
     * @param string $signature X-Sign header 值
     * @param string $apiSecretHash 数据库存储的 secret 哈希
     * @return bool
     */
    public static function verify($params, $timestamp, $signature, $apiSecretHash)
    {
        try {
            $ts = (int)$timestamp;
            if ($ts > 1e12) {
                $ts = (int)($ts / 1000);
            }
            $now = time();
            $expireSeconds = env('signature.expire_seconds', 300);
            if (abs($now - $ts) > $expireSeconds) {
                return false;
            }
        } catch (\Exception $e) {
            return false;
        }

        $sortedParams = [];
        foreach ($params as $k => $v) {
            $sortedParams[$k] = $v;
        }
        ksort($sortedParams);

        $paramParts = [];
        foreach ($sortedParams as $k => $v) {
            if ($v !== null && $v !== '') {
                $paramParts[] = "{$k}={$v}";
            }
        }
        $paramStr = implode('&', $paramParts);
        $fullStr = $paramStr . '&timestamp=' . $timestamp;

        $expectedSign = hash_hmac('sha256', $fullStr, $apiSecretHash);

        return strcasecmp($expectedSign, $signature) === 0;
    }

    /**
     * 生成签名（用于测试）
     * 
     * @param array $params 请求参数
     * @param string $timestamp 时间戳字符串
     * @param string $apiSecret API Secret 明文
     * @return string
     */
    public static function sign($params, $timestamp, $apiSecret)
    {
        $sortedParams = [];
        foreach ($params as $k => $v) {
            $sortedParams[$k] = $v;
        }
        ksort($sortedParams);

        $paramParts = [];
        foreach ($sortedParams as $k => $v) {
            if ($v !== null && $v !== '') {
                $paramParts[] = "{$k}={$v}";
            }
        }
        $paramStr = implode('&', $paramParts);
        $fullStr = $paramStr . '&timestamp=' . $timestamp;

        return hash_hmac('sha256', $fullStr, $apiSecret);
    }
}
