<?php

namespace Oney\ThreeByFour\Gateway\Http;

use Magento\Framework\HTTP\Client\Curl;
use Magento\Payment\Gateway\Http\ClientException;
use Magento\Payment\Gateway\Http\ClientInterface;
use Magento\Payment\Gateway\Http\ConverterException;
use Magento\Payment\Gateway\Http\ConverterInterface;
use Magento\Payment\Gateway\Http\TransferInterface;
use Magento\Payment\Model\Method\Logger;

class ClientRest implements ClientInterface
{
    const DEFAULT_ENC_TYPE = "application/json";

    /**
     * @var Curl
     */
    private $curl;

    /**
     * @var ConverterInterface|null
     */
    private $converter;

    /**
     * @var Logger
     */
    private $logger;

    public function __construct(
        Curl $curl,
        Logger $logger,
        ConverterInterface $converter = null
    ) {
        $this->curl = $curl;
        $this->converter = $converter;
        $this->logger = $logger;
    }

    /**
     * {@inheritdoc}
     *
     * @param TransferInterface $transferObject
     * @return array
     * @throws ClientException
     * @throws ConverterException
     */
    public function placeRequest(TransferInterface $transferObject)
    {
        $log = [
            'request' => $transferObject->getBody(),
            'request_uri' => $transferObject->getUri()
        ];

        try {
            // Préparer les headers et forcer Content-Type
            $headers = $transferObject->getHeaders() ?: [];
            if (!isset($headers['Content-Type'])) {
                $headers['Content-Type'] = self::DEFAULT_ENC_TYPE;
            }
            foreach ($headers as $key => $value) {
                $this->curl->addHeader($key, $value);
            }

            // Traiter la requête selon la méthode
            switch (strtoupper($transferObject->getMethod())) {
                case 'GET':
                    $url = $transferObject->getUri();
                    $params = $transferObject->getBody();
                    if (!empty($params)) {
                        $url .= '?' . http_build_query($params);
                    }
                    $this->curl->get($url);
                    break;

                case 'POST':
                    $this->curl->setOption(CURLOPT_POSTFIELDS, json_encode($transferObject->getBody()));
                    $this->curl->post($transferObject->getUri(), []); // second param vide
                    break;

                default:
                    throw new \LogicException(
                        sprintf('Unsupported HTTP method %s', $transferObject->getMethod())
                    );
            }

            // Récupérer la réponse et la convertir si nécessaire
            $responseBody = $this->curl->getBody();
            $result = $this->converter
                ? $this->converter->convert($responseBody)
                : [$responseBody];

            $log['response'] = $result;

        } catch (\Exception $e) {
            throw new ClientException(__($e->getMessage()));
        } finally {
            $this->logger->debug($log);
        }

        return $result;
    }
}
