<?php
/**
 * FastPayGlobal PHP SDK v1.0.0
 * Requires: PHP 7.4+, ext-curl, ext-json
 */

namespace FastPayGlobal;

class FastPayGlobalException extends \Exception {
    public string $code;
    public function __construct(string $code, string $message) {
        parent::__construct($message);
        $this->code = $code;
    }
}

class Client {
    private string $publicKey;
    private string $secretKey;
    private string $webhookSecret;
    private string $baseUrl;

    public function __construct(array $opts) {
        $this->publicKey     = $opts['publicKey']     ?? '';
        $this->secretKey     = $opts['secretKey']     ?? '';
        $this->webhookSecret = $opts['webhookSecret'] ?? '';
        $this->baseUrl       = rtrim($opts['baseUrl'] ?? 'https://demo.fastpayglobal.app', '/');
    }

    /**
     * Create a payment. Returns ['id', 'hostedUrl', 'expiresAt', ...]
     */
    public function createPayment(array $payload): array {
        return $this->request('POST', '/api/public/create-payment', $payload, true);
    }

    /** Get payment status. */
    public function getPayment(string $id): array {
        return $this->request('GET', "/api/public/payment/$id");
    }

    /** Manually verify a transaction id submitted by customer. */
    public function verifyPayment(string $id, string $trxId, ?string $sender = null): array {
        return $this->request('POST', '/api/public/verify-payment', [
            'paymentId' => $id, 'trxId' => $trxId, 'sender' => $sender,
        ], true);
    }

    /** Verify incoming webhook signature (X-Signature header). */
    public function verifyWebhook(string $rawBody, string $signature): bool {
        if ($this->webhookSecret === '') return false;
        $expected = hash_hmac('sha256', $rawBody, $this->webhookSecret);
        return hash_equals($expected, $signature);
    }

    private function request(string $method, string $path, ?array $body = null, bool $usePublicKey = false): array {
        $ch = curl_init($this->baseUrl . $path);
        $headers = ['Content-Type: application/json', 'Accept: application/json'];
        if ($usePublicKey) $headers[] = 'X-Public-Key: ' . $this->publicKey;
        if ($this->secretKey) $headers[] = 'X-Secret-Key: ' . $this->secretKey;

        curl_setopt_array($ch, [
            CURLOPT_CUSTOMREQUEST  => $method,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER     => $headers,
            CURLOPT_TIMEOUT        => 30,
        ]);
        if ($body !== null) curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));

        $resp = curl_exec($ch);
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $err  = curl_error($ch);
        curl_close($ch);

        if ($resp === false) throw new FastPayGlobalException('network_error', $err);
        $data = json_decode($resp, true) ?? [];
        if ($code >= 400) {
            throw new FastPayGlobalException('api_error_' . $code, $data['error'] ?? "HTTP $code");
        }
        return $data;
    }
}

// Deprecated alias kept for older integrations.
if (!\class_exists(__NAMESPACE__ . "\\PaysolutionException")) {
    \class_alias(__NAMESPACE__ . "\\FastPayGlobalException", __NAMESPACE__ . "\\PaysolutionException");
}
