<?php

namespace Oney\ThreeByFour\Gateway\Request;

use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Directory\Model\Country;
use Magento\Payment\Gateway\Data\OrderAdapterInterface;
use Magento\Payment\Gateway\Data\PaymentDataObjectInterface;
use Magento\Payment\Gateway\Request\BuilderInterface;
use Oney\ThreeByFour\Helper\Config;
use Oney\ThreeByFour\Logger\Logger;

class CustomerDataBuilder implements BuilderInterface
{
    /**
     * @var Config
     */
    protected $_helperConfig;
    /**
     * @var CustomerRepositoryInterface
     */
    protected $_customerRepository;
    /**
     * @var Logger
     */
    protected $_logger;
    /**
     * @var Country
     */
    protected $country;
    /**
     * CustomerDataBuilder constructor.
     *
     * @param Config                      $helperConfig
     * @param CustomerRepositoryInterface $customerRepository
     * @param Logger                      $logger
     * @param Country                     $country
     */
    public function __construct(
        Config $helperConfig,
        CustomerRepositoryInterface $customerRepository,
        Logger $logger,
        Country $country
    )
    {
        $this->_customerRepository = $customerRepository;
        $this->_logger = $logger;
        $this->country = $country;
        $this->_helperConfig = $helperConfig;
    }

    public function build(array $buildSubject)
    {
        if (!isset($buildSubject['payment']) || !$buildSubject['payment'] instanceof PaymentDataObjectInterface)
        {
            throw new \InvalidArgumentException('Payment data object should be provided');
        }
        /** @var PaymentDataObjectInterface $payment */
        $payment = $buildSubject['payment'];

        $order = $payment->getOrder();
        $billing_address = $order->getBillingAddress();

        $response = [
            'customer' => [
                "customer_external_code" => $order->getOrderIncrementId(),
                "language_code" => $this->_helperConfig->getLanguageCode(),
                "identity" => [
                    "honorific_code" => $this->getGender($order),
                    "first_name" => $billing_address->getFirstname(),
                    "last_name" => $billing_address->getLastname()
                ],
                "contact_details" => [
                    "mobile_phone_number" => $this->formatPhone($billing_address->getTelephone(), $billing_address->getCountryId()),
                    "email_address" => $billing_address->getEmail()
                ]
            ]
        ];
        $this->_logger->info('[SUCCESS] [JSON] Create Customer object (CustomerDataBuilder): ', [
            'customer' => $response['customer']
        ]);
        return $response;
    }

    /**
     * @param OrderAdapterInterface $orderAdapter
     *
     * @return int|null
     */
    protected function getGender(OrderAdapterInterface $orderAdapter)
    {
        try {
            $gender = $this->_customerRepository->getById($orderAdapter->getCustomerId())->getGender();
        } catch (\Exception $e) {
            $gender = 1;
        }

        return ($gender === 3 || $gender === null) ? 1 : $gender;
    }

    /**
     * @param string  $phone
     * @param integer $country
     *
     * @return int|null
     */
    protected function formatPhone($phone, $country)
    {
        $countryCode = $this->_helperConfig->getPhonePrefixByCountry($country);
        // If international Format (+33XXXXXXXXXXX)
        if (preg_match("/^\\+" . $countryCode . "/", $phone)) return $phone;
        // If international Format with 00 (0033XXXXXXXXXXX)
        if (preg_match("/^00" . $countryCode . "/", $phone)) return '+' . ltrim($phone, "0");
        // If national format (0XXXXXXXXXX)
        return '+' . $countryCode . ltrim($phone, "0"); 
        
    }
}
