<?php

namespace Oney\ThreeByFour\Model\Api\Payment;

use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Directory\Model\Country;
use Magento\Framework\HTTP\Client\Curl;
use Magento\Framework\Message\ManagerInterface;
use Magento\Framework\UrlInterface;
use Magento\Sales\Api\Data\OrderInterface;
use Oney\ThreeByFour\Api\Payment\PurchaseInterface;
use Oney\ThreeByFour\Helper\Config as HelperConfig;
use Oney\ThreeByFour\Logger\Logger;
use Oney\ThreeByFour\Model\Api\ApiAbstract;

class Purchase extends ApiAbstract implements PurchaseInterface
{
    /**
     * @var Country
     */
    protected $_country;
    /**
     * @var CustomerRepositoryInterface
     */
    protected $_customerRepository;
    /**
     * @var UrlInterface
     */
    protected $_urlBuilder;

    /**
     * Purchase constructor.
     *
     * @param Curl                        $client
     * @param HelperConfig                $config
     * @param Logger                      $logger
     * @param ManagerInterface            $messageManager
     * @param Country                     $country
     * @param CustomerRepositoryInterface $customerRepository
     * @param UrlInterface                $urlBuilder
     */
    public function __construct(
        Curl $client,
        HelperConfig $config,
        Logger $logger,
        ManagerInterface $messageManager,
        Country $country,
        CustomerRepositoryInterface $customerRepository,
        UrlInterface $urlBuilder
    )
    {
        $this->_country = $country;
        $this->_urlBuilder = $urlBuilder;
        $this->_customerRepository = $customerRepository;
        $this->_logger = $logger;
        parent::__construct($client, $config, $logger, $messageManager);
    }

    public function purchase(OrderInterface $order)
    {
        $this->setParams($this->buildParams($order));

        $this->addHeader('X-Oney-Authorization', $this->_helperConfig->getGeneralConfigValue('api_payment'))
            ->addHeader('X-Oney-Partner-Country-Code', $this->_helperConfig->getCountrySpecificationsConfigValue('country', $order->getStoreId()));

        return $this->call("POST", $this->_helperConfig->getUrlForStep('purchase'));
    }

    protected function buildParams(OrderInterface $order)
    {
        $carrierCode = explode("_", $order->getShippingMethod())[0];
        $deliveryModeCode = $this->_helperConfig->getCarrierConfig($carrierCode, 'deliverymodecode');
        $expressDeliveryFlag = $this->_helperConfig->getCarrierConfig($carrierCode, 'expressdeliveryflag');
        $shippingAddress = $order->getShippingAddress();
        $billingAddress = $order->getBillingAddress();

        $itemList = [];
        $maxPrice = 0;

        foreach ($order->getItems() as $item){
            /** @var  \Magento\Sales\Model\Order\Item $item */
            if ($maxPrice < $item->getPrice()) $maxPrice = $item->getPrice();

            $itemList[] = [
                "type" => 1,
                "label" => $item->getName(),
                "item_external_code" => $item->getSku(),
                "quantity" => (int)$item->getQtyOrdered(),
                "price" => $item->getPrice()
                
            ];
        }

        $itemList[] = [
            "type" => 3,
            "label" => "TRANSPORT",
            "item_external_code" => 'shipping_fees',
            "quantity" => 1,
            "price" => $order->getShippingAmount()
        ];

        $deliveryAddress = [
            "line1" => $this->streetToLine($deliveryAddress, $shippingAddress->getStreet(), $deliveryModeCode),
            "postal_code" => $shippingAddress->getPostCode(),
            "municipality" => $shippingAddress->getCity(),
            "country_code" => $this->_country->loadByCode($shippingAddress->getCountryId())->getData('iso3_code')
        ];

        $delivery = [
            "delivery_mode_code" => $deliveryModeCode,
            "express_delivery_flag" => $expressDeliveryFlag,
            "delivery_address" => $deliveryAddress,
            "delivery_point_name" => $this->_helperConfig->getConfigValue('general/store_information/name')
        ];

        $purchase = [
            "external_reference" => $order->getIncrementId(),
            "delivery" => $delivery,
            "item_list" => $itemList
            
        ];

        $customerAddress = [
            "line1" => $this->streetToLine($deliveryAddress, $shippingAddress->getStreet(), $expressDeliveryFlag),
            "postal_code" => $billingAddress->getPostcode(),
            "municipality" => $billingAddress->getCity(),
            "country_code" => $this->_country->loadByCode($billingAddress->getCountryId())->getData('iso3_code')
        ];

        $this->streetToLine($customerAddress,$billingAddress->getStreet(), $expressDeliveryFlag);

        $customer = [
            "customer_external_code" => $order->getIncrementId(),
            "identity" => [
                "honorific_code" => $this->getGender($order),
                "first_name" => $order->getCustomerFirstname(),
                "last_name" => $order->getCustomerLastname()
            ],
            "contact_details" => [
                "mobile_phone_number" => $billingAddress->getTelephone(),
                "email_address" => $order->getCustomerEmail()
            ],
            "customer_address" => $customerAddress
        ];

        $payment = [
            "business_transaction_code" => str_replace('threebyfour_', '', $order->getPayment()->getMethod()),
            "payment_amount" => $order->getGrandTotal(),
            "currency_code" => $order->getOrderCurrencyCode()
        ];

        $navigation = [
            "success_url" => $this->_urlBuilder->getUrl("checkout/onepage/success"),
            "fail_url" => $this->_urlBuilder->getUrl("checkout/onepage/success"),
            "pending_url" => $this->_urlBuilder->getUrl("checkout/onepage/success", ['pending' => '1']),
            "server_response_url" => $this->_urlBuilder->getUrl("threebyfour/payment/callback")
        ];

        $body = [
            "psp_guid" => $this->_helperConfig->getGeneralConfigValue("psp_guid"),
            "merchant_guid" => $this->_helperConfig->getGeneralConfigValue("merchant_guid"),
            "merchant_request_id" => $order->getIncrementId() . "_" . date('YmdHms'),
            "purchase" => $purchase,
            "customer" => $customer,
            "payment" => $payment,
            "navigation" => $navigation
        ];

        $this->_logger->info('[SUCCESS] [JSON] Create Payment complete object (PurchaseInterface): ', [
            'body' => $body
        ]);

        return $body;
    }

    protected function getGender(OrderInterface $order) {
        if ($order->getCustomerGender() == 3) return 1;
        return $order->getCustomerGender();
    }


    protected function streetToLine(&$deliveryAddress, $streets = [], $shippingMode = 1) {
        $delivery_address_full = "";

        foreach ($streets as $key => $line) {
            $delivery_address_full .= $line;
        }

        $name = [];
        if ($shippingMode == 1 && strpos($delivery_address_full, '/') !== false) {
            $name = explode('/', $delivery_address_full);
            $delivery_address_full = str_replace($name[0].'/', '', $delivery_address_full);
        }

        $delivery_address_split = str_split($delivery_address_full,38);

        if ($shippingMode == 1 && count($name) > 1) {
            array_unshift($delivery_address_split, $name[0]);
        }

        foreach ($delivery_address_split as $key => $line) {
            $delivery_address['line'. ($key+1)] = $line;
        }
    }
}
