<?php

namespace App\Services\BrentPriceSources;

use App\Services\ApiLogger;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Http;
use Throwable;

final class EiaBrentPriceSource
{
    private const string URL = 'https://api.eia.gov/v2/petroleum/pri/spt/data/';

    public function __construct(private readonly ApiLogger $apiLogger) {}

    /**
     * @return array{date: string, price_usd: float}[]|null null only when the response carried no usable rows
     *
     * @throws BrentPriceFetchException on network failure or non-2xx response after retries
     */
    public function fetch(): ?array
    {
        try {
            $response = $this->apiLogger->send('eia', 'GET', self::URL, fn () => Http::timeout(30)
                ->retry(3, 200, fn (Throwable $e) => $this->shouldRetry($e))
                ->throw()
                ->get(self::URL, [
                    'api_key' => config('services.eia.api_key'),
                    'frequency' => 'daily',
                    'data[0]' => 'value',
                    'facets[series][]' => 'RBRTE',
                    'sort[0][column]' => 'period',
                    'sort[0][direction]' => 'desc',
                    'length' => 30,
                ]));
        } catch (ConnectionException $e) {
            throw new BrentPriceFetchException("EIA connection failed: {$e->getMessage()}", previous: $e);
        } catch (RequestException $e) {
            throw new BrentPriceFetchException("EIA returned HTTP {$e->response->status()}", previous: $e);
        }

        $rows = collect($response->json('response.data') ?? [])
            ->filter(fn (array $row) => ($row['value'] ?? '.') !== '.')
            ->map(fn (array $row) => [
                'date' => $row['period'],
                'price_usd' => (float) $row['value'],
            ])
            ->all();

        return $rows === [] ? null : $rows;
    }

    private function shouldRetry(Throwable $e): bool
    {
        return $e instanceof ConnectionException
            || ($e instanceof RequestException && $e->response->serverError());
    }
}
