<?php

declare(strict_types=1);

namespace SeoScope\Updates;

/**
 * Fetches https://seoscope.cloud/releases.json (or custom URL) — read-only, no auth.
 */
final class ReleaseInfoFetcher
{
    public function __construct(
        private string $url,
        private int $timeoutSec = 6
    ) {
    }

    /**
     * @return array{ok: true, info: ReleaseInfo}|array{ok: false, error: string}
     */
    public function fetch(): array
    {
        $url = trim($this->url);
        if ($url === '' || !str_starts_with($url, 'https://') && !str_starts_with($url, 'http://')) {
            return ['ok' => false, 'error' => 'invalid_url'];
        }

        $raw = $this->httpGet($url);
        if ($raw === null) {
            return ['ok' => false, 'error' => 'unreachable'];
        }

        $j = json_decode($raw, true);
        if (!is_array($j)) {
            return ['ok' => false, 'error' => 'invalid_json'];
        }

        $info = ReleaseInfo::fromJsonArray($j);
        if ($info === null) {
            return ['ok' => false, 'error' => 'invalid_payload'];
        }

        return ['ok' => true, 'info' => $info];
    }

    private function httpGet(string $url): ?string
    {
        if (function_exists('curl_init')) {
            $ch = curl_init($url);
            if ($ch === false) {
                return null;
            }
            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_FOLLOWLOCATION => true,
                CURLOPT_MAXREDIRS => 3,
                CURLOPT_TIMEOUT => $this->timeoutSec,
                CURLOPT_USERAGENT => 'SeoScope/ReleaseInfoFetcher',
            ]);
            $out = curl_exec($ch);
            $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            if (!is_string($out) || $out === '' || $code < 200 || $code >= 300) {
                return null;
            }

            return $out;
        }

        $ctx = stream_context_create([
            'http' => [
                'timeout' => $this->timeoutSec,
                'header' => "User-Agent: SeoScope/ReleaseInfoFetcher\r\n",
            ],
        ]);
        $out = @file_get_contents($url, false, $ctx);
        if (!is_string($out) || $out === '') {
            return null;
        }

        return $out;
    }
}
