<?php

namespace PaymentWebhooks\Gateway\Mollie;

use PaymentWebhooks\Contract\RequesterInterface;
use PaymentWebhooks\Infrastructure\Config;
use RuntimeException;
use WP_REST_Request;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

final class MollieAdditionalRequester implements RequesterInterface
{
    private string $apiKey;
    private Client $client;

    public function __construct()
    {
        $this->apiKey = Config::get('PW_MOLLIE_API_KEY');
        $this->client = new Client([
            'base_uri' => 'https://api.mollie.com/v2/',
            'timeout' => 5,
        ]);
    }

    public function get(WP_REST_Request $request): WP_REST_Request
    {
        $id = $request->get_param('id') ?? '';
        if (empty($id)) {
            throw new RuntimeException('Missing ID parameter');
        }
        $this->checkTransactionIDInRequest($id);

        $data = $this->fetchPayment($id);

        $newRequest = new WP_REST_Request('POST');
        $newRequest->set_body(json_encode($data));
        $newRequest->add_header('Content-Type', 'application/json');

        return $newRequest;
    }

    private function checkTransactionIDInRequest(string $id): void
    {
        if (!str_starts_with($id, 'tr_')) {
            throw new RuntimeException('Expected transaction ID starting with \"tr_\", got: ' . $id);
        }
    }

    /**
     * @throws RuntimeException
     * @throws GuzzleException
     */
    private function fetchPayment(string $id): array
    {
        $response = $this->client->get("payments/{$id}", [
            'headers' => [
                'Authorization' => "Bearer {$this->apiKey}",
                'Accept' => 'application/json',
            ],
        ]);

        if ($response->getStatusCode() !== 200) {
            throw new RuntimeException("Mollie API returned status {$response->getStatusCode()}");
        }

        $data = json_decode((string)$response->getBody(), true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new RuntimeException('Invalid JSON from Mollie: ' . json_last_error_msg());
        }

        return $data;
    }

}
