<?php

namespace FiloBlu\Storelocator\Controller\Rma\Guest;

use Exception;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\Result\ForwardFactory;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\Registry;
use Magento\Framework\Stdlib\DateTime\DateTime;
use Magento\Framework\View\Result\LayoutFactory;
use Magento\Framework\View\Result\PageFactory;
use Magento\Rma\Controller\Guest;
use Magento\Rma\Helper\Data;
use Magento\Rma\Model\Rma\Source\Status;
use Magento\Rma\Model\Rma\Status\HistoryFactory;
use Magento\Rma\Model\RmaFactory;
use Psr\Log\LoggerInterface;

/**
 *
 */
class Create extends Guest
{
    /**
     * @var \Magento\Framework\Stdlib\DateTime\DateTime
     */
    private $dateTime;
    /**
     * @var \Magento\Rma\Model\RmaFactory
     */
    private $rmaFactory;
    /**
     * @var \Magento\Rma\Model\Rma\Status\HistoryFactory
     */
    private $historyFactory;
    /**
     * @var \Psr\Log\LoggerInterface
     */
    private $logger;

    /**
     * @param \Magento\Framework\App\Action\Context $context
     * @param \Magento\Framework\Registry $coreRegistry
     * @param \Magento\Rma\Helper\Data $rmaHelper
     * @param \Magento\Sales\Helper\Guest $salesGuestHelper
     * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
     * @param \Magento\Framework\View\Result\LayoutFactory $resultLayoutFactory
     * @param \Magento\Framework\Controller\Result\ForwardFactory $resultForwardFactory
     * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime
     * @param \Magento\Rma\Model\RmaFactory $rmaFactory
     * @param \Psr\Log\LoggerInterface $logger
     * @param \Magento\Rma\Model\Rma\Status\HistoryFactory $historyFactory
     */
    public function __construct(
        Context $context,
        Registry $coreRegistry,
        Data $rmaHelper,
        \Magento\Sales\Helper\Guest $salesGuestHelper,
        PageFactory $resultPageFactory,
        LayoutFactory $resultLayoutFactory,
        ForwardFactory $resultForwardFactory,
        DateTime $dateTime,
        RmaFactory $rmaFactory,
        LoggerInterface $logger,
        HistoryFactory $historyFactory
    ) {
        parent::__construct(
            $context,
            $coreRegistry,
            $rmaHelper,
            $salesGuestHelper,
            $resultPageFactory,
            $resultLayoutFactory,
            $resultForwardFactory
        );
        $this->dateTime = $dateTime;
        $this->rmaFactory = $rmaFactory;
        $this->historyFactory = $historyFactory;
        $this->logger = $logger;
    }

    /**
     * @return \Magento\Framework\Controller\Result\Redirect|\Magento\Framework\Controller\ResultInterface|\Magento\Framework\View\Result\Page
     * @throws \Magento\Framework\Exception\InputException
     * @throws \Magento\Framework\Stdlib\Cookie\CookieSizeLimitReachedException
     * @throws \Magento\Framework\Stdlib\Cookie\FailureToSendException
     */
    public function execute()
    {
        $result = $this->salesGuestHelper->loadValidOrder($this->_request);
        if ($result instanceof ResultInterface) {
            return $result;
        }
        $order = $this->_coreRegistry->registry('current_order');
        $orderId = $order->getId();
        if (!$this->_loadOrderItems($orderId)) {
            return $this->resultRedirectFactory->create()->setPath('sales/order/history');
        }

        $post = $this->getRequest()->getPostValue();

        if ($post && !empty($post['items'])) {
            try {
                /** @var \Magento\Rma\Model\Rma $rmaModel */
                $rmaModel = $this->rmaFactory->create();
                $rmaData = [
                    'status'                => Status::STATE_PENDING,
                    'date_requested'        => $this->dateTime->gmtDate(),
                    'order_id'              => $order->getId(),
                    'order_increment_id'    => $order->getIncrementId(),
                    'store_id'              => $order->getStoreId(),
                    'customer_id'           => $order->getCustomerId(),
                    'order_date'            => $order->getCreatedAt(),
                    'customer_name'         => $order->getCustomerName(),
                    'customer_custom_email' => $post['customer_custom_email'],
                ];
                $result = $rmaModel->setData($rmaData)->saveRma($post);

                if (!$result) {
                    return $this->resultRedirectFactory->create()->setPath('*/*/create', ['order_id' => $orderId]);
                }
                /** @var \Magento\Rma\Model\Rma\Status\History $statusHistory */
                $statusHistory = $this->historyFactory->create();
                $statusHistory->setRmaEntityId($result->getId());
                $statusHistory->sendNewRmaEmail();
                $statusHistory->saveSystemComment();
                if (isset($post['rma_comment']) && !empty($post['rma_comment'])) {
                    /** @var \Magento\Rma\Model\Rma\Status\History $statusHistory */
                    $comment = $this->historyFactory->create();
                    $comment->setRmaEntityId($result->getId());
                    $comment->saveComment($post['rma_comment'], true);
                }
                $this->messageManager->addSuccess(__('You submitted Return #%1.', $rmaModel->getIncrementId()));
                $url = $this->_url->getUrl('*/*/returns');
                return $this->resultRedirectFactory->create()->setUrl($this->_redirect->success($url));
            } catch (Exception $exception) {
                $this->messageManager->addError(
                    __('We can\'t create a return right now. Please try again later.')
                );
                $this->logger->critical($exception, ['exception' => $exception]);
            }
        }
        $resultPage = $this->resultPageFactory->create();
        $resultPage->getConfig()->getTitle()->set(__('Create New Return'));
        if ($block = $resultPage->getLayout()->getBlock('customer.account.link.back')) {
            $block->setRefererUrl($this->_redirect->getRefererUrl());
        }
        return $resultPage;
    }

    /**
     * Try to load valid collection of ordered items
     *
     * @param int $orderId
     * @return bool
     */
    protected function _loadOrderItems($orderId)
    {
        if ($this->rmaHelper->canCreateRma($orderId)) {
            return true;
        }

        $incrementId = $this->_coreRegistry->registry('current_order')->getIncrementId();
        $message = __('We can\'t create a return transaction for order #%1.', $incrementId);
        $this->messageManager->addError($message);
        return false;
    }
}
