<?php

namespace FiloBlu\Storelocator\Rewrite\Magento\Sales\Model\Order;

use Magento\Framework\Exception\AlreadyExistsException;
use Magento\Quote\Model\Quote\Address as QuoteAddress;

/**
 *
 */
class CustomerManagement extends \Magento\Sales\Model\Order\CustomerManagement
{
    /**
     * {@inheritdoc}
     */
    public function create($orderId)
    {
        $order = $this->orderRepository->get($orderId);
        if ($order->getCustomerId()) {
            throw new AlreadyExistsException(__('This order already has associated customer account'));
        }
        $customerData = $this->objectCopyService->copyFieldsetToTarget(
            'order_address',
            'to_customer',
            $order->getBillingAddress(),
            []
        );
        $addresses = $order->getAddresses();
        foreach ($addresses as $address) {
            /* If order has option "pick up in store", I save only billing address.
               The new customer won't have the shipping address, he'll have to add it from the account. */
            if (is_null($order->getPickupInStoreId()) || $address->getAddressType() == QuoteAddress::ADDRESS_TYPE_BILLING) {
                $addressData = $this->objectCopyService->copyFieldsetToTarget(
                    'order_address',
                    'to_customer_address',
                    $address,
                    []
                );
                /** @var \Magento\Customer\Api\Data\AddressInterface $customerAddress */
                $customerAddress = $this->addressFactory->create(['data' => $addressData]);
                switch ($address->getAddressType()) {
                    case QuoteAddress::ADDRESS_TYPE_BILLING:
                        $customerAddress->setIsDefaultBilling(true);
                        break;
                    case QuoteAddress::ADDRESS_TYPE_SHIPPING:
                        $customerAddress->setIsDefaultShipping(true);
                        break;
                }

                if (is_string($address->getRegion())) {
                    /** @var \Magento\Customer\Api\Data\RegionInterface $region */
                    $region = $this->regionFactory->create();
                    $region->setRegion($address->getRegion());
                    $region->setRegionCode($address->getRegionCode());
                    $region->setRegionId($address->getRegionId());
                    $customerAddress->setRegion($region);
                }
                $customerData['addresses'][] = $customerAddress;
            }
        }

        /** @var \Magento\Customer\Api\Data\CustomerInterface $customer */
        $customer = $this->customerFactory->create(['data' => $customerData]);
        $account = $this->accountManagement->createAccount($customer);
        $order->setCustomerId($account->getId());
        $this->orderRepository->save($order);
        return $account;
    }
}