<?php

namespace AutoAdmin\Bundle\Content\Service;

use DateInterval;
use DateTime;
use Exception;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

class GoogleAnalyticsServiceApi
{
    private const GA_API_URL = "https://ga.api.gda.host";
    private const AVAILABLE_TYPES = ['visit', 'audience'];

    private HttpClientInterface $httpClient;
    private RequestStack $requestStack;
    private string $apiKey;
    private string $env;

    public function __construct(
        HttpClientInterface $httpClient,
        RequestStack $requestStack,
        string $apiKey,
        string $env
    ) {
        $this->httpClient = $httpClient;
        $this->requestStack = $requestStack;
        $this->apiKey = $apiKey;
        $this->env = $env;
    }

    /**
     * @throws TransportExceptionInterface
     * @throws ServerExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws DecodingExceptionInterface
     * @throws ClientExceptionInterface
     * @throws Exception
     */
    public function getStats($type, string $domain, array $period): array
    {
        if (!in_array($type, self::AVAILABLE_TYPES)) {
            throw new Exception('No stats for this type, available types : '.implode(', ', self::AVAILABLE_TYPES));
        }

        $domain = $this->env === 'dev' ? 'www.arthur-loyd.com' : 'www'.$domain;

        $domainBase64 = base64_encode($domain);

        $from = $period['from'] ?
            (new DateTime($period['from']))->format('Y-o') :
            (new DateTime())->sub(new DateInterval("P1Y"))->format('Y-o');

        $to = (new DateTime($period['to'] ?? 'now'))->format('Y-o');

        $url = self::GA_API_URL."/api/$domainBase64/traffic/$type"."?date_type=range_week&from=$from&to=$to";

        $response = $this->httpClient->request(
            'GET', $url,
            [
                'headers' => [
                    'X-AUTH-TOKEN' => $this->apiKey,
                ],
                'verify_peer' => false,
                'verify_host' => false,
                'max_redirects' => 0,
            ]
        );

        if ($response->getStatusCode() === 400) {
            throw new Exception('The domain "' . $domain . '" was not registered to the database');
        }

        return $response->toArray();
    }
}
