<?php

namespace FiloBlu\Esb\Model\Consumer;

use FiloBlu\Esb\Model\Consumer\SendObjectToEndpointConsumer;
use FiloBlu\Esb\Api\Data\MessageInterface;
use FiloBlu\Esb\Api\Data\MessageInterfaceFactory;
use FiloBlu\Esb\Api\Data\ObjectTypeDescriptorInterface;
use FiloBlu\Esb\Api\Data\StatusInterface;
use FiloBlu\Esb\Api\Data\StatusInterfaceFactory;
use FiloBlu\Esb\Converter\ConverterResolverInterface;
use FiloBlu\Esb\Core\Exception\NonRecoverableException;
use FiloBlu\Esb\Core\Expression\EvaluatorInterfaceFactory;
use FiloBlu\Esb\Core\Expression\SwitchExpressionEvaluatorFactory;
use FiloBlu\Esb\Core\Extractor\ObjectTypeFromMessage;
use FiloBlu\Esb\Framework\Template\TemplateInterfaceFactory;
use Magento\Framework\DataObjectFactory;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\HTTP\ZendClientFactory;
use Psr\Log\LoggerInterface;

/**
 * Class SendOrderToEndpointConsumer
 * @package FiloBlu\Esb\Model\Consumer
 */
class SendCustomerToEndpointConsumer extends SendObjectToEndpointConsumer
{
    /**
     * SendOrderToEndpointConsumer constructor.
     * @param ZendClientFactory $httpClientFactory
     * @param EvaluatorInterfaceFactory $evaluatorFactory
     * @param SwitchExpressionEvaluatorFactory $switchEvaluatorFactory
     * @param ObjectTypeDescriptorInterface $objectTypeDescriptor
     * @param MessageInterfaceFactory $messageFactory
     * @param ObjectTypeFromMessage $objectTypeFromMessage
     * @param ConverterResolverInterface $converterResolver
     * @param StatusInterfaceFactory $statusFactory
     * @param TemplateInterfaceFactory $templateFactory
     * @param DataObjectFactory $dataObjectFactory
     * @param LoggerInterface $logger
     */
    public function __construct(
        ZendClientFactory $httpClientFactory,
        EvaluatorInterfaceFactory $evaluatorFactory,
        SwitchExpressionEvaluatorFactory $switchEvaluatorFactory,
        ObjectTypeDescriptorInterface $objectTypeDescriptor,
        MessageInterfaceFactory $messageFactory,
        ObjectTypeFromMessage $objectTypeFromMessage,
        ConverterResolverInterface $converterResolver,
        StatusInterfaceFactory $statusFactory,
        TemplateInterfaceFactory $templateFactory,
        DataObjectFactory $dataObjectFactory,
        LoggerInterface $logger
    )
    {
        parent::__construct(
            $httpClientFactory,
            $evaluatorFactory,
            $switchEvaluatorFactory,
            $objectTypeDescriptor,
            $messageFactory,
            $objectTypeFromMessage,
            $converterResolver,
            $statusFactory,
            $templateFactory,
            $dataObjectFactory,
            $logger
        );
    }

    /**
     * @param MessageInterface $message
     * @return MessageInterface
     * @throws NoSuchEntityException
     * @throws NonRecoverableException
     */
    public function consume(MessageInterface $message): MessageInterface
    {
        $customer = $this->loadObject($message);

        if (!$this->checkConditions($customer, $message)) {
            $this->getStatus()
                ->setCode(StatusInterface::SKIPPED)
                ->setOutputData('Required data missed');
            return $message;
        }

        $outputMessage = parent::consume($message);

        if ($this->getStatus()->getCode() !== StatusInterface::SUCCESS) {
            return $outputMessage;
        }

        $this->performAction($customer, $message);
        return $outputMessage;
    }

    /**
     * @inheritDoc
     */
    public function getName(): string
    {
        return 'Send Customer to E.P.';
    }

    /**
     * @inheritDoc
     */
    public function getUniqueName(): string
    {
        return 'FiloBlu_Esb::send_customer_to_endpoint';
    }

    /**
     * @param $message
     * @throws NonRecoverableException
     * @throws NoSuchEntityException
     */
    protected function performAction($customer, $message)
    {
        $parameters = $this->getConfiguration()->getParameters();

        $action = $parameters->getData('on_success_action');

        if ($action === null) {
            return;
        }

        $payload = $message->getPayload();
        $payload->setData('object_type','customer');
        $payload->setData('object_id',$customer->getId());
        $message->setPayload($payload);
        $object = $this->loadObject($message);
        $argument = $action['parameters'];

        switch ($action['action']) {
            case 'change_group_id':
                if((int)$argument > 0) {
                    $object->setData('group_id', $argument);
                }
                break;
            default:
                return;
        }

        $this->saveObject($object);
    }

    protected function checkConditions($object, $message)
    {
        // TODO implement message data validation

        return true;
    }
}
