<?php

namespace FiloBlu\Esb\Model\Producer;

use FiloBlu\Esb\Api\Data\MessageInterface;
use FiloBlu\Esb\Api\Data\StatusInterface;
use FiloBlu\Esb\Core\Extractor\ObjectTypeFromMessage;
use Magento\Framework\DataObject;
use Magento\Catalog\Model\Product;

/**
 * Class StockStatusSaveAfterProducer
 * @package FiloBlu\Esb\Model\Producer
 */
class StockStatusSaveAfterProducer extends AbstractProductProducer
{

    /**
     * @inheritDoc
     */
    public function produce(Product $product = null): MessageInterface
    {
        /** @var MessageInterface $message */
        $message = $this->getMessageFactory()->create();

        if ($product === null || !$this->isConditionSatisfied($this->prepareDataForEvaluation($product))) {
            $this->getStatus()->setCode(StatusInterface::SKIPPED)->setOutputData(
                    $product === null ? 'Product was null' : 'Condition was not satisfied'
                );
            return $message;
        }

        $parameters = $this->getConfiguration()->getParameters();

        if ($product !== null && $parameters->hasData(self::PAYLOAD_KEY)) {
            $template = $parameters->getData(self::PAYLOAD_KEY);
            $this->messageFiller->fill($message, $this->getDataForFiller($product), $template);
        }

        $message->getPayload()->addData([
            ObjectTypeFromMessage::OBJECT_TYPE_PATH => $this->getObjectTypeDescriptor()->getTypeCode(),
            ObjectTypeFromMessage::OBJECT_ID_PATH => $product->getEntityId()
        ]);

        if (array_key_exists('sku', $message->getPayload()->getDataByPath('origData')) && array_key_exists('quantity_and_stock_status', $message->getPayload()->getDataByPath('origData'))
        && array_key_exists('store_id', $message->getPayload()->getDataByPath('origData'))) {
            $newPayloadData['sku'] = $message->getPayload()->getDataByPath('origData')['sku'];
            $newPayloadData['quantity_and_stock_status'] = $message->getPayload()->getDataByPath('origData')['quantity_and_stock_status'];
            $newPayloadData['store_id'] = $message->getPayload()->getDataByPath('origData')['store_id'];
        }
        $message->getPayload()->setData('origData',$newPayloadData);
        $this->getStatus()->setCode(StatusInterface::SUCCESS);

        return $message;
    }

    /**
     * @param Product $product
     * @return DataObject
     */
    protected function prepareDataForEvaluation(Product $product = null): DataObject
    {
        /** @var DataObject $dataToEvaluate */
        $dataToEvaluate = $this->dataObjectFactory->create();

        if ($product === null) {
            return $dataToEvaluate;
        }

        $dataToEvaluate->setData('data', $product->getData());
        $dataToEvaluate->setData('origdata', $product->getOrigData() ?: $this->dataObjectFactory->create());
        return $dataToEvaluate;
    }

    /**
     * @param Product $product
     * @return mixed
     */
    protected function getDataForFiller(Product $product)
    {
        return $this->dataObjectFactory->create(
            [
                'data' => [
                    'data' => $product->getData(),
                    'origdata' => $product->getOrigData() ?: $this->dataObjectFactory->create()
                ]
            ]
        );
    }

    /**
     * @inheritDoc
     */
    public function getName(): string
    {
        return 'Stock Status Save After Producer';
    }

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