<?php
// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

namespace Shopware\Plugins\ViisonSetArticles\Subscribers\Frontend;

use Shopware\Plugins\ViisonCommon\Classes\Subscribers\FrontendArticleCartEnabler as ViisonCommonFrontendArticleCartEnabler;
use Shopware\Plugins\ViisonSetArticles\Util;

/**
 * This Subscriber extends the FrontendArticleCartEnabler in a sense that set articles need more manipulations than
 * DropShipping articles.
 *
 * This Subscriber subscribes additional events and manipulates availability information in multiple places.
 */
class FrontendArticleCartEnablerSubscriber extends ViisonCommonFrontendArticleCartEnabler
{
    /**
     * @inheritdoc
     */
    public static function getSubscribedEvents()
    {
        $parentSubscriptions = parent::getSubscribedEvents();

        return array_merge($parentSubscriptions, [
            'Shopware_Components_AboCommerceBasket::addArticle::before' => 'onBeforeAddArticle',
            'Shopware_Components_AboCommerceBasket::addArticle::after' => 'onAfterAddArticle',
            'Shopware_Controllers_Frontend_Checkout::getBasket::after' => [
                // Execution "around" the AboCommerce after hook
                [
                    'getBasketDisableLastStock',
                    -999,
                ],
                [
                    'getBasketEnableLastStock',
                    999,
                ],
            ],
        ]);
    }

    /**
     * @inheritdoc
     */
    public function doAvailabilityCheck($orderNumber)
    {
        return Util::isSetArticleByOrdernumber($orderNumber);
    }

    /**
     * Shopwares AboCommerce plugin adds some additional availability checks in the checkout/confirm view. To bypass
     * these checks we have to add hooks "around" the after-hook of AboCommerce, that disables the lastStock flag of
     * set articles. This way set articles are not flagged as "not available" and no information in the view is missing.
     *
     * @param \Enlight_Hook_HookArgs $args
     */
    public function getBasketDisableLastStock(\Enlight_Hook_HookArgs $args)
    {
        $basket = $args->getReturn();
        foreach ($basket['content'] as $article) {
            $this->disableLastStockIfNecessary($article['ordernumber']);
        }
    }

    /**
     * See getBasketDisableLastStock(). Turns lastStock back on.
     *
     * @param \Enlight_Hook_HookArgs $args
     */
    public function getBasketEnableLastStock(\Enlight_Hook_HookArgs $args)
    {
        $basket = $args->getReturn();
        foreach ($basket['content'] as $article) {
            $this->enableLastStockIfNecessary($article['ordernumber']);
        }
    }

    /**
     * This event is used "around" multiple functions to bypass availability checks of a single article in the frontend
     * (e.g. AboCommerce addArticle, Shopware getInstock). We temporarily set lastStock to false. This way set articles
     * are not flagged as "not available".
     *
     * @param \Enlight_Hook_HookArgs $args
     */
    public function onBeforeAddArticle(\Enlight_Hook_HookArgs $args)
    {
        $this->disableLastStockIfNecessary($args->get('orderNumber'));
    }

    /**
     * See onBeforeAddArticle(). Turns lastStock back on.
     *
     * @param \Enlight_Hook_HookArgs $args
     */
    public function onAfterAddArticle(\Enlight_Hook_HookArgs $args)
    {
        $this->enableLastStockIfNecessary($args->get('orderNumber'));
    }
}
