<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\FranceTravailApiBundle\ApiHelper;

use GuzzleHttp\Client;
use Psr\Log\LoggerInterface;
use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface;

/**
 * Queries for ROME partenaires api.
 */
class PartenaireRomeAppellation
{
    use ProcessRequestTrait;
    /**
     * @var ApiWrapper
     */
    protected $wrapper;

    /**
     * @var Client
     */
    protected $client;

    /**
     * @var LoggerInterface
     */
    protected $logger;

    private const BASE = 'https://api.pole-emploi.io/partenaire/rome-metiers/v1/metiers/';

    public function __construct(
        ApiWrapper $wrapper,
        LoggerInterface $logger,
        private \Symfony\Contracts\HttpClient\HttpClientInterface $httpClient,
    ) {
        $this->wrapper = $wrapper;
        $this->logger = $logger;
        $this->client = new Client([
            'base_uri' => 'https://api.pole-emploi.io/partenaire/rome-metiers/v1/metiers/',
        ]);
    }

    private function getBearer()
    {
        return $this->wrapper->getPublicBearer([
            'api_rome-metiersv1',
            'nomenclatureRome',
        ]);
    }

    public function getListeAppellation(string $search): array
    {
        $bearer = $this->getBearer();

        try {
            $response = $this->httpClient->request(
                'GET',
                self::BASE.'appellation/requete',
                [
                    'headers' => [
                        'Authorization' => 'Bearer '.$bearer,
                        'Accept' => 'application/json',
                    ],
                    'query' => [
                        'q' => $search,
                    ],
                ]
            );

            return $response->toArray()['resultats'];
        } catch (HttpExceptionInterface $exception) {
            throw $exception;
        }
    }

    public function getAppellation(string $code): array
    {
        $bearer = $this->getBearer();

        while (true) {
            try {
                $response = $this->httpClient->request('GET', sprintf(self::BASE.'appellation/%s', $code), [
                    'headers' => [
                        'Authorization' => 'Bearer '.$bearer,
                        'Accept' => 'application/json',
                    ],
                    'query' => [
                        'champs' => 'code,libelle,metier(code,libelle)',
                    ],
                ]);

                return $response->toArray();
            } catch (HttpExceptionInterface $exception) {
                if (429 === $exception->getResponse()->getStatusCode()) {
                    $retryAfter = $exception->getResponse()->getHeaders(false)['retry-after'][0] ?? 1;
                    sleep((int) $retryAfter);
                } else {
                    throw $exception;
                }
            }
        }
    }
}
