<?php
/**
 * @author  Magediary
 * @package Magediary_ProductQuestion
 */

namespace Magediary\ProductQuestion\Controller\Answer;

use Magento\Framework\App\Action\Action;
use Magento\Framework\Controller\Result\Redirect;
use Magento\Framework\Controller\ResultFactory;
use Magediary\ProductQuestion\Model\Answer;

class Post extends Action
{
    /**
     * @var \Magediary\ProductQuestion\Helper\Data
     */
    protected $_helperData = null;

    /**
     * @var \Magento\Framework\Registry
     */
    protected $coreRegistry = null;

    /**
     * @var \Magento\Customer\Model\Session
     */
    protected $customerSession;

    /**
     * @var \Magento\Framework\Session\Generic
     */
    protected $answerSession;

    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;

    /**
     * @var Answer
     */
    protected $answerFactory;

    /**
     * @var \Magediary\ProductQuestion\Api\QuestionRepositoryInterface
     */
    protected $questionRepository;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $storeManager;

    /**
     * @var \Magento\Framework\Data\Form\FormKey\Validator
     */
    protected $formKeyValidator;

    /**
     * @param \Magento\Framework\App\Action\Context $context
     * @param \Magento\Framework\Registry $coreRegistry
     * @param \Magento\Customer\Model\Session $customerSession
     * @param \Psr\Log\LoggerInterface $logger
     * @param \Magediary\ProductQuestion\Model\AnswerFactory $answerFactory
     * @param \Magediary\ProductQuestion\Api\QuestionRepositoryInterface $questionRepository
     * @param \Magento\Framework\Session\Generic $answerSession
     * @param \Magediary\ProductQuestion\Helper\Data $helperData
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\Framework\Data\Form\FormKey\Validator $formKeyValidator
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\Registry $coreRegistry,
        \Magento\Customer\Model\Session $customerSession,
        \Psr\Log\LoggerInterface $logger,
        \Magediary\ProductQuestion\Model\AnswerFactory $answerFactory,
        \Magediary\ProductQuestion\Api\QuestionRepositoryInterface $questionRepository,
        \Magento\Framework\Session\Generic $answerSession,
        \Magediary\ProductQuestion\Helper\Data $helperData,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Data\Form\FormKey\Validator $formKeyValidator
    ) {
        $this->coreRegistry = $coreRegistry;
        $this->customerSession = $customerSession;
        $this->logger = $logger;
        $this->answerFactory = $answerFactory;
        $this->questionRepository = $questionRepository;
        $this->answerSession = $answerSession;
        $this->_helperData = $helperData;
        $this->storeManager = $storeManager;
        $this->formKeyValidator = $formKeyValidator;

        parent::__construct($context);
    }

    /**
     * Get question id
     *
     * @return int
     */
    protected function getQuestionId()
    {
        return $this->getRequest()->getParam('id', false);
    }

    /**
     * Get product id
     *
     * @return int
     */
    protected function getProductId()
    {
        return $this->getRequest()->getParam('product_id', false);
    }

    /**
     * Get question object by id
     *
     * @return \Magediary\ProductQuestion\Api\Data\QuestionInterface
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function initQuestion()
    {
        return $this->questionRepository->getById(
            $this->getQuestionId()
        );
    }

    /**
     * Submit new answer action
     *
     * @return Redirect
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    public function execute()
    {
        /** @var Redirect $resultRedirect */
        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
        if (!$this->formKeyValidator->validate($this->getRequest())) {
            $resultRedirect->setUrl($this->_redirect->getRefererUrl());
            return $resultRedirect;
        }

        $data = $this->answerSession->getFormData(true);
        if (!$data) {
            $data = $this->getRequest()->getPostValue();
        }
        if (($this->initQuestion()) && !empty($data)) {
            /** @var Answer $answer */
            $answer = $this->answerFactory->create()->setData($data);
            $answer->unsetData('answer_id');

            $validate = $answer->validate();
            if ($validate === true) {
                try {
                    $type = Answer::TYPE_GUEST;
                    if ($this->customerSession->getCustomerId()) {
                        $type = Answer::TYPE_CUSTOMER;

                        if (!$answer->getEmail()) {
                            $answer->setEmail($this->customerSession->getCustomer()->getEmail());
                        }
                    }

                    $status = Answer::STATUS_PENDING;
                    $autoApprove = $this->_helperData->getConfig('question/answer/auto_approval');
                    if ($autoApprove) {
                        $status = Answer::STATUS_APPROVED;
                    }

                    $answer->setQuestionId($this->getQuestionId())
                        ->setProductId($this->getProductId())
                        ->setStatus($status)
                        ->setType($type)
                        ->setCustomerId($this->customerSession->getCustomerId())
                        ->setStoreId($this->storeManager->getStore()->getId())
                        ->save();

                    if ($autoApprove) {
                        $this->messageManager->addSuccess(__('Your answer has been posted successfully.'));
                    } else {
                        $this->messageManager->addSuccess(
                            __('Your answer has been submitted successfully for moderation.')
                        );
                    }
                } catch (\Exception $e) {
                    $this->answerSession->setFormData($data);
                    $this->messageManager->addExceptionMessage(
                        $e,
                        __('We can\'t post your answer right now.')
                    );
                    $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
                }
            } else {
                $this->answerSession->setFormData($data);
                if (is_array($validate)) {
                    foreach ($validate as $errorMessage) {
                        $this->messageManager->addError($errorMessage);
                    }
                } else {
                    $this->messageManager->addError(__('We can\'t post your answer right now.'));
                }
            }
        }
        $redirectUrl = $this->answerSession->getRedirectUrl(true);
        $resultRedirect->setUrl($redirectUrl ?: $this->_redirect->getRedirectUrl());
        return $resultRedirect;
    }
}
