<?php

namespace FiloBlu\Esb\Controller\Adminhtml\Producer;

use Exception;
use FiloBlu\Esb\Api\Data\ProducerConfigurationInterface;
use FiloBlu\Esb\Api\Data\ProducerConfigurationInterfaceFactory;
use FiloBlu\Esb\Api\ProducerConfigurationRepositoryInterface;
use FiloBlu\Esb\Api\ProducerResolverInterface;
use FiloBlu\Esb\Api\RetryStrategyResolverInterface;
use FiloBlu\Esb\Controller\Adminhtml\Common\AbstractEdit;
use FiloBlu\Esb\Converter\JsonToDataObject;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\View\Result\PageFactory;

/**
 * Class Edit
 * @package FiloBlu\Esb\Controller\Adminhtml\Producer
 */
class Edit extends AbstractEdit
{
    /**
     * @var PageFactory
     */
    protected $resultPageFactory;
    /**
     * @var ProducerConfigurationInterfaceFactory
     */
    private $producerConfigurationFactory;
    /**
     * @var ProducerConfigurationRepositoryInterface
     */
    private $producerConfigurationRepository;
    /**
     * @var JsonToDataObject
     */
    private $jsonToDataObject;
    /**
     * @var RetryStrategyResolverInterface
     */
    private $strategyResolver;
    /**
     * @var ProducerResolverInterface
     */
    private $producerResolver;

    /**
     * Constructor
     *
     * @param Context $context
     * @param JsonToDataObject $jsonToDataObject
     * @param PageFactory $resultPageFactory
     * @param ProducerConfigurationInterfaceFactory $producerConfigurationFactory
     * @param ProducerConfigurationRepositoryInterface $producerConsumerConfigurationInterfaceRepository
     * @param ProducerResolverInterface $producerResolver
     * @param RetryStrategyResolverInterface $strategyResolver
     */
    public function __construct(
        Context $context,
        JsonToDataObject $jsonToDataObject,
        PageFactory $resultPageFactory,
        ProducerConfigurationInterfaceFactory $producerConfigurationFactory,
        ProducerConfigurationRepositoryInterface $producerConsumerConfigurationInterfaceRepository,
        ProducerResolverInterface  $producerResolver,
        RetryStrategyResolverInterface $strategyResolver
    ) {
        parent::__construct($context);
        $this->resultPageFactory = $resultPageFactory;
        $this->producerConfigurationFactory = $producerConfigurationFactory;
        $this->producerConfigurationRepository = $producerConsumerConfigurationInterfaceRepository;
        $this->jsonToDataObject = $jsonToDataObject;
        $this->strategyResolver = $strategyResolver;
        $this->producerResolver = $producerResolver;
    }

    /**
     * Execute view action
     *
     * @return ResultInterface
     */
    public function execute()
    {
        $general = $this->getRequest()->getParam('general');
        $producer = isset($general['producer']) ? $general['producer'] : null;

        if ($producer !== null) {
            $id = $producer[ProducerConfigurationInterface::ID] ?? null;

            try {
                $strategy = $producer[ProducerConfigurationInterface::RETRY_STRATEGY];
                $parameters = $producer[ProducerConfigurationInterface::PARAMETERS];

                /** @var  ProducerConfigurationInterface $producerObject */
                $producerObject = $this->producerConfigurationFactory->create();

                $producerObject
                    ->setPriority($producer[ProducerConfigurationInterface::PRIORITY])
                    ->setOutputEvent($producer[ProducerConfigurationInterface::OUTPUT_EVENT])
                    ->setProducer($this->producerResolver->get($producer[ProducerConfigurationInterface::PRODUCER]))
                    ->setLabel($producer[ProducerConfigurationInterface::LABEL])
                    ->setId($id)
                    ->setUuid($producer[ProducerConfigurationInterface::UUID]);

                if ($strategy) {
                    $producerObject->setRetryStrategy($this->strategyResolver->get($strategy));
                }

                if ($producer[ProducerConfigurationInterface::ENABLE]) {
                    $producerObject->enable();
                } else {
                    $producerObject->disable();
                }

                $producerObject->setParameters($this->jsonToDataObject->convert($parameters));
                $this->producerConfigurationRepository->save($producerObject);
                $id = $producerObject->getId();

                $this->messageManager->addSuccessMessage('Save success');
            } catch (Exception $exception) {
                $this->messageManager->addExceptionMessage($exception);
            }

            return $this->getRedirectPath($id);
        }
        return $this->resultPageFactory->create();
    }
}
