<?php
declare(strict_types=1);

namespace SeoScope\Licensing;

final class LicenseClient
{
    public function __construct(
        private string $baseUrl,
        private ?string $devSecret = null
    ) {
        $this->baseUrl = rtrim($this->baseUrl, '/');
    }

    /**
     * @return array{ok:bool,status:int,data:array<string,mixed>|null}
     */
    public function activate(string $purchaseCode, string $domain, string $installId): array
    {
        return $this->postJson('/api/v1/activate', [
            'purchase_code' => $purchaseCode,
            'domain' => $domain,
            'install_id' => $installId,
        ]);
    }

    /**
     * @return array{ok:bool,status:int,data:array<string,mixed>|null}
     */
    public function validate(string $token, string $domain, string $installId): array
    {
        return $this->postJson('/api/v1/validate', [
            'token' => $token,
            'domain' => $domain,
            'install_id' => $installId,
        ]);
    }

    /**
     * @param array<string,mixed> $payload
     * @return array{ok:bool,status:int,data:array<string,mixed>|null}
     */
    private function postJson(string $path, array $payload): array
    {
        $url = $this->baseUrl . $path;
        $ch = curl_init($url);
        if ($ch === false) {
            return ['ok' => false, 'status' => 0, 'data' => null];
        }
        $json = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        if (!is_string($json)) {
            $json = '{}';
        }
        $headers = [
            'Content-Type: application/json',
            'Accept: application/json',
            'User-Agent: SeoScope/LicenseClient',
        ];
        if (is_string($this->devSecret) && $this->devSecret !== '') {
            $headers[] = 'X-Licensing-Dev-Secret: ' . $this->devSecret;
        }
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $json,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_TIMEOUT => 15,
        ]);
        $body = curl_exec($ch);
        $status = (int) curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
        curl_close($ch);

        if ($body === false || $body === null) {
            return ['ok' => false, 'status' => $status > 0 ? $status : 0, 'data' => null];
        }
        $data = json_decode((string) $body, true);
        return [
            'ok' => $status >= 200 && $status < 300,
            'status' => $status,
            'data' => is_array($data) ? $data : null,
        ];
    }
}

