<?php

namespace FiloBlu\Storelocator\Controller\Index;

use Exception;
use FiloBlu\Storelocator\Model\StoresFactory;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\Area;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\Controller\Result\Redirect;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\View\Result\Page;
use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\Store;
use Magento\Store\Model\StoreManagerInterface;

/**
 *
 */
class Appointment extends Action
{
    /**
     * @return Redirect|Page
     */

    protected $context;

    /**
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    protected $scopeConfig;

    /**
     * @var \FiloBlu\Storelocator\Model\StoresFactory
     */
    protected $storesFactory;

    /**
     * @var TransportBuilder
     */
    protected $transportBuilder;

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

    /**
     * @var \Magento\Framework\Controller\Result\JsonFactory
     */
    private $resultJsonFactory;

    /**
     * @param \Magento\Framework\App\Action\Context $context
     * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
     * @param \Magento\Store\Model\StoreManagerInterface $_storeManager
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     * @param \FiloBlu\Storelocator\Model\StoresFactory $storesFactory
     * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
     */
    public function __construct(
        Context $context,
        TransportBuilder $transportBuilder,
        StoreManagerInterface $_storeManager,
        ScopeConfigInterface $scopeConfig,
        StoresFactory $storesFactory,
        JsonFactory $resultJsonFactory
    ) {
        parent::__construct($context);
        $this->transportBuilder = $transportBuilder;
        $this->storeManager = $_storeManager;
        $this->scopeConfig = $scopeConfig;
        $this->storesFactory = $storesFactory;
        $this->resultJsonFactory = $resultJsonFactory;
    }

    /**
     * Execute action based on request and return result
     *
     * @return \Magento\Framework\Controller\ResultInterface
     * @throws \Magento\Framework\Exception\NotFoundException|\Magento\Framework\Exception\NoSuchEntityException
     */
    public function execute()
    {
        $resultJson = $this->resultJsonFactory->create();
        $post = $this->getRequest()->getPostValue();

        $requiredFields = ['appointment_name', 'appointment_lastname', 'appointment_email', 'appointment_date', 'appointment_hours', 'appointment_time_slot'];
        foreach ($requiredFields as $field) {
            if (!isset($post[$field]) || empty($post[$field])) {
                $resultJson->setData([
                    'success' => false,
                    'error'   => true,
                    'message' => __('Please fill in all required fields.')
                ]);

                return $resultJson;
            }
        }

        $shopId = $this->getRequest()->getParam('id');
        $shop = $this->storesFactory->create()->load($shopId);
        $shopData = $shop->getData();
        $shopDataArray = $shopData;


        $storeName = $this->scopeConfig->getValue(
            'filoblu_storelocator_section/general/appointment__contact_name',
            ScopeInterface::SCOPE_STORE
        );

        $storeEmail = $this->scopeConfig->getValue(
            'filoblu_storelocator_section/general/appointment__contact_email',
            ScopeInterface::SCOPE_STORE
        );

        $appointmentEmailTemplate = $this->scopeConfig->getValue(
            'filoblu_storelocator_section/general/appointment_email_template',
            ScopeInterface::SCOPE_STORE
        );

        $appointmentEmailTemplateToCustomer = $this->scopeConfig->getValue(
            'filoblu_storelocator_section/general/appointment_email_to_customer_template',
            ScopeInterface::SCOPE_STORE
        );

        $emailToShop = $this->scopeConfig->getValue(
            'filoblu_storelocator_section/general/appointment_email_to_shop',
            ScopeInterface::SCOPE_STORE
        );

        $emailCcToContact = $this->scopeConfig->getValue(
            'filoblu_storelocator_section/general/appointment_email_cc_contact',
            ScopeInterface::SCOPE_STORE
        );

        // Email sender to store

        $fromEmailToStore = $storeEmail;
        $fromNameToStore = $storeName;

        $templateVarsToStore = [
            'store'               => $this->storeManager->getStore(),
            'customer_name'       => $post['appointment_name'],
            'customer_lastname'   => $post['appointment_lastname'],
            'customer_phone'      => $post['appointment_phone'],
            'customer_email'      => $post['appointment_email'],
            'chosen_date'         => $post['appointment_date'],
            'time_slot'           => $post['appointment_time_slot'],
            'appointment_message' => $post['appointment_message'],
            'appointment_hours'   => $post['appointment_hours'],
            'product_name'        => $post['product_name'],
            'product_sku'         => $post['product_sku'],
            'product_price'       => $post['product_price'],
            'product_image'       => $post['product_image'],
            'wishlist_products'   => $post['wishlist_products']
        ];

        $fromToStore = ['email' => $fromEmailToStore, 'name' => $fromNameToStore];
        $toToStore = ($emailToShop && $shopData['email']) ? $shopData['email'] : $storeEmail;
        $emailCcToStore = $emailCcToContact ? $storeEmail : false;


        $templateOptions = [
            'area'  => Area::AREA_FRONTEND,
            'store' => Store::DEFAULT_STORE_ID
        ];

        try {
            if ($emailCcToStore) {
                $transport = $this->transportBuilder->setTemplateIdentifier($appointmentEmailTemplate)
                    ->setTemplateOptions($templateOptions)
                    ->setTemplateVars($templateVarsToStore)
                    ->setFrom($fromToStore)
                    ->addTo($toToStore)
                    ->addCc($emailCcToStore)
                    ->getTransport();
            } else {
                $transport = $this->transportBuilder->setTemplateIdentifier($appointmentEmailTemplate)
                    ->setTemplateOptions($templateOptions)
                    ->setTemplateVars($templateVarsToStore)
                    ->setFrom($fromToStore)
                    ->addTo($toToStore)
                    ->getTransport();
            }
            $transport->sendMessage();
        } catch (LocalizedException $e) {
            return $resultJson->setData(
                [
                    'success' => false,
                    'error'   => true,
                    'message' => __('There was a problem with the request: %1', $e->getMessage())
                ]
            );
        } catch (Exception $e) {
            return $resultJson->setData(['success' => false, 'error' => true, 'message' => __($e->getMessage())]);
        }

        //Email sender to customer

        $templateVarsToCustomer = [
            'store'             => $this->storeManager->getStore(),
            'customer_name'     => $post['appointment_name'],
            'store_name'        => $shopDataArray['title'],
            'store_address'     => $shopDataArray['street'],
            'store_postcode'    => $shopDataArray['postcode'],
            'store_city'        => $shopDataArray['city'],
            'store_phone'       => $shopDataArray['phone_1'],
            'store_email'       => $shopDataArray['email'],
            'product_name'      => $post['product_name'],
            'product_sku'       => $post['product_sku'],
            'product_price'     => $post['product_price'],
            'product_image'     => $post['product_image'],
            'chosen_date'       => $post['appointment_date'],
            'time_slot'         => $post['appointment_time_slot'],
            'wishlist_products' => $post['wishlist_products']
        ];

        $fromEmailToCustomer = $storeEmail;
        $fromNameToCustomer = $storeName;

        $fromToCustomer = ['email' => $fromEmailToCustomer, 'name' => $fromNameToCustomer];

        $toToCustomer = $post['appointment_email'];

        try {
            $transport = $this->transportBuilder->setTemplateIdentifier($appointmentEmailTemplateToCustomer)
                ->setTemplateOptions($templateOptions)
                ->setTemplateVars($templateVarsToCustomer)
                ->setFrom($fromToCustomer)
                ->addTo($toToCustomer)
                ->getTransport();
            $transport->sendMessage();
        } catch (Exception $e) {
            return $resultJson->setData(['success' => false, 'error' => true, 'message' => __($e->getMessage())]);
        }

        $resultJson->setData(
            [
                'success' => true,
                'error'   => false,
                'message' => __('Apointment request recived, a recap email has been sent to you')
            ]
        );

        return $resultJson;
    }
}
