<?php

namespace FiloBlu\Rma\Plugin\Returns;

use FiloBlu\Rma\Helper\RmaHelper;
use FiloBlu\Rma\Helper\ChangeSizeAttributeHelper;
use FiloBlu\Rma\Logger\Logger;
use FiloBlu\Rma\Model\ChangeSize;
use Magento\Sales\Api\OrderRepositoryInterface;
use Psr\Log\LoggerInterface;
use Magento\Rma\Controller\Returns\Create as ReturnsCreate;
use Magento\Framework\Stdlib\Cookie\PublicCookieMetadataFactory;
use Magento\Framework\Stdlib\CookieManagerInterface;


class Create
{
    /**
     * @var RmaHelper
     */
    private $rmaHelper;

    /**
     * @var ChangeSizeAttributeHelper
     */
    private $changeSizeAttributeHelper;

    /**
     * @var PublicCookieMetadataFactory
     */
    private $publicCookieMetadataFactory;
    /**
     * @var CookieManagerInterface
     */
    private $cookieManager;
    /**
     * @var LoggerInterface
     */
    private $logger;
    /**
     * @var Logger
     */
    private $filobluLogger;
    /**
     * @var ChangeSize
     */
    private $changeSize;
    /**
     * @var OrderRepositoryInterface
     */
    private $orderRepository;

    /**
     * Create constructor.
     * @param RmaHelper $rmaHelper
     * @param ChangeSizeAttributeHelper $changeSizeAttributeHelper
     * @param PublicCookieMetadataFactory $publicCookieMetadataFactory
     * @param CookieManagerInterface $cookieManager
     * @param LoggerInterface $logger
     * @param Logger $filobluLogger
     * @param ChangeSize $changeSize
     * @param OrderRepositoryInterface $orderRepository
     */
    public function __construct(
        RmaHelper $rmaHelper,
        ChangeSizeAttributeHelper $changeSizeAttributeHelper,
        PublicCookieMetadataFactory $publicCookieMetadataFactory,
        CookieManagerInterface $cookieManager,
        LoggerInterface $logger,
        Logger $filobluLogger,
        ChangeSize $changeSize,
        OrderRepositoryInterface $orderRepository
    )
    {
        $this->rmaHelper = $rmaHelper;
        $this->changeSizeAttributeHelper = $changeSizeAttributeHelper;
        $this->publicCookieMetadataFactory = $publicCookieMetadataFactory;
        $this->cookieManager = $cookieManager;
        $this->logger = $logger;
        $this->filobluLogger = $filobluLogger;
        $this->changeSize = $changeSize;
        $this->orderRepository = $orderRepository;
    }

    /**
     * @param ReturnsCreate $subject
     * @param callable $proceed
     * @return mixed
     */
    public function aroundExecute(ReturnsCreate $subject, callable $proceed)
    {
        try {
            $orderId = (int)$subject->getRequest()->getParam('order_id');
            if ($subject->getRequest()->getMethod() !== 'POST') {
                return $proceed();
            }
            $post = $subject->getRequest()->getPostValue();
            $isValid = true;
            $error = [];
            $itemToLog = [];
            if (isset($post['items'])) {

                $changeSizeResolution = $this->changeSizeAttributeHelper->getChangeSizeAttributeOptionId();
                foreach ($post['items'] as $item) {
                    if (isset($item['resolution']) && $item['resolution'] == $changeSizeResolution) {
                        $itemToLog [] =$item;
                        if (!isset($item['reason'])) {
                            $isValid = false;
                            $error [] = 'Reason is empty';
                        } else {
                            $isValid = $this->rmaHelper->checkIfAllowedMagentoChangeSizeReason($item['reason']);
                            if (!$isValid) {
                                $error [] = "The selected reason isn't allowed with selected resolution";
                            }
                            if (!isset($item['change_size']) || (isset($item['change_size']) && $item['change_size'] == 0)) {
                                $isValid = false;
                                $error [] = "Change Size isn't setted properly";
                            }
                            if(isset($item['change_size']) && $item['change_size']>0){
                                $storeId = $this->orderRepository->get($orderId)->getStoreId();
                                $qtyAvailable = $this->changeSize->getProductQtyById($item['change_size'],$storeId);
                                if($qtyAvailable < $item['qty_requested']){
                                    $isValid = false;
                                    $error [] = "Product is no more available, please select a new size or request a new resolution.";
                                    $itemToLog [] = "Product with id ".$item['change_size']." is no more available. Request resetted!";
                                }
                            }
                        }
                    }
                    if (!$isValid) {
                        if (count($error) > 0) {
                            $details = implode(",", $error);
                        } else {
                            $details = "";
                        }
                        $message = __('We can\'t create a return transaction. Errors:' . $details);
                        $metadata = $this->publicCookieMetadataFactory->create()->setPath('/')->setSecure(false)->setHttpOnly(false);
                        $this->cookieManager->setPublicCookie('mage-messages', json_encode(['type' => 'error', 'text' => $message]), $metadata);
                        $subject->getRequest()->setPostValue([]);
                        return $proceed();
                    }
                }
            }
            if(count($itemToLog)>0){
                $mes ="[".date("d/m/Y h:i:s")."] New ChangeSize Rma Request on orderId ".$subject->getRequest()->getParam('order_id')." :";
                $mes .= json_encode($itemToLog);
                $this->filobluLogger->debug($mes);
            }
            return $proceed();
        } catch (\Exception $e) {
            $subject->getRequest()->setPostValue([]);
            $this->logger->critical($e->getMessage());
            return $proceed();
        } catch (\Throwable $t) {
            $subject->getRequest()->setPostValue([]);
            $this->logger->critical($t->getMessage());
            return $proceed();
        }
    }
}
