<?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 Chill\MainBundle\Redis\ChillRedis;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;

/**
 * Wraps the pole emploi api.
 */
class ApiWrapper
{
    /**
     * @var Client
     */
    private $client;

    /**
     * key for the bearer for the api pole emploi.
     *
     * This bearer is shared across users
     */
    public const UNPERSONAL_BEARER = 'api_pemploi_bear_';

    public function __construct(private $clientId, private $clientSecret, private readonly ChillRedis $redis)
    {
        $this->client = new Client([
            'base_uri' => 'https://entreprise.francetravail.fr/connexion/oauth2/access_token',
        ]);
    }

    public function getPublicBearer($scopes): string
    {
        $cacheKey = $this->getCacheKey($scopes);

        if ($this->redis->exists($cacheKey) > 0) {
            $data = \unserialize($this->redis->get($cacheKey));

            return $data->access_token;
        }

        try {
            $response = $this->client->post('', [
                'query' => ['realm' => '/partenaire'],
                'headers' => [
                    'Content-Type' => 'application/x-www-form-urlencoded',
                ],
                'form_params' => [
                    'grant_type' => 'client_credentials',
                    'client_id' => $this->clientId,
                    'client_secret' => $this->clientSecret,
                    'scope' => \implode(' ', \array_merge($scopes, ['application_'.$this->clientId])),
                ],
            ]);
        } catch (ClientException $e) {
            dump($e->getResponse());
        }
        $data = \json_decode((string) $response->getBody());

        // set the key with an expiry time
        $this->redis->setex(
            $cacheKey,
            $data->expires_in - 2,
            \serialize($data)
        );

        return $data->access_token;
    }

    protected function getCacheKey($scopes)
    {
        return self::UNPERSONAL_BEARER.implode('', $scopes);
    }
}
