<?php

namespace App\Service\Typo3;

use App\Service\Utils\UrlBuilder;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;

/**
 * Service d'appel à l'API de l'instance Typo3
 */
class Typo3Service
{
    public function __construct(
        private readonly HttpClientInterface $typo3_client,
    )
    {}

    /**
     * Send a command to the given route of the Typo3 API
     *
     * @param string $route
     * @param array<mixed> $parameters
     * @return ResponseInterface
     * @throws TransportExceptionInterface
     */
    protected function sendCommand(string $route, array $parameters): ResponseInterface
    {
        $url = UrlBuilder::concatParameters('/typo3/index.php?route=' . $route, $parameters);
        return $this->typo3_client->request('GET', $url);
    }

    /**
     * Clear the cache of the given organization's website
     * @throws TransportExceptionInterface
     */
    public function clearSiteCache(int $organizationId): ResponseInterface
    {
        return $this->sendCommand('/otadmin/site/clear-cache', ['organization-id' => $organizationId]);
    }

    /**
     * Create a new Typo3 website for the given organization
     * @throws TransportExceptionInterface
     */
    public function createSite(int $organizationId): ResponseInterface
    {
        return $this->sendCommand('/otadmin/site/create', ['organization-id' => $organizationId]);
    }

    /**
     * Update the given organization's website with the Opentalent DB data
     * @throws TransportExceptionInterface
     */
    public function updateSite(int $organizationId): ResponseInterface
    {
        return $this->sendCommand('/otadmin/site/update', ['organization-id' => $organizationId]);
    }

    /**
     * Mark the given organization's website as deleted. This can be reverted with 'undeleteSite'
     * @throws TransportExceptionInterface
     */
    public function deleteSite(int $organizationId): ResponseInterface
    {
        return $this->sendCommand('/otadmin/site/delete', ['organization-id' => $organizationId]);
    }

    /**
     * Restore a website that has been deleted with 'deleteSite'
     * @throws TransportExceptionInterface
     */
    public function undeleteSite(int $organizationId): ResponseInterface
    {
        return $this->sendCommand('/otadmin/site/undelete', ['organization-id' => $organizationId]);
    }

    /**
     * Set a custom domain for the given website
     * @throws TransportExceptionInterface
     */
    public function setSiteDomain(int $organizationId, string $newDomain, bool $addRedirection=false): ResponseInterface
    {
        $params = ['organization-id' => $organizationId, 'domain' => $newDomain];
        if ($addRedirection) {
            $params['redirect'] = 1;
        }
        return $this->sendCommand('/otadmin/site/set-domain', $params);
    }

    /**
     * Reset the permissions of the BE users of the given organization's website
     * @throws TransportExceptionInterface
     */
    public function resetSitePerms(int $organizationId): ResponseInterface
    {
        return $this->sendCommand('/otadmin/site/reset-perms', ['organization-id' => $organizationId]);
    }

    /**
     * Returns the given organization's website status
     * @throws TransportExceptionInterface
     */
    public function getSiteStatus(int $organizationId): ResponseInterface
    {
        return $this->sendCommand('/otadmin/site/status', ['organization-id' => $organizationId]);
    }

    /**
     * Returns the given organization's website status
     * @throws TransportExceptionInterface
     */
    public function addRedirection(string $fromDomain, string $toDomain): ResponseInterface
    {
        return $this->sendCommand(
            '/otadmin/redirect/add',
            ['from-domain' => $fromDomain, 'to-domain' => $toDomain]
        );
    }
}
