<?php

declare(strict_types=1);

namespace App\Shopware;

use RuntimeException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

final readonly class StoreApiClient
{
    public function __construct(
        private HttpClientInterface $httpClient,
        private string $baseUrl,
        private string $salesChannelAccessKey,
        private int $timeoutSeconds = 5,
    ) {
    }

    /**
     * @throws TransportExceptionInterface
     * @throws ServerExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws ClientExceptionInterface
     */
    public function searchProducts(array $criteria): array
    {
        $url = rtrim($this->baseUrl, '/') . '/store-api/search';

        $response = $this->httpClient->request('POST', $url, [
            'headers' => [
                'Content-Type' => 'application/json',
                'Accept' => 'application/json',
                'sw-access-key' => $this->salesChannelAccessKey,
            ],
            'json' => $criteria,
            'timeout' => $this->timeoutSeconds,
        ]);

        $statusCode = $response->getStatusCode();
        $content = $response->getContent(false);

        if ($statusCode < 200 || $statusCode >= 300) {
            throw new RuntimeException(sprintf(
                'Shopware Store API request failed with status %d. Response: %s',
                $statusCode,
                mb_substr(trim($content), 0, 1000)
            ));
        }

        $data = json_decode($content, true);

        if (!is_array($data)) {
            throw new RuntimeException('Shopware Store API returned invalid JSON.');
        }

        return $data;
    }
}