<?php 

namespace MNM\Spitzner\Plugin\Customer;

use Magento\Customer\Api\Data\AddressInterface;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\Translate\Inline\StateInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\Area;
use Magento\Framework\Reflection\DataObjectProcessor;

class AddressUpdate {
    const MAIL_TO = 'wellness@spitzner.de';
    const MAIL_TEMPLATE = 'spitzner_email_update_address_template';
    
    /**
     * @var TransportBuilder
     */
    private $transportBuilder;

    /**
     * @var StateInterface
     */
    private $inlineTranslation;

    /**
     * @var StoreManagerInterface
     */
    private $storeManager;
    
    /**
     * @var DataObjectProcessor
     */
    private $dataProcessor;

    /**
     * Initialize dependencies.
     *
     * @param TransportBuilder $transportBuilder
     * @param StateInterface $inlineTranslation
     * @param StoreManagerInterface|null $storeManager
     * @param DataObjectProcessor $dataProcessor
     */
    public function __construct(
        TransportBuilder $transportBuilder,
        StateInterface $inlineTranslation,
        StoreManagerInterface $storeManager = null,
        DataObjectProcessor $dataProcessor
    ) {
        $this->transportBuilder = $transportBuilder;
        $this->inlineTranslation = $inlineTranslation;
        $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class);
        $this->dataProcessor = $dataProcessor;
    }
    
    /**
     * 
     * @param \Magento\Customer\Model\Address $subject
     * @param \Magento\Customer\Api\Data\AddressInterface $address
     * 
     * @return \Magento\Customer\Api\Data\AddressInterface
     */
    public function beforeUpdateData(\Magento\Customer\Model\Address $subject, \Magento\Customer\Api\Data\AddressInterface $address)
    {
       $observedAttributes = [ AddressInterface::PREFIX,
                                AddressInterface::FIRSTNAME,
                                AddressInterface::LASTNAME,
                                AddressInterface::SUFFIX,
                                AddressInterface::COMPANY,
                                AddressInterface::STREET, 
                                AddressInterface::POSTCODE,
                                AddressInterface::CITY,
                                AddressInterface::COUNTRY_ID];
        $update = false;
        $oldNotEmpty = false;
        
        // Set all attributes
        $attributes = $this->dataProcessor
                        ->buildOutputDataArray($address, \Magento\Customer\Api\Data\AddressInterface::class);
        
        //check for changes
        foreach ($attributes as $attributeCode => $attributeData) 
        {
            if (in_array($attributeCode, $observedAttributes))
            {
                $old = $subject->getDataUsingMethod($attributeCode);
                $new = $attributeData;
                
                if(     $old != $new
                    &&  (   !is_array($new)
                        ||  count($old) == count($new)
                        ||  (   array_filter($old, function($a) {return !empty($a);}) != $new
                            &&  $old != array_filter($new, function($a) {return !empty($a);}))))
                {
                    $update = true;
                    
                    if(!is_array($old) && !empty($old))
                    {
                        $oldNotEmpty = true;
                    }
                }
            }
        }
        
        if($update && $oldNotEmpty)
        {
            $old = [];
            $new = [];
            
            foreach($observedAttributes as $attributeCode)
            {
                $old[$attributeCode] = '';
                $new[$attributeCode] = '';             
            }
            
            foreach ($attributes as $attributeCode => $attributeData)
            {
                if (in_array($attributeCode, $observedAttributes))
                {
                    $old[$attributeCode] = $subject->getDataUsingMethod($attributeCode);
                    $new[$attributeCode] = $attributeData;
                    
                    //make sure street has two entries
                    if($attributeCode == 'street')
                    {
                        $old[$attributeCode] = [$old[$attributeCode][0], $old[$attributeCode][1] ?? ''];
                        $new[$attributeCode] = [$new[$attributeCode][0], $new[$attributeCode][1] ?? ''];
                    }
                }
            }            
            
            $this->sendMail([
                'customer_id' => $subject->getCustomerId(),
                'oldAddress' => $old,
                'newAddress' => $new
            ]);
        }
    }
    
    /**
     * Send email
     *
     * @param array $variables
     * @return void
     */
    protected function sendMail(array $variables)
    {        
        $this->inlineTranslation->suspend();

        try {
            $transport = $this->transportBuilder
                            ->setTemplateIdentifier(self::MAIL_TEMPLATE)
                            ->setTemplateOptions(
                                [
                                    'area' => Area::AREA_FRONTEND,
                                    'store' => $this->storeManager->getStore()->getId()
                                ]
                            )
                            ->setTemplateVars($variables)
                            ->setFrom(['name' => 'Spitzner Webshop', 'email' => 'wellness@spitzner.de'])
                            ->addTo(self::MAIL_TO)
                            ->getTransport();

            $transport->sendMessage();
        } finally {
            $this->inlineTranslation->resume();
        }
    }
}