<?php

namespace Win7\Ads\Service;

use Google\Client;
use GuzzleHttp\Client as GuzzleClient;
use Psr\Http\Message\ResponseInterface;
use Win7\App;
use Win7\Utils\ArrayUtils;

/**
 * Serviço responsável por realizar as requisições ao Google Ads.
 *
 * @author Thiago Daher
 */
class RequestManager
{

    /**
     * @var GuzzleClient
     */
    private $client;

    /**
     * @var array
     */
    private $config;

    /**
     * Construtor
     */
    public function __construct()
    {
        $this->config = App::getConfig()->get('google_ads');
    }

    /**
     * Envia uma solicitação POST para o Google Ads.
     *
     * @param string $path caminho (URL parcial) da requisição
     * @param array $params parâmetros da requisição, como body, headers, etc
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function sendPost(string $path, array $params): ResponseInterface
    {
        return $this->getClient()->post(
            $this->getFullUrl($path),
            $this->getRequestParams($params)
        );
    }

    /**
     * @return GuzzleClient
     */
    public function getClient(): GuzzleClient
    {
        if (!isset($this->client)) {
            $this->initClient();
        }

        return $this->client;
    }

    /**
     * Inicializa o cliente HTTP responsável pelas requisições.
     *
     * @return void
     */
    private function initClient()
    {
        $client = new Client();
        $client->addScope($this->config['scope']);
        $client->setAccessType('offline');
        $client->setClientId($this->config['client_id']);
        $client->setClientSecret($this->config['client_secret']);
        $client->fetchAccessTokenWithRefreshToken($this->config['refresh_token']);
        $this->client = $client->authorize();
    }

    /**
     * @param string $resourcePath
     * @return string
     */
    private function getFullUrl(string $resourcePath): string
    {
        return sprintf(
            '%s/v%s/%s',
            $this->config['url'],
            $this->config['version'],
            $resourcePath
        );
    }

    /**
     * @param array $replace
     * @return array
     */
    private function getRequestParams(array $replace): array
    {
        return ArrayUtils::arrayMergeRecursiveDistinct([
            'headers' => [
                'developer-token'   => $this->config['developer_token'],
                'login-customer-id' => $this->config['admin_id'],
            ],
        ], $replace);
    }

    /**
     * Envia uma solicitação GET para o Google Ads.
     *
     * @param string $path caminho (URL parcial) da requisição
     * @param array $params parâmetros da requisição, como query, headers, etc
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function sendGet(string $path, array $params): ResponseInterface
    {
        return $this->getClient()->get(
            $this->getFullUrl($path),
            $this->getRequestParams($params)
        );
    }
}