<?php
/**
 * Mageplaza
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Mageplaza.com license that is
 * available through the world-wide-web at this URL:
 * https://www.mageplaza.com/LICENSE.txt
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade this extension to newer
 * version in the future.
 *
 * @category    Mageplaza
 * @package     Mageplaza_EditOrder
 * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)
 * @license     https://www.mageplaza.com/LICENSE.txt
 */

namespace Mageplaza\EditOrder\Block\Adminhtml\Order\Edit;

use Magento\Backend\Block\Template\Context;
use Magento\Backend\Block\Widget\Form\Generic;
use Magento\Customer\Model\Customer as CustomerModel;
use Magento\Customer\Model\CustomerFactory;
use Magento\Customer\Model\ResourceModel\Customer\CollectionFactory;
use Magento\Customer\Model\ResourceModel\Group\Collection;
use Magento\Eav\Model\Config;
use Magento\Framework\Data\Form;
use Magento\Framework\Data\FormFactory;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Message\ManagerInterface as MessageInterface;
use Magento\Framework\Registry;
use Magento\Newsletter\Model\Queue;
use Magento\Sales\Model\Order;
use Magento\Store\Model\System\Store;
use Mageplaza\EditOrder\Block\Adminhtml\Order\EditOrder;
use Mageplaza\EditOrder\Helper\Data;
use Mageplaza\EditOrder\Model\Config\Source\Customer;

/**
 * Class CustomerInfo
 * @package Mageplaza\EditOrder\Block\Adminhtml\Order\Edit
 */
class CustomerInfo extends Generic
{
    /**
     * @var EditOrder
     */
    protected $editOrder;

    /**
     * @var Store
     */
    protected $_systemStore;

    /**
     * @var Customer
     */
    protected $editCustomer;

    /**
     * @var Config
     */
    protected $eavConfig;

    /**
     * @var Collection
     */
    protected $_customerGroupColl;

    /**
     * @var MessageInterface
     */
    protected $_messageManager;

    /**
     * @var CollectionFactory
     */
    private $collectionFactory;

    /**
     * @var CustomerFactory
     */
    private $customerFactory;

    /**
     * @var CustomerModel
     */
    protected $customerModel;

    /**
     * CustomerInfo constructor.
     *
     * @param Context $context
     * @param Registry $registry
     * @param FormFactory $formFactory
     * @param EditOrder $editOrder
     * @param Store $systemStore
     * @param Customer $editCustomer
     * @param Collection $customerGroupColl
     * @param Config $eavConfig
     * @param MessageInterface $messageManager
     * @param CollectionFactory $collectionFactory
     * @param CustomerFactory $customerFactory
     * @param CustomerModel $customerModel
     * @param array $data
     */
    public function __construct(
        Context $context,
        Registry $registry,
        FormFactory $formFactory,
        EditOrder $editOrder,
        Store $systemStore,
        Customer $editCustomer,
        Collection $customerGroupColl,
        Config $eavConfig,
        MessageInterface $messageManager,
        CollectionFactory $collectionFactory,
        CustomerFactory $customerFactory,
        CustomerModel $customerModel,
        array $data = []
    ) {
        $this->editOrder          = $editOrder;
        $this->_systemStore       = $systemStore;
        $this->_customerGroupColl = $customerGroupColl;
        $this->editCustomer       = $editCustomer;
        $this->eavConfig          = $eavConfig;
        $this->_messageManager    = $messageManager;
        $this->collectionFactory  = $collectionFactory;
        $this->customerFactory    = $customerFactory;
        $this->customerModel      = $customerModel;

        parent::__construct($context, $registry, $formFactory, $data);
    }

    /**
     * @return $this|Generic
     * @throws LocalizedException
     * @throws NoSuchEntityException
     */
    protected function _prepareForm()
    {
        /* @var $queue Queue */
        $order      = $this->getCurrentOrder();
        $customer   = $this->customerFactory->create()->load($order->getCustomerId());
        $emailClass = 'validate-email' . $this->isIssetCustomer($order->getCustomerEmail());

        /** @var Form $form */
        $form     = $this->_formFactory->create();
        $fieldset = $form->addFieldset(
            'base_fieldset',
            ['class' => 'fieldset-wide']
        );
        $fieldset->addField(
            'mpeditorder-customer-website-id',
            'hidden',
            [
                'name'     => 'order[customer][website-id]',
                'label'    => __('Associate to Website'),
                'required' => true,
                'values'   => $this->getAssociateWebsite()
            ]
        );
        $fieldset->addField(
            'mpeditorder-customer-email',
            'text',
            [
                'name'     => 'order[customer][email]',
                'label'    => __('Customer Email'),
                'required' => true,
                'class'    => $emailClass,
                'value'    => $order->getCustomerEmail(),
                'readonly' => true
            ]
        );

        $fieldset->addField(
            'check-customer-email-id',
            'hidden',
            [
                'name'  => 'order[customer][check_email_id]',
                'value' => $this->checkExistCustomer($order->getCustomerEmail()),
                'class' => 'check-customer-email-id'
            ]
        );
        $fieldset->addField(
            'mpeditorder-customer-name-prefix',
            'text',
            [
                'name'  => 'order[customer][name-prefix]',
                'label' => __('Name Prefix'),
                'value' => $order->getCustomerPrefix()
            ]
        );

        $fieldset->addField(
            'mpeditorder-customer-first-name',
            'text',
            [
                'name'     => 'order[customer][first-name]',
                'label'    => __('First Name'),
                'required' => true,
                'value'    => $order->getCustomerFirstname()
            ]
        );

        $fieldset->addField(
            'mpeditorder-customer-middle-name',
            'text',
            [
                'name'  => 'order[customer][middle-name]',
                'label' => __('Middle Name/Initial'),
                'value' => $order->getCustomerMiddlename()
            ]
        );

        $fieldset->addField(
            'mpeditorder-customer-last-name',
            'text',
            [
                'name'     => 'order[customer][last-name]',
                'label'    => __('Last Name'),
                'required' => true,
                'value'    => $order->getCustomerLastname()
            ]
        );

        $fieldset->addField(
            'mpeditorder-customer-name-suffix',
            'text',
            [
                'name'  => 'order[customer][name-suffix]',
                'label' => __('Name Suffix'),
                'value' => $order->getCustomerSuffix()
            ]
        );

        $fieldset->addField(
            'mpeditorder-customer-group',
            'select',
            [
                'name'     => 'order[customer][customer-group]',
                'label'    => __('Customer Group'),
                'required' => true,
                'values'   => $this->_customerGroupColl->toOptionArray(),
                'value'    => $order->getCustomerGroupId()
            ]
        );

        $fieldset->addField(
            'mpeditorder-customer-dob',
            'date',
            [
                'name'        => 'order[customer][dob]',
                'label'       => __('Date of Birth'),
                'date_format' => 'M/d/yyyy',
                'timezone'    => false,
                'class'       => 'validate-dob',
                'required'    => false,
                'value'       => $order->getCustomerDob(),
                'max_date'    => date('m/d/Y')
            ]
        );

        $fieldset->addField(
            'mpeditorder-customer-taxvat',
            'text',
            [
                'name'  => 'order[customer][taxvat]',
                'label' => __('Tax/VAT Number'),
                'value' => $order->getCustomerTaxvat()
            ]
        );

        $fieldset->addField(
            'mpeditorder-customer-gender',
            'select',
            [
                'name'   => 'order[customer][gender]',
                'label'  => __('Gender'),
                'values' => $this->getCustomerGenderOptions(),
                'value'  => $order->getCustomerGender() ?: 1
            ]
        );

        if (!$this->_storeManager->hasSingleStore()) {
            $fieldset->addField(
                'mpeditorder-customer-sendemail_store_id',
                'select',
                [
                    'name'   => 'order[customer][sendemail_store_id]',
                    'label'  => __('Send Welcome Email From'),
                    'values' => $this->_systemStore->getStoreValuesForForm(),
                    'value'  => $customer->getData('store_id') ?: 1
                ]
            );
        } else {
            $fieldset->addField(
                'mpeditorder-customer-sendemail_store_id',
                'hidden',
                [
                    'name'  => 'order[customer][sendemail_store_id]',
                    'value' => $this->_storeManager->getStore(true)->getId()
                ]
            );
        }

        $this->setForm($form);

        return $this;
    }

    /**
     * @return string
     */
    public function getButtonEditUrl()
    {
        return $this->getUrl(
            'mpeditorder/customer/form',
            [
                'order_id' => $this->getCurrentOrder()->getId(),
                'form_key' => $this->getFormKey()
            ]
        );
    }

    /**
     * @return string
     */
    public function getUrlOrder()
    {
        return $this->getUrl(
            'sales/order/view',
            [
                'order_id' => $this->getCurrentOrder()->getId(),
                'form_key' => $this->getFormKey()
            ]
        );
    }

    /**
     * @return string
     */
    public function getActionForm()
    {
        return $this->getUrl(
            'mpeditorder/customer/save',
            [
                'order_id'    => $this->getCurrentOrder()->getId(),
                'customer_id' => $this->getCurrentOrder()->getCustomerId()
            ]
        );
    }

    /**
     * @return Order Order
     */
    public function getCurrentOrder()
    {
        return $this->editOrder->getCurrentOrder();
    }

    /**
     * @return string
     */
    public function getCustomerData()
    {
        return $this->editOrder->getCustomerData();
    }

    /**
     * @return array
     */
    public function getCustomerGenderOptions()
    {
        $options = [];

        try {
            $attribute = $this->eavConfig->getAttribute('customer', 'gender');
            $options   = $attribute->getSource()->getAllOptions();
        } catch (LocalizedException $e) {
            $this->_messageManager->addErrorMessage($e->getMessage());
        }

        return $options;
    }

    /**
     * @return string
     */
    public function getCustomerGridUrl()
    {
        return $this->editOrder->getCustomerGridUrl();
    }

    /**
     * @return mixed
     */
    public function getCustomerUrls()
    {
        $urlAr              = [];
        $customerCollection = $this->collectionFactory->create();
        /** @var \Magento\Customer\Model\Customer $item */
        foreach ($customerCollection->getItems() as $item) {
            $customerId         = $item->getId();
            $urlAr[$customerId] = $this->getUrl('customer/index/edit', ['id' => $customerId]);
        }

        return Data::jsonEncode($urlAr);
    }

    /**
     * @return array
     */
    public function getAssociateWebsite()
    {
        $websites = $this->_storeManager->getWebsites();
        $options  = [];

        foreach ($websites as $key => $value) {
            $options[] = ['label' => $value->getName(), 'value' => $key];
        }

        return $options;
    }

    /**
     * @param string $email
     *
     * @return string
     */
    public function isIssetCustomer($email = '')
    {
        if ($email !== '') {
            $customer     = $this->customerFactory->create();
            $customerData = $customer->getCollection()->addFieldToFilter('email', $email);

            if (!empty($customerData->getData())) {
                return ' isset-email';
            }

            return '';
        }

        return '';
    }

    /**
     * Check email already exist
     *
     * @param $email
     *
     * @return int||null
     */
    public function checkExistCustomer($email)
    {
        $customerData = $this->customerModel->getCollection()->addFieldToFilter('email', $email);

        return $customerData->getFirstItem()->getId();
    }

}
