<?php

namespace FiloBlu\Flow\Model\Actions\From;

use Exception;
use Magento\Store\Model\StoreRepository;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Customer\Model\AddressFactory;
use Magento\Directory\Model\Region;
use FiloBlu\Flow\Model\Channel\In\Customer;
use FiloBlu\Flow\Helper\CustomerHelper;

/**
 * Class Addtocustomeraddress
 * @package FiloBlu\Flow\Model\Actions\From
 */
class Addtocustomeraddress
{
    /**
     * @var ScopeConfigInterface
     */
    protected $scopeConfig;
    /**
     * @var AddressFactory
     */
    protected $addressFactory;
    /**
     * @var Region
     */
    protected $modelRegion;
    /**
     * @var Customer
     */
    protected $flowInCustomer;
    /**
     * @var CustomerHelper
     */
    protected $customerHelper;
    protected $customerAddress;


    /**
     * @param ScopeConfigInterface $scopeConfig
     * @param AddressFactory $addressFactory
     * @param Region $modelRegion
     * @param Customer $flowInCustomer
     * @param CustomerHelper $customerHelper
     */
    public function __construct(
        ScopeConfigInterface $scopeConfig,
        AddressFactory $addressFactory,
        Region $modelRegion,
        Customer $flowInCustomer,
        CustomerHelper $customerHelper
    ) {
        $this->scopeConfig = $scopeConfig;
        $this->addressFactory = $addressFactory;
        $this->modelRegion = $modelRegion;
        $this->flowInCustomer = $flowInCustomer;
        $this->customerHelper = $customerHelper;
    }


    /**
     * @param $customer
     * @param $value
     * @param $storeId
     * @param $channelConfig
     * @return void
     * @throws Exception
     */
    public function process($customer, $value, $storeId, $channelConfig)
    {
        if (!$value || count($value) == 0) {
            throw new Exception('Error add_to_customer_address: Empty customer adress');
        }
        if (!$customer->getId()) {
            throw new Exception('Error add_to_customer_address: Customer not found');
        }

        $addressData = [];
        foreach ($value as $actionData) {
            $params = json_decode($actionData['params'], true);
            if ($params[0]['field'] == 'vat_id') {
                if (isset($addressData[$params[0]['type']]['vat_id']) && $addressData[$params[0]['type']]['vat_id'] != '') {
                    continue;
                }
            }
            $addressData[$params[0]['type']][$params[0]['field']] = trim($actionData['value'] ?? '');
        }

        $counter = 1;
        foreach ($addressData as $data) {
            $this->customerAddress = $this->addressFactory->create();
            $this->customerAddress->setCustomerId($customer->getId());
            $this->setAddressData($data);

            if ($counter == 1 && $channelConfig['create_company_with_customer'] && !$this->customerHelper->companyExist($customer->getId())) {
                $companyData = [
                    'company_name'      => $customer->getFirstname(),
                    'company_email'     => $customer->getEmail(),
                    'street'            => $this->customerAddress->getData('street'),
                    'city'              => $this->customerAddress->getData('city'),
                    'country_id'        => $this->customerAddress->getData('country_id'),
                    'region'            => $this->customerAddress->getData('region'),
                    'postcode'          => $this->customerAddress->getData('postcode'),
                    'telephone'         => $this->customerAddress->getData('telephone'),
                    'super_user_id'     => $customer->getId(),
                    'customer_group_id' => $customer->getGroupId()
                ];

                if ($this->customerAddress->getData('region_id')) {
                    $companyData['region_id'] = $this->customerAddress->getData('region_id');
                }

                try {
                    $this->customerHelper->addCompanyToCustomer($companyData);
                } catch (Exception $e) {
                    throw new Exception('Error create company: '.$e->getMessage());
                }
            }

            try {
                $this->customerAddress->save();
            } catch (Exception $e) {
                throw new Exception('Error create customer adress: '.$e->getMessage());
            }
            $counter++;
        }
    }

    /**
     * @param $data
     * @return void
     */
    protected function setAddressData($data)
    {
        if (!isset($data['lastname']) || $data['lastname'] == '') {
            $data['lastname'] = $data['firstname'];
        }

        if (!isset($data['region']) || $data['region'] == '') {
            $data['region'] = $data['city'];
        }

        if (!isset($data['country_id']) || $data['country_id'] == '') {
            $countryId = $this->getCountryByRegion($data['region']);
            if($countryId){
                $data['country_id'] = $countryId;
            }
        }

        if(isset($data['country_id']) && isset($data['region'])) {
            $regionId = $this->getRegionIdByCode($data['region'], $data['country_id']);
            if ($regionId) {
                $this->customerAddress->setData('region_id', $regionId);
            }
        }

        if(!isset($data['postcode']) || $data['postcode'] == '') {
            $data['postcode'] = 'oooo';
        }

        if(!isset($data['telephone']) || $data['telephone'] == '') {
            $data['telephone'] = 'oooo';
        }

        foreach ($data as $addressField => $fieldValue) {
            $this->customerAddress->setData($addressField, $fieldValue);
        }
    }

    /**
     * @param $code
     * @param $countryId
     * @return null|int
     */
    protected function getRegionIdByCode($code, $countryId)
    {
        $region = $this->modelRegion->loadByName(trim($code ?? ''), trim($countryId ?? ''));
        if ($region && $region->getId()) {
            return $region->getId();
        }
        return null;
    }

    protected function getCountryByRegion($region) {
        $region = $this->modelRegion->load(trim($region ?? ''), 'code');
        if ($region && $region->getId()) {
            return $region->getCountryId();
        }
        return null;
    }
}
