<?php

declare(strict_types=1);

namespace External\HannahBundle\Maileon\Util;

use de\xqueue\maileon\api\client\AbstractMaileonService;
use de\xqueue\maileon\api\client\contacts\Contact;
use de\xqueue\maileon\api\client\contacts\ContactsService;
use de\xqueue\maileon\api\client\contacts\Permission;
use de\xqueue\maileon\api\client\contacts\SynchronizationMode;
use de\xqueue\maileon\api\client\MaileonAPIResult;
use de\xqueue\maileon\api\client\transactions\Transaction;
use de\xqueue\maileon\api\client\transactions\TransactionsService;
use External\HannahBundle\Maileon\Exception\MaileonException;
use External\HannahBundle\Util\Configuration;

class MaileonApi
{
    private $configuration;

    public function __construct(Configuration $configuration)
    {
        $this->configuration = $configuration;
    }

    public function createContact(Contact $contact): MaileonAPIResult
    {
        return $this->getContactsService()
            ->createContact(
                $contact,
                SynchronizationMode::getSynchronizationMode(2)
            );
    }

    public function createTransaction(Transaction $transaction): MaileonAPIResult
    {
        // create contact if not exists
        $result = $this->createContact(
            $this->prepareContact($transaction->contact->email)
        );

        if (!$result->getResult()) {
            throw new MaileonException('Unable to create contact');
        }

        return $this->getTransactionsService()
            ->createTransactions([$transaction]);
    }

    public function getTransactionsService(): TransactionsService
    {
        return $this->getService(TransactionsService::class);
    }

    public function getContactsService(): ContactsService
    {
        return $this->getService(ContactsService::class);
    }

    private function prepareContact(string $email): Contact
    {
        return new Contact(
            null,
            $email,
            Permission::getPermission(5),
        );
    }

    private function getService(string $class): AbstractMaileonService
    {
        static $services = [];

        if (!($services[$class] ?? false)) {
            $services[$class] = new $class([
                'BASE_URI' => 'https://api.maileon.com/1.0/',
                'API_KEY' => $this->configuration->get('maileon')['apiKey'] ?? null,
                'THROW_EXCEPTION' => true,
            ]);
        }

        return $services[$class];
    }
}
