<?php

namespace Medienreaktor\Career\Command;

use GuzzleHttp\Exception\ClientException;
use TYPO3\CMS\Core\Core\Environment;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Style\SymfonyStyle;
use TYPO3\CMS\Core\Http\RequestFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Connection;
class GenerateApiToken extends Command
{
    protected const API_ENDPOINT = "https://accounts.zoho.eu/oauth/v2/token";
    protected function configure(): void
    {
        $this->setDescription('Generate ZoHo Api Token');
        $this->addArgument('code', InputArgument::REQUIRED, 'Code');
        $this->addArgument('client_id', InputArgument::REQUIRED, 'Client ID');
        $this->addArgument('client_secret', InputArgument::REQUIRED, 'Client Secret');
        $this->addArgument('redirect_uri', InputArgument::REQUIRED, 'Redirect Uri');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {

        $code = $input->getArgument("code") ? $input->getArgument("code") : NULL;
        $clientId = $input->getArgument("client_id") ? $input->getArgument("client_id") : NULL;
        $clientSecret = $input->getArgument("client_secret") ? $input->getArgument("client_secret") : NULL;
        $redirectUri = $input->getArgument("redirect_uri") ? $input->getArgument("redirect_uri") : "/";

        $response = $this->rawApiCall($code, $clientId, $clientSecret, $redirectUri);

        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_career_api_token_collection');
        $affectedRows = $queryBuilder
            ->insert('tx_career_api_token_collection')->values([
            'access_token' => $response['access_token'],
            'refresh_token' => $response['refresh_token'],
            'client_id' => $clientId,
            'client_secret' => $clientSecret,
            'api_domain' => $response['api_domain'],
            'token_type' => $response['token_type'],
            'expires_in' => $response['expires_in'],
            'is_refresh' => 0,
            'crdate' => time(),
        ])->executeStatement();
        return 0;
    }

    protected function rawApiCall(string $code, string $clientId, string $clientSecret, string $redirectUri): ?array {

        /** @var RequestFactory $requestFactory */
        $requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
        $url = self::API_ENDPOINT;

        $additionalOptions = [
            'form_params' => [
                'code' => $code,
                'grant_type' => 'authorization_code',
                'client_id' => $clientId,
                'client_secret' => $clientSecret,
                'redirect_uri' => $redirectUri,
            ],

        ];

        try {
            $response = $requestFactory->request($url, 'POST', $additionalOptions);

        } catch (ClientException $exception) {
            return null;
        }
        return json_decode($response->getBody()->getContents(), true);
    }
}