<?php
/**
 * Copyright © 2018 EaDesign by Eco Active S.R.L. All rights reserved.
 * See LICENSE for license details.
 */

namespace Eadesigndev\Awb\Controller\Adminhtml\Index;

use Eadesigndev\Urgent\Model\GenerateAwb as GenerateAwbUrgent;
use Eadesigndev\FanCourier\Model\GenerateAwb as GenerateAwbFan;
use Eadesigndev\DPD\Model\GenerateAwb as GenerateAwbDPD;
use Eadesigndev\GLS\Model\GenerateAwb as GenerateAwbGLS;
use Eadesigndev\DragonStar\Model\GenerateAwb as GenerateAwbDragonStar;
use Eadesigndev\NemoExpress\Model\GenerateAwb as GenerateAwbNemoExpress;
use Eadesigndev\Sameday\Model\GenerateAwb as GenerateAwbSameday;
use Eadesigndev\Awb\Model\Awb;
use Eadesigndev\Awb\Model\AwbRepository;
use Eadesigndev\Awb\Model\AwbFactory;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Backend\Model\View\Result\Redirect;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\Exception\LocalizedException;
use Eadesigndev\Awb\Model\Sources\CarrierType;
use Leadlion\AutogedalOrderFlow\Helper\Data as OrderFlowData;

#[\AllowDynamicProperties]
class Save extends Action
{
    const AWB_NUMBER_FIELD = "awb_number";
    const PICKUP_NAME_FIELD = "pickup_name";
    const PICKUP_ID_FIELD = "pickup_id";
    const CARRIER_ID_FIELD = "carrier_id";
    const CARRIER_NAME_FIELD = "carrier_name";

    private $dataPersistor;

    private $awbRepository;

    private $awbFactory;

    public $generateAwb;
    public $generateAwbUrgent;
    public $generateAwbFanCourier;
    public $generateAwbDPD;

    public $_objectManager;
    public $orderRepository;
	protected $helper;
    protected $orderFlowHelper;

    public function __construct(
        Context $context,
        DataPersistorInterface $dataPersistor,
        AwbRepository $awbRepository,
        AwbFactory $awbFactory,
        GenerateAwbUrgent $generateAwbUrgent,
        GenerateAwbFan $generateAwbFanCourier,
        GenerateAwbDPD $generateAwbDPD,
        GenerateAwbGLS $generateAwbGLS,
        GenerateAwbDragonStar $generateAwbDragonStar,
        GenerateAwbNemoExpress $generateAwbNemoExpress,
        GenerateAwbSameday $generateAwbSameday,
		\Leadlion\Web2Sms\Helper\Data $helper,
        OrderFlowData $orderFlowHelper
    ) {
        $this->dataPersistor = $dataPersistor;
        $this->awbRepository = $awbRepository;
        $this->awbFactory    = $awbFactory;
        $this->generateAwbUrgent   = $generateAwbUrgent;
        $this->generateAwbFanCourier   = $generateAwbFanCourier;
        $this->generateAwbDPD   = $generateAwbDPD;
        $this->generateAwbGLS   = $generateAwbGLS;
        $this->generateAwbDragonStar = $generateAwbDragonStar;
        $this->generateAwbNemoExpress = $generateAwbNemoExpress;
        $this->generateAwbSameday = $generateAwbSameday;

        $this->_objectManager = $context->getObjectManager();
        $this->orderRepository = $this->_objectManager->create('Magento\Sales\Api\OrderRepositoryInterface');
		
		$this->helper = $helper;
		$this->orderFlowHelper = $orderFlowHelper;

        parent::__construct($context);
    }

    /**
     * Save action
     *
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @return ResultInterface
     */
    public function execute()
    {
        $data = $this->getRequest()->getPostValue();
        /** @var Redirect $resultRedirect */
        $resultRedirect = $this->resultRedirectFactory->create();
        $orderItems = '';
        if ($data) {
            $id = $this->getRequest()->getParam('entity_id');

            $orderId = $this->getRequest()->getParam('order_id');
            if($data["carrier_id"] == CarrierType::DRAGON_STAR) {
                $orderObject = $this->orderRepository->get($orderId);
                $orderItems = $this->orderFlowHelper->getOrderItems($orderObject);
            }
            
            if ($id) {
                /** @var Awb $model */
                $model = $this->awbRepository->getById($id);
            } else {
                unset($data['entity_id']);
                /** @var Awb $model */
                $model = $this->awbFactory->create();
                $data['comments'] = $orderItems. ' - ' .$data["comments"];
            }
            $model->setData($data);
            $model->setData('update_time', time());

            try {
                $this->awbRepository->save($model);
                $this->dataPersistor->clear('awb_data');

                if (!$this->getRequest()->getParam('back')) {
                    $id = $model->getEntityId();
                    switch ($data["carrier_id"])
                    {
                        case CarrierType::URGENT_CURRIER:
                            $this->generateAwb = $this->generateAwbUrgent;
                            $currentCarrierPickupPointsRepository = $this->_objectManager->create('Eadesigndev\Urgent\Model\Sources\PickupId')->getAvailable();
                            break;
                        case CarrierType::FAN_CURRIER:
                            $this->generateAwb = $this->generateAwbFanCourier;
                            $currentCarrierPickupPointsRepository = $this->_objectManager->create('Eadesigndev\FanCourier\Model\Sources\PickupId')->getAvailable();
                            break;
                        case CarrierType::DPD:
                            $this->generateAwb = $this->generateAwbDPD;
                            $currentCarrierPickupPointsRepository = $this->_objectManager->create('Eadesigndev\DPD\Model\Sources\PickupId')->getAvailable();
                            break;
                        case CarrierType::GLS:
                            $this->generateAwb = $this->generateAwbGLS;
                            $currentCarrierPickupPointsRepository = $this->_objectManager->create('Eadesigndev\GLS\Model\Sources\PickupId')->getAvailable();
                            break;
                        case CarrierType::DRAGON_STAR:
                            $this->generateAwb = $this->generateAwbDragonStar;
                            $currentCarrierPickupPointsRepository = $this->_objectManager->create('Eadesigndev\DragonStar\Model\Sources\PickupId')->getAvailable();
                            break;
                        case CarrierType::NEMO_EXPRESS:
                            $this->generateAwb = $this->generateAwbNemoExpress;
                            $currentCarrierPickupPointsRepository = $this->_objectManager->create('Eadesigndev\NemoExpress\Model\Sources\PickupId')->getAvailable();
                            break;
                        case CarrierType::SAMEDAY:
                            $this->generateAwb = $this->generateAwbSameday;
                            $currentCarrierPickupPointsRepository = $this->_objectManager->create('Eadesigndev\Sameday\Model\Sources\PickupId')->getAvailable();
                            break;
                    }

                    $availableCarriers = $this->_objectManager->create('Eadesigndev\Awb\Model\Sources\CarrierType')->getAvailable();

                    $this->generateAwb->setGenerateAwb($id);
                    $awbNumber = $this->generateAwb->generateAwb($id);

                    if (!empty($awbNumber)) {
                        $model->setData('awb_number', $awbNumber);

                        $this->messageManager->addSuccessMessage(__('You awb ' . var_export($awbNumber, true) . ' number is generated.'));

                        $model->setData('status', 1);
                        $this->awbRepository->save($model);

                        if (!empty($model->getOrderId())) {
							$autogedalCarrierText = $availableCarriers[$data["carrier_id"]]->getText() ?? "";
							$this->helper->callAfterShipmentSaveByGenerateAwb($model->getOrderId(), $awbNumber, $autogedalCarrierText, $autogedalCarrierText);
                            $orderObject = $this->saveOrderExtraData($model->getOrderId(), [
                                self::AWB_NUMBER_FIELD => $awbNumber,
                                self::PICKUP_ID_FIELD => $data["awb_pickup_id"],
                                self::CARRIER_ID_FIELD => $data["carrier_id"],
                                self::CARRIER_NAME_FIELD => $availableCarriers[$data["carrier_id"]]->getText() ?? "",
                                self::PICKUP_NAME_FIELD => $currentCarrierPickupPointsRepository[$data["awb_pickup_id"]] ?? ""
                            ]);

                            //Dispatch an event so you can change order status later
                            $this->_eventManager->dispatch('order_awb_generated', ['obj' => $orderObject]);
                        }
                    } else {
                        $this->messageManager->addErrorMessage(__('You awb was not generated.'));
                    }

                    return $resultRedirect->setPath('*/*/index', ['entity_id' => $model->getId(), '_current' => true]);
                }
                return $resultRedirect->setPath('*/*/');
            } catch (LocalizedException $e) {
                $this->messageManager->addErrorMessage($e->getMessage());
            } catch (\Exception $e) {
                $this->messageManager->addExceptionMessage(
                    $e,
                    __('Something went wrong while aprove the awb.') . ':' . $e->getMessage()
                );
            }

            $this->dataPersistor->set('awb_data', $data);
            return $resultRedirect->setPath('*/*/edit', ['entity_id' => $id]);
        }
        return $resultRedirect->setPath('*/*/');
    }

    /**
     * Check the permission to run it
     *
     * @return boolean
     */
    //@codingStandardsIgnoreLine
    protected  function _isAllowed()
    {
        return $this->_authorization->isAllowed(Index::ADMIN_RESOURCE);
    }

    protected function saveOrderExtraData($orderId, $extraData = [])
    {
        if (empty($extraData)) {
            return false;
        }

        $orderObject = $this->orderRepository->get($orderId);
        foreach ($extraData as $dataName => $dataValue) {
            $orderObject->setData($dataName, $dataValue);
        }

        $orderObject->save();

        return $orderObject;
    }
}
