<?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.

use Shopware\Models\Order\Order;
use Shopware\Plugins\ViisonCommon\Components\ParameterValidator;
use Shopware\Plugins\ViisonDHL\Classes\CreateShipmentOrderRequest;
use Shopware\Plugins\ViisonDHL\Classes\DhlServiceOptions\PreferredDeliveryServiceOption;
use Shopware\Plugins\ViisonDHL\Classes\NonCodableAddressDHLException;
use Shopware\Plugins\ViisonDHL\Classes\ShippingLabelGenerator;
use Shopware\Plugins\ViisonDHL\Classes\ShippingProvider;
use Shopware\Plugins\ViisonDHL\Classes\ShippingUtil;
use Shopware\Plugins\ViisonDHL\Util;
use Shopware\Plugins\ViisonShippingCommon\Controllers\Backend\ViisonShippingCommonOrder;

/**
 * This controller adds some actions called in the order backend controller.
 * These actions are responsible for creating and deleting shipping labels via DHL
 * as well as returning the pre calculated weight of shipments or multiple shipping labels
 * merged in one PDF file.
 */
class Shopware_Controllers_Backend_ViisonDHLOrder extends ViisonShippingCommonOrder
{

    public function __construct(Enlight_Controller_Request_Request $request = null, Enlight_Controller_Response_Response $response = null)
    {
        $shippingLabelGenerator = new ShippingLabelGenerator();
        $shippingProvider = new ShippingProvider();
        $shippingUtil = new ShippingUtil();
        parent::__construct($request, $response, $shippingProvider, Util::instance(), $shippingLabelGenerator, $shippingUtil);
    }

    /**
     * Returns data fields that are specific to the Shopware DHL integration. This is useful if customers want to use the frontend
     * implementation of the Shopware DHL integration e.g. to support Packstation addresses.
     */
    public function getShopwareDHLIntegrationDataAction()
    {
        $this->View()->success = true;
        // Check request
        $orderId = $this->Request()->getParam('orderId', null);

        $orderModel = Shopware()->Models()->getRepository('Shopware\\Models\\Order\\Order')->findOneBy(['id' => $orderId]);
        $attribute = $orderModel->getAttribute();

        $postNumber = null;
        // Check if the Shopware DHL integration is installed
        if (method_exists($attribute, 'getSwagDhlAddress')) {
            $address = unserialize($attribute->getSwagDhlAddress());
            $postNumber = $address->postNumber;
            if ($postNumber == '') {
                $postNumber = null;
            }
        }

        // Return result
        $data['creationSuccess'] = true;
        $this->View()->data = [
            'postNumber' => $postNumber,
        ];
    }

    /**
     * Returns the default settings for service options according to the configuration
     * of the shop that the order was placed in.
     */
    public function getDefaultServiceOptionsAction()
    {
        $this->View()->success = true;

        // Get order id
        $orderId = $this->Request()->getParam('orderId');
        if (!isset($orderId)) {
            $this->View()->success = false;
            $this->View()->message = 'Missing orderId.';

            return;
        }

        $settings = $this->util->getDispatchMethodLevelSettings($orderId);

        if ($settings === null) {
            $endorsementType = false;
            $parcelOutletRouting = false;
            $minimumAge = null;
            $personalHandover = false;
            $identCheckAge = null;
            $postalDeliveryDutyPaid = false;
            $closestDroppointDelivery = false;
            $signedForByRecipient = false;
        } else {
            $endorsementType = $settings['endorsementType'];
            $parcelOutletRouting = $settings['parcelOutletRouting'];
            $minimumAge = $settings['visualAgeCheck'];
            $personalHandover = $settings['personalHandover'];
            $identCheckAge = $settings['identCheckAge'];
            $postalDeliveryDutyPaid = $settings['postalDeliveryDutyPaid'];
            $closestDroppointDelivery = $settings['closestDroppointDelivery'];
            $signedForByRecipient = $settings['signedForByRecipient'];
        }

        // Default minimum age should be either null if not configured or a positive number
        if ($minimumAge !== null) {
            $minimumAge = intval($minimumAge);
        }

        $this->View()->endorsementType = $endorsementType;
        $this->View()->parcelOutletRouting = (bool) $parcelOutletRouting;
        $this->View()->minimumAge = $minimumAge;
        $this->View()->personalHandover = (bool) $personalHandover;
        $this->View()->identCheckAge = $identCheckAge;
        $this->View()->postalDeliveryDutyPaid = $postalDeliveryDutyPaid;
        $this->View()->closestDroppointDelivery = $closestDroppointDelivery;
        $this->View()->signedForByRecipient = (bool) $signedForByRecipient;
    }

    /* Override */
    protected function getShippingSettings($request)
    {
        $settings = parent::getShippingSettings($request);
        if ($settings === null) {
            return null;
        }
        $settings['minimumage'] = $request->getParam('settingsMinimumAge', null);
        $settings['personalhandover'] = $request->getParam('settingsPersonalHandover', null);
        $settings['issaturdaydelivery'] = $request->getParam('settingsSaturdayDelivery', null);
        $settings['insuredvalue'] = $request->getParam('settingsInsuredValue', null);
        $settings['parceloutletrouting'] = $request->getParam('settingsParcelOutletRouting', null);
        $settings['addresseesCustomsReference'] = $request->getParam('addresseesCustomsReference', null);
        $settings['identCheckAge'] = $request->getParam('settingsIdentCheckAge', null);
        $settings['postalDeliveryDutyPaid'] = $request->getParam('settingsPostalDeliveryDutyPaid', null);
        $settings['closestDroppointDelivery'] = $request->getParam('settingsClosestDroppointDelivery', null);
        $settings['signedForByRecipient'] = $request->getParam('settingsSignedForByRecipient', null);

        return $settings;
    }

    /**
     * {@inheritdoc}
     * This action allows to load all dispatch service provider dependant settings
     * with only one AJAX call. By using this method instead of the individual actions,
     * the loading speed in the backend is improved.
     */
    public function getShippingOrderDataAction()
    {
        parent::getShippingOrderDataAction();
        if ($this->View()->success === false) {
            return;
        }

        try {
            $data = $this->View()->data;
            $data['defaultDayOfDelivery'] = $this->util->getDefaultDayOfDelivery(false);

            $orderId = $this->Request()->getParam('orderId');
            ParameterValidator::assertIsNotNull($orderId, 'orderId');

            /** @var Order $order */
            $order = $this->get('models')->find(Order::class, $orderId);
            ParameterValidator::assertEntityFound($order, Order::class, $orderId, 'orderId');

            $shop = $order->getShop();
            if (!$data['product']['incoterm']) {
                $data['product']['incoterm'] = $this->util->config($shop->getId(), 'exportIncoterm');
            }

            $this->View()->data = $data;
        } catch (\Exception $e) {
            $this->handleException($e);
        }
    }

    /**
     * Return the MOB Packstation data if plugin is installed.
     */
    public function getMOBPackingStationDataAction()
    {
        $this->View()->success = true;

        // Get order id
        $orderId = $this->Request()->getParam('orderId', null);

        if ($orderId === null) {
            $this->View()->data = [
                'creationSuccess' => false,
                'message' => 'No order ID has been send.',
            ];

            return;
        }

        /** @var Shopware\Models\Attribute\Order $orderAttribute */
        $orderAttribute = $this->util->getOrderAttributeIfPackingStationPluginExist($orderId);
        if ($orderAttribute !== null) {
            $result = [
                'id' => $orderAttribute->getId(),
                'preferredLocation' => $orderAttribute->getMoptwunschpaketpreferredlocation(),
                'preferredNeighborName' => $orderAttribute->getMoptwunschpaketpreferredneighborname(),
                'preferredNeighborAddress' => $orderAttribute->getMoptwunschpaketpreferredneighboraddress(),
                'preferredDay' => $orderAttribute->getMoptwunschpaketpreferredday(),
            ];
        } else {
            // The Plugin has not been installed, return null
            $result = null;
        }

        $this->View()->assign([
            'success' => true,
            'data' => $result,
        ]);
    }

    /**
     * @Override
     * @return array Data that can be used inside the Views
     */
    public function getViewParams()
    {
        return array_merge(
            parent::getViewParams(),
            ['dimensionConstraints' => CreateShipmentOrderRequest::getDimensionConstraints()],
            ['errorCodeNonCodeable' => NonCodableAddressDHLException::ERROR_CODE]
        );
    }
}
