<?php

declare(strict_types=1);

namespace Myvetshop\Module\Clinique\Api;

class CricCrocApi
{
    private string $host = 'https://www.crokit.fr';

    /**
     * @return array{
     *    code: string,
     *    petname: string,
     *    race: string,
     *    act: string,
     *    age: string,
     *    date: string,
     *    esp: string,
     *    sex: int,
     *    stadePhysio: string,
     *    patho: string,
     *    actualw: float,
     *    idealw: float,
     *    be: int,
     *    nbrAliment: int,
     *    dob: string|null,
     *    productIDmvs1: int|null,
     *    productIDmvs2: int|null,
     *    productIDmvs3: int|null,
     *    qteAliment1: int|null,
     *    qteAliment2: int|null,
     *    qteAliment3: int|null,
     *    transition12: int|null,
     *    transition23: int|null,
     * }
     *
     * @throws \Exception
     */
    public function getRecommandationByCode(string $code): array
    {
        $code = strtoupper($code);

        if (1 !== preg_match('#^[A-Z0-9]{5}$#', $code)) {
            throw new \Exception('Code reco invalide. Il doit être composé de 5 lettres et chiffres.');
        }

        $path = '/MVSreturn.php?secure=SMV4521bou&codeReco=' . urlencode($code);
        $data = $this->request($path);

        $data = \json_decode($data, true);

        if (\is_array($data) && isset($data[0])) {
            $recommandation = $data[0];

            // Si il n'y a pas de code, c'est que la recommandation n'existe pas / plus.
            if (null === $recommandation['code']) {
                throw new \Exception("Cette recommandation n'est plus disponible.");
            }
            $recommandationDate = \DateTime::createFromFormat('d-m-Y', $recommandation['date'])
                ?: new \DateTime();
            $dobDate = !empty($recommandation['dob']) ?
                \DateTime::createFromFormat('d-m-Y', $recommandation['dob'])
                : null;

            $recommandation['date'] = $recommandationDate->format('Y-m-d');
            $recommandation['esp'] = strtolower($recommandation['esp']);
            $recommandation['sex'] = str_contains(strtolower($recommandation['sex']), 'mâle') ? 1 : 2;
            $recommandation['dob'] = $dobDate ? $dobDate->format('Y-m-d') : null;
            $recommandation['productIDmvs1'] = !empty($recommandation['productIDmvs1'])
                ? (int) $recommandation['productIDmvs1']
                : null;
            $recommandation['productIDmvs2'] = !empty($recommandation['productIDmvs2'])
                ? (int) $recommandation['productIDmvs2']
                : null;
            $recommandation['productIDmvs3'] = !empty($recommandation['productIDmvs3'])
                ? (int) $recommandation['productIDmvs3']
                : null;
            $recommandation['qteAliment1'] = !empty($recommandation['qteAliment1'])
                ? (int) $recommandation['qteAliment1']
                : null;
            $recommandation['qteAliment2'] = !empty($recommandation['qteAliment2'])
                ? (int) $recommandation['qteAliment2']
                : null;
            $recommandation['qteAliment3'] = !empty($recommandation['qteAliment3'])
                ? (int) $recommandation['qteAliment3']
                : null;
            $recommandation['transition12'] = !empty($recommandation['transition12'])
                ? (int) $recommandation['transition12']
                : null;
            $recommandation['transition23'] = !empty($recommandation['transition23'])
                ? (int) $recommandation['transition23']
                : null;

            return $recommandation;
        }

        throw new \Exception('Retour cric-croc invalide.');
    }

    public function getPdf(string $codeReco): string
    {
        return $this->request('/pdf/' . urlencode($codeReco) . '.pdf');
    }

    protected function request(string $endpoint): string
    {
        $curl = curl_init();
        if (!$curl) {
            throw new \Exception('Erreur initialisation cURL');
        }
        curl_setopt($curl, \CURLOPT_URL, $this->host . $endpoint);
        curl_setopt($curl, \CURLOPT_TIMEOUT, 30);
        curl_setopt($curl, \CURLOPT_RETURNTRANSFER, 1);

        $ret = curl_exec($curl);

        if (\is_bool($ret)) {
            throw new \Exception('Erreur requête cURL');
        }

        return $ret;
    }
}
