<?php
/**
 * @author Amasty Team
 * @copyright Copyright (c) Amasty (https://www.amasty.com)
 * @package Free Gift Base for Magento 2
 */

namespace Amasty\Promo\Helper;

use Magento\Framework\App\Area;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\State;

/**
 * Promo Messages for customer
 */
class Messages extends \Magento\Framework\App\Helper\AbstractHelper
{
    /**
     * @var \Magento\Framework\Message\ManagerInterface
     */
    protected $messageManager;

    /**
     * @var \Magento\Checkout\Model\Session
     */
    protected $_checkoutSession;

    /**
     * @var State
     */
    private $appState;

    public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Checkout\Model\Session $resourceSession,
        \Magento\Framework\Message\ManagerInterface $messageManager,
        ?State $appState = null // TODO move to not optional
    ) {
        parent::__construct($context);

        $this->_checkoutSession = $resourceSession;
        $this->messageManager = $messageManager;
        $this->appState = $appState ?? ObjectManager::getInstance()->get(State::class);
    }

    public function addAvailabilityError($product)
    {
        if ($this->appState->getAreaCode() === Area::AREA_GRAPHQL) {
            return;
        }
        $this->showMessage(
            __(
                "We apologize, but your free gift <strong>%1</strong> is not available at the moment",
                $product->getName()
            )
        );
    }

    /**
     * @param string|\Magento\Framework\Phrase $message
     * @param bool $isError
     * @param bool $showEachTime
     * @param bool $isSuccess
     */
    public function showMessage($message, $isError = true, $showEachTime = false, $isSuccess = false)
    {
        if ($this->appState->getAreaCode() === Area::AREA_GRAPHQL) {
            return;
        }
        $displayErrors = $this->scopeConfig->isSetFlag(
            'ampromo/messages/display_error_messages',
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
        );

        if (!$displayErrors && $isError) {
            return;
        }

        $displaySuccess = $this->scopeConfig->isSetFlag(
            'ampromo/messages/display_success_messages',
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
        );

        if (!$displaySuccess && !$isError) {
            return;
        }

        $all = $this->messageManager->getMessages(false);

        foreach ($all as $existingMessage) {
            if ($message == $existingMessage->getText()) {
                return;
            }
        }

        if ($isError && $this->_request->getParam('debug')) {
            $this->messageManager->addComplexErrorMessage(
                'amastyPromoMessagesInfo',
                ['text' => is_string($message) ? $message : $message->render()]
            );
        } elseif ($showEachTime || !$this->isMessageWasShown($message)) {
            if ($isSuccess) {
                $this->messageManager->addComplexSuccessMessage(
                    'amastyPromoMessagesInfo',
                    ['text' => is_string($message) ? $message : $message->render()]
                );
            } else {
                $this->messageManager->addComplexNoticeMessage(
                    'amastyPromoMessagesInfo',
                    ['text' => is_string($message) ? $message : $message->render()]
                );
            }
        }
    }

    /**
     * @param string|\Magento\Framework\Phrase $message
     *
     * @return bool
     */
    private function isMessageWasShown($message)
    {
        if ($message instanceof \Magento\Framework\Phrase) {
            $messageText = $message->render();
        } else {
            $messageText = $message;
        }
        $arr = $this->_checkoutSession->getAmpromoMessages();
        if (!is_array($arr)) {
            $arr = [];
        }
        if (!in_array($messageText, $arr)) {
            $arr[] = $messageText;
            $this->_checkoutSession->setAmpromoMessages($arr);

            return false;
        }

        return true;
    }
}
