<?php

namespace Twnt4All\Engine;

use Twnt4All\Engine\Contract\ConfigProviderInterface;
use Twnt4All\Engine\Contract\LoggerInterface;
use Twnt4All\Engine\Contract\RestInterface;
use Twnt4All\Engine\Contract\LockInterface;
use Twnt4All\Engine\Service\BaseMailer;
use Twnt4All\Engine\Service\BackofficeTransactionService;
use Twnt4All\Engine\Service\TransactionService;

/**
 * Class TWINT
 * @package Twnt4All\Engine
 */
class TwintCore
{
    const DATAPROVIDER_CLASS = 'Twnt4All\\Engine\\Adapter\\ConfigProvider';
    const EVENTHANDLER_CLASS = 'Twnt4All\\Engine\\Adapter\\DomainEvents';
    const RESTHELPER_CLASS   = 'Twnt4All\\Engine\\Adapter\\RestClient';
    const LOCK_CLASS         = 'Twnt4All\\Support\\WooOrderLock';

    /** @var TransactionService|BackofficeTransactionService */
    public $transactionHandler;

    /** @var ConfigProviderInterface */
    public $dataProvider;

    /** @var BaseMailer */
    public static $mailer = T4A_MAILER_CLASS;

    /** @var LoggerInterface */
    public static $logger = T4A_LOGGER_CLASS;

    /** @var RestInterface */
    public static $rest = T4A_REST_HELPER_CLASS;

    /** @var LockInterface */
    public static $db_lock = T4A_DB_LOCK_CLASS;

    /**
     * TWINT constructor.
     */
    private function __construct()
    {
    }

    public static function create_for_transaction( $order_id, $merchant_id )
    {
        return static::create( $order_id, $merchant_id, TransactionService::class );
    }

    public static function create_for_admin( $order_id, $merchant_id )
    {
        return static::create( $order_id, $merchant_id, BackofficeTransactionService::class );
    }

    /**
     * @param $order_id
     * @param $merchant_id
     * @param $transaction_handler_class
     * @return static|null
     */
    private static function create( $order_id, $merchant_id, $transaction_handler_class )
    {
        $instance = new static();
        $dp_class = static::DATAPROVIDER_CLASS;
        /** @var ConfigProviderInterface $data_provider */
        $data_provider = new $dp_class();
        $data_provider->set_order( $order_id )->set_merchant( $merchant_id );

        $eh_class      = static::EVENTHANDLER_CLASS;
        $event_handler = new $eh_class( $data_provider );

        try {
            $transaction_handler = new $transaction_handler_class( $data_provider, $event_handler );
        } catch ( \Twnt4All\Exception\SoapNotLoadedException $e ) {
            static::$logger::log_error( 'SOAP not loaded.', 'SOAP extension not loaded', $data_provider );
            return null;
        } catch ( \Twnt4All\Exception\TwintCredentialsNotSetException $e ) {
            static::$logger::log_error( 'TWINT credentials not set.', 'All credentials must be set.', $data_provider );
            return null;
        }

        $instance->dataProvider       = $data_provider;
        $instance->transactionHandler = $transaction_handler;
        //$instance->transactionResponseHandler = new TransactionResponseHandler( $data_provider );

        return $instance;

    }

}