<?php

declare(strict_types=1);

namespace Ekdos\N8n;

use GuzzleHttp\Client as Guzzle;
use GuzzleHttp\Exception\GuzzleException;

/**
 * Duenner HTTP-Zugang zu n8n.
 *
 * Wirft bei einem HTTP-Fehlerstatus nicht: der Aufrufer entscheidet, was ein
 * 404 oder 502 aus n8n fuer die Oberflaeche bedeutet. Nur ein echter
 * Verbindungsfehler ergibt Status 0.
 */
final readonly class Client
{
    public function __construct(private Guzzle $http) {}

    public function get(string $url, array $headers = []): Reply
    {
        return $this->send('GET', $url, $headers, null);
    }

    public function post(string $url, ?array $json = null, array $headers = []): Reply
    {
        return $this->send('POST', $url, $headers, $json);
    }

    public function put(string $url, ?array $json = null, array $headers = []): Reply
    {
        return $this->send('PUT', $url, $headers, $json);
    }

    public function delete(string $url, ?array $json = null, array $headers = []): Reply
    {
        return $this->send('DELETE', $url, $headers, $json);
    }

    private function send(string $method, string $url, array $headers, ?array $json): Reply
    {
        $options = ['headers' => $headers + ['Accept' => 'application/json'], 'http_errors' => false];

        if ($json !== null) {
            $options['json'] = $json;
        }

        try {
            $response = $this->http->request($method, $url, $options);

            return new Reply(
                status: $response->getStatusCode(),
                body: (string) $response->getBody(),
                contentType: $response->getHeaderLine('Content-Type'),
            );
        } catch (GuzzleException) {
            // n8n nicht erreichbar. Kein Stacktrace ins Protokoll: der Aufrufer
            // meldet das als 502 und faellt, wo moeglich, auf den Cache zurueck.
            return new Reply(status: 0, body: '', contentType: '');
        }
    }
}
