<?php
declare(strict_types=1);

/**
 * WebhookPay PHP quick-start (HMAC theo Event + Raw Body).
 * Yêu cầu PHP 8.1+ và cURL.
 */
final class WebhookPayClient
{
    public function __construct(
        private readonly string $baseUrl,
        private readonly string $apiKey,
        private readonly string $apiSecret,
        private readonly array $proxy = [],
        private readonly int $connectTimeout = 8,
        private readonly int $timeout = 20
    ) {
        $parts = parse_url($this->baseUrl);
        $scheme = strtolower((string)($parts['scheme'] ?? ''));
        if (!in_array($scheme, ['http','https'], true) || empty($parts['host'])) {
            throw new InvalidArgumentException('baseUrl phải là URL HTTP hoặc HTTPS hợp lệ.');
        }
    }

    public function ping(): array { return $this->request('GET','/api/v1/ping','system.ping'); }
    public function paymentMethods(): array { return $this->request('GET','/api/v1/payment-methods','payment.methods.list'); }
    public function createPayment(array $payload,string $idempotencyKey): array { return $this->request('POST','/api/v1/payment-requests','payment.request.create',$payload,['Idempotency-Key: '.$idempotencyKey]); }
    public function payment(string $paymentId): array { return $this->request('GET','/api/v1/payment-requests/'.rawurlencode($paymentId),'payment.request.status'); }

    private function request(string $method,string $path,string $event,?array $payload=null,array $extraHeaders=[]): array
    {
        if(!function_exists('curl_init')) throw new RuntimeException('PHP chưa bật extension cURL.');
        $method=strtoupper($method);
        $rawBody=$payload===null?'':json_encode($payload,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|JSON_THROW_ON_ERROR);
        $signature=hash_hmac('sha256',$event."\n".$rawBody,$this->apiSecret);
        $headers=array_merge([
            'Accept: application/json',
            'Content-Type: application/json',
            'X-API-Key: '.$this->apiKey,
            'X-API-Event: '.$event,
            'X-API-Signature: '.$signature,
            'X-API-Signature-Alg: HMAC-SHA256',
        ],$extraHeaders);
        $url=rtrim($this->baseUrl,'/').$path;
        $ch=curl_init($url);if($ch===false)throw new RuntimeException('Không thể khởi tạo cURL.');
        $options=[CURLOPT_CUSTOMREQUEST=>$method,CURLOPT_HTTPHEADER=>$headers,CURLOPT_RETURNTRANSFER=>true,CURLOPT_FOLLOWLOCATION=>false,CURLOPT_CONNECTTIMEOUT=>$this->connectTimeout,CURLOPT_TIMEOUT=>$this->timeout];
        if(str_starts_with(strtolower($url),'https://')){$options[CURLOPT_SSL_VERIFYPEER]=true;$options[CURLOPT_SSL_VERIFYHOST]=2;}
        curl_setopt_array($ch,$options);
        if($payload!==null)curl_setopt($ch,CURLOPT_POSTFIELDS,$rawBody);
        $this->applyProxy($ch);
        $body=curl_exec($ch);if($body===false){$e=curl_error($ch);curl_close($ch);throw new RuntimeException('Lỗi kết nối API: '.$e);} $status=(int)curl_getinfo($ch,CURLINFO_RESPONSE_CODE);curl_close($ch);
        $decoded=json_decode((string)$body,true);if(!is_array($decoded))throw new RuntimeException('API trả dữ liệu không phải JSON.');
        if($status<200||$status>=300||empty($decoded['success'])){$code=(string)($decoded['error']['code']??'API_ERROR');$message=(string)($decoded['error']['message']??('API HTTP '.$status));throw new RuntimeException($code.': '.$message);}
        return (array)($decoded['data']??[]);
    }

    private function applyProxy($ch): void
    {
        if(empty($this->proxy['enabled'])) return;
        $host=trim((string)($this->proxy['host']??''));$port=(int)($this->proxy['port']??0);$type=strtolower((string)($this->proxy['type']??'http'));
        if($host===''||$port<1||$port>65535)throw new RuntimeException('Cấu hình proxy không hợp lệ.');
        curl_setopt($ch,CURLOPT_PROXY,$host);curl_setopt($ch,CURLOPT_PROXYPORT,$port);
        if($type==='socks5'){
            if(!defined('CURLPROXY_SOCKS5_HOSTNAME'))throw new RuntimeException('cURL hiện tại không hỗ trợ SOCKS5 hostname.');
            curl_setopt($ch,CURLOPT_PROXYTYPE,CURLPROXY_SOCKS5_HOSTNAME);
        }else curl_setopt($ch,CURLOPT_PROXYTYPE,CURLPROXY_HTTP);
        $user=(string)($this->proxy['username']??'');$pass=(string)($this->proxy['password']??'');if($user!==''||$pass!=='')curl_setopt($ch,CURLOPT_PROXYUSERPWD,$user.':'.$pass);
        if(defined('CURLOPT_NOPROXY'))curl_setopt($ch,CURLOPT_NOPROXY,'');
    }
}

/*
$client = new WebhookPayClient(
    'https://payment.example.com', // có thể dùng http:// nếu môi trường cần tương thích
    'YOUR_API_KEY',
    'YOUR_API_SECRET',
    [
        'enabled' => false,
        'type' => 'socks5', // http hoặc socks5
        'host' => '127.0.0.1',
        'port' => 1080,
        'username' => '',
        'password' => '',
    ]
);

$payment = $client->createPayment([
    'merchant_invoice_id' => 'ABC123ABCB',
    'amount' => 100000,
    'description' => 'Nạp số dư',
], 'order-ABC123ABCB');
*/
