<?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\Modules;

use Shopware\Plugins\ViisonCommon\Classes\Subscribers\Base;
use Shopware\Plugins\ViisonSetArticles\Components\PluginConfigService;

/**
 * This Subscriber manipulates confirmation mail content
 */
class MailSubscriber extends Base
{
    /**
     * @inheritdoc
     */
    public static function getSubscribedEvents()
    {
        return [
            'Shopware_Modules_Order_SendMail_FilterVariables' => 'onFilterMailVariables',
        ];
    }

    /**
     * This event is fired by sOrder before the order-confirmation-mail is sent. This hook does two things:
     *
     * 1) removes sub articles from the content (if config is set) to hide sub articles in the email. No modification of
     * the email template is needed.
     *
     * 2) manipulates some set article availability properties (shippingtime, instock,..) since the mail variables are
     * taken directly from the basket content, which is not modified int he frontend.
     *
     * @param \Enlight_Event_EventArgs $args
     * @return mixed
     */
    public function onFilterMailVariables(\Enlight_Event_EventArgs $args)
    {
        $mailVariables = $args->getReturn();
        $newOrderDetails = [];
        /** @var PluginConfigService $pluginConfigService */
        $pluginConfigService = $this->get('viison_set_articles.plugin_config');
        $hideSubArticles = $pluginConfigService->getDisplaySubArticlesOnDocuments() !== PluginConfigService::ALWAYS_SHOW_SUB_ARTICLES_ON_DOCUMENTS;

        foreach ($mailVariables['sOrderDetails'] as $article) {
            $isSubArticle = isset($article['viisonSetArticleSetArticleOrderNumber']) && ($article['viisonSetArticleSetArticleOrderNumber'] !== $article['ordernumber']);
            if ($hideSubArticles && $isSubArticle) {
                // Ignore this sub article by not adding it to the result list
                continue;
            }

            /**
             * Remark: If necessary information (e.g. orderDetailId) is missing, this Event is probably thrown in an
             * unknown context (e.g. "Resend OrderConfirmation Plugin"). Just pass along the article information without
             * any manipulation in that case.
             */
            if (!is_array($article) || !array_key_exists('orderDetailId', $article) || !$article['orderDetailId']) {
                $newOrderDetails[] = $article;
                continue;
            }

            // Remark: attributes are persisted in the DB but are missing in this order detail array. Load manually
            $orderDetail = $this->get('models')->find('Shopware\\Models\\Order\\Detail', $article['orderDetailId']);
            if ($orderDetail &&
                $orderDetail->getAttribute() &&
                $orderDetail->getAttribute()->getViisonSetarticleOrderid() === intval($article['orderDetailId'])
            ) {
                // Manipulate set article availability information, overwrite fields in article array
                $availabilityInformation = $this->get('models')
                    ->getRepository('Shopware\\CustomModels\\ViisonSetArticles\\SetArticle')
                    ->getCombinedSetArticleDetailsData($article['articleDetailId'], $article['quantity']);
                // Since the currently loaded availablity (instock) is already reduced by this exact order, we need to
                // increase the instock again to restore the pre-order availabilty that should be displayed in the
                // status mail.
                $availabilityInformation['instock'] += $article['quantity'];

                $article = array_replace($article, $availabilityInformation);
            }

            // Add article to result list
            $newOrderDetails[] = $article;
        }
        $mailVariables['sOrderDetails'] = $newOrderDetails;

        return $mailVariables;
    }
}
