<?php

namespace Myvetshop\Module\Clinique\Clinic;

use Myvetshop\Module\Clinique\Api\OvhApiFactory;
use Ovh\Api;

class ClinicEmailRedirectionManager
{
    public const DOMAIN = 'myvetshop.fr';

    protected OvhApiFactory $ovhApiFactory;

    /**
     * @return list<array{from: string, id: string, to: string}>
     *
     * @throws \Exception
     */
    protected function getRedirectionsRaw(Api $ovhApi, string $codePrivilege): array
    {
        $queryParams = \http_build_query(
            ['from' => \strtolower($codePrivilege) . '@' . self::DOMAIN]
        );

        $redirectionIds = $ovhApi->get('/email/domain/' . self::DOMAIN . '/redirection?' . $queryParams);

        if (!\is_array($redirectionIds)) {
            throw new \Exception('Error calling redirection API for ' . $codePrivilege);
        }

        return \array_map(
            fn (string $redirectionId) => $this->getRedirectionRawData($ovhApi, $redirectionId),
            $redirectionIds
        );
    }

    /**
     * @param string $redirectionId
     *
     * @return array{from: string, id: string, to: string}
     */
    protected function getRedirectionRawData(Api $ovhApi, string $redirectionId): array
    {
        /** @var array{from: string, id: string, to: string}|null $ret */
        $ret = $ovhApi->get('/email/domain/' . self::DOMAIN . '/redirection/' . \urlencode($redirectionId));

        if (!\is_array($ret)) {
            throw new \Exception('Error fetching redirection ' . $redirectionId);
        }

        return $ret;
    }

    protected function removeRedirectionRaw(Api $ovhApi, string $redirectionId): void
    {
        $ovhApi->delete('/email/domain/' . self::DOMAIN . '/redirection/' . \urlencode($redirectionId));
    }

    public function __construct(
        OvhApiFactory $ovhApiFactory
    ) {
        $this->ovhApiFactory = $ovhApiFactory;
    }

    /**
     * Get the destination $codePrivilege@myvetshop.fr
     * If multiples destinations are provided by the API, only the first is returned
     *
     * @param string $codePrivilege
     */
    public function getRedirection(string $codePrivilege): ?string
    {
        try {
            $ovhApi = $this->ovhApiFactory->create();
        } catch (\Exception $e) {
            return null;
        }

        $redirections = $this->getRedirectionsRaw($ovhApi, $codePrivilege);

        return $redirections[0]['to'] ?? null;
    }

    public function setRedirection(string $codePrivilege, string $emailTo): void
    {
        try {
            $ovhApi = $this->ovhApiFactory->create();
        } catch (\Exception $e) {
            return;
        }

        $emailTo = \trim(\strtolower($emailTo));

        $actualRedirections = $this->getRedirectionsRaw($ovhApi, $codePrivilege);

        $exists = false;

        // Remove excess redirections
        foreach ($actualRedirections as $redirection) {
            if ($redirection['to'] === $emailTo) {
                $exists = true;
            } else {
                $this->removeRedirectionRaw($ovhApi, $redirection['id']);
            }
        }

        // Create redirection if it does not exists
        if (!$exists) {
            $ovhApi->post(
                '/email/domain/' . self::DOMAIN . '/redirection',
                [
                    'from' => \strtolower($codePrivilege) . '@' . self::DOMAIN,
                    'to' => $emailTo,
                    'localCopy' => false,
                ]
            );
        }
    }
}
