<?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\ViisonShippingCommon\Subscriber;

use Doctrine\Common\Collections\ArrayCollection;
use Enlight_View_Default;
use Shopware\Models\Shop\Shop;
use Shopware\Plugins\ViisonCommon\Classes\ExceptionHandling\SubscriberExceptionHandling;
use Shopware\Plugins\ViisonCommon\Classes\Subscribers\Base;
use Shopware\Plugins\ViisonShippingCommon\Classes\ShippingProvider;

class CheckoutSubscriber extends Base
{
    use SubscriberExceptionHandling;

    const EVENT_COLLECT_SHIPPING_PROVIDERS = 'Shopware_Plugins_ViisonShippingCommon_CollectShippingProviders';
    const GDPR_CHECKBOX_PARAM_NAME = 'viisonTransferCustomerContactDataAllowed';

    /**
     * @inheritdoc
     */
    public static function getSubscribedEvents()
    {
        return [
            'Shopware_Controllers_Frontend_Checkout::confirmAction::after' => 'onAfterConfirmAction',
            'Shopware_Controllers_Frontend_Checkout::finishAction::after' => 'onAfterFinishAction',
            'Shopware_Controllers_Frontend_Checkout::paymentAction::after' => 'onAfterPaymentAction',
        ];
    }

    /**
     * Add the allow customer contact data transfer checkbox.
     *
     * @param \Enlight_Hook_HookArgs $args
     */
    public function onAfterConfirmAction(\Enlight_Hook_HookArgs $args)
    {
        try {
            /** @var Enlight_View_Default $view */
            $view = $args->getSubject()->View();
            $dispatchId = $view->getAssign()['sDispatch']['id'];

            if ($this->showGdprCheckbox($dispatchId, $this->get('shop'))) {
                $view->extendsTemplate('frontend/viison_shippingcommon_checkout/gdpr_checkbox.tpl');
            }
        } catch (\Exception $e) {
            $this->handleException($e, $args);
        }
    }

    /**
     * Decides whether to show the frontend GDPR checkbox.
     *
     * Based on if the adapter configuration of the matching
     * dispatch method provider is configured to show it.
     *
     * @param int $dispatchId
     * @param Shop $shop
     * @return bool
     */
    private function showGdprCheckbox($dispatchId, Shop $shop)
    {
        $showGdprCheckbox = false;

        $providers = $this->getContainer()->get('events')->collect(
            static::EVENT_COLLECT_SHIPPING_PROVIDERS,
            new ArrayCollection()
        )->toArray();
        foreach ($providers as $provider) {
            if (!($provider instanceof ShippingProvider)) {
                continue;
            }
            $productMapping = $provider->getUtil()->findProductMapping($dispatchId);
            if ($productMapping === null || $productMapping['productId'] == 0) {
                continue;
            }
            $adapterGdprMailConfig = $provider->getGdprMailConfiguration($shop);
            if ($adapterGdprMailConfig === null) {
                continue;
            }
            if ($adapterGdprMailConfig === ShippingProvider::GDPR_CUSTOMER_CHOICE) {
                $showGdprCheckbox = true;
            }
            break;
        }

        return $showGdprCheckbox;
    }

    /**
     * Add the allow customer contact data transfer checkbox value to the order attributes.
     *
     * @param \Enlight_Hook_HookArgs $args
     */
    public function onAfterFinishAction(\Enlight_Hook_HookArgs $args)
    {
        try {
            $session = $this->get('session');
            $subject = $args->getSubject();

            $dataTransferAllowed = $subject->Request()->getParam(self::GDPR_CHECKBOX_PARAM_NAME) || $session[self::GDPR_CHECKBOX_PARAM_NAME];
            unset($session[self::GDPR_CHECKBOX_PARAM_NAME]);

            $view = $subject->View();
            $assign = $view->getAssign();
            $entityManager = $this->get('models');
            $order = $entityManager->getRepository(
                'Shopware\Models\Order\Order'
            )->findOneBy(array(
                'number' => $assign['sOrderNumber'],
            ));
            if (!$order) {
                return;
            }

            $orderAttributes = $order->getAttribute();
            if ($orderAttributes !== null) {
                $orderAttributes->setViisonTransferCustomerContactDataAllowed($dataTransferAllowed);
                $entityManager->flush($orderAttributes);
            }
        } catch (\Exception $e) {
            $this->handleException($e, $args);
        }
    }

    /**
     * Save the value of the DSGVO checkbox to the session when using an external payment provider.
     *
     * @param \Enlight_Hook_HookArgs $args
     */
    public function onAfterPaymentAction(\Enlight_Hook_HookArgs $args)
    {
        try {
            $subject = $args->getSubject();
            $session = $this->get('session');
            $session[self::GDPR_CHECKBOX_PARAM_NAME] = boolval($subject->Request()->getParam(self::GDPR_CHECKBOX_PARAM_NAME));
        } catch (\Exception $e) {
            $this->handleException($e, $args);
        }
    }
}
