<?php

class CentravetStockApi
{
    protected string $apiUrl;

    protected string $apiLogin;

    protected string $apiPass;

    protected ?string $apiJwtToken = null;

    /**
     * Génération d'un token JWT pour l'Api CentraVet (one-shot).
     *
     * @throws Exception
     */
    protected function apiGetJWTToken(): string
    {
        $cache = Cache::getInstance();

        if (!$this->apiJwtToken) {
            $cachedToken = $cache->get('centravet_stock_jwt_token');
            if (!$cachedToken) {
                $curl = curl_init();
                if (!$curl) {
                    throw new Exception('Erreur initialisation cURL');
                }

                curl_setopt($curl, CURLOPT_URL, $this->apiUrl . '/auth/V2/tokens/user');
                curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
                curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode(['email' => $this->apiLogin, 'password' => $this->apiPass]));
                curl_setopt($curl, CURLOPT_HTTPHEADER,
                    [
                        'Content-Type: application/json',
                    ]
                );
                curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
                $result = curl_exec($curl);
                if (is_bool($result)) {
                    throw new Exception('Erreur requête cURL');
                }

                $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

                if ($statusCode < 200 || $statusCode >= 300) {
                    throw new Exception('Impossible de récupérer un token JWT');
                }

                $cachedToken = trim($result, ' "');
                // Token en cache pour 1500 secondes
                $cache->set('centravet_stock_jwt_token', $this->apiJwtToken, 1500);
            }

            $this->apiJwtToken = $cachedToken;
        }

        return $this->apiJwtToken;
    }

    public function checkStock(string $codeclinique, string $codeProduit, int $quantite): bool
    {
        $token = $this->apiGetJWTToken();

        $curl = curl_init();
        if (!$curl) {
            throw new Exception('Erreur initialisation cURL');
        }

        curl_setopt($curl, CURLOPT_URL, $this->apiUrl . '/openwebveto/V1/stocks/210633?codeClinique=' . urlencode($codeclinique) . '&homeDelivery=false');
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode([['articleCode' => $codeProduit, 'quantity' => $quantite]]));
        curl_setopt($curl, CURLOPT_HTTPHEADER,
            [
                'Authorization: Bearer ' . $token,
                'Content-Type: application/json',
            ]
        );
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($curl);
        if (is_bool($result)) {
            throw new Exception('Erreur requête cURL');
        }

        $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

        if ($statusCode < 200 || $statusCode >= 300) {
            throw new Exception('Code HTTP invalide');
        }

        $nbManquants = array_filter(
            json_decode($result, true),
            function ($line) {
                return false === $line['available'];
            }
        );

        // Si au moins 1 produit manquant, alors on considère que le stock n'est pas bon
        return 0 === count($nbManquants);
    }

    public function __construct(
        string $apiUrl,
        string $apiLogin,
        string $apiPass
    ) {
        $this->apiUrl = $apiUrl;
        $this->apiLogin = $apiLogin;
        $this->apiPass = $apiPass;
    }
}
