<?php
/**
 * Webkul Software.
 *
 * @category  Webkul
 * @package   Webkul_MpPayPal
 * @author    Webkul
 * @copyright Copyright (c) Webkul Software Private Limited (https://webkul.com)
 * @license   https://store.webkul.com/license.html
 */
namespace Webkul\MpPayPal\Gateway\Request;

use Magento\Payment\Gateway\Request\BuilderInterface;
use Webkul\MpPayPal\Gateway\Helper\SubjectReader;
use Magento\Framework\ObjectManager\TMap;
use Magento\Framework\ObjectManager\TMapFactory;
use Webkul\MpPayPal\Observer\DataAssignObserver;
use Webkul\MpPayPal\Model\PayPal\Adapter as MpPaypalAdapter;

/**
 * Class CustomerDataBuilder
 */
class SellerDataBuilder implements BuilderInterface
{
    /**
     * seller id
     */
    const SELLER = 'seller';

    /**
     * @var SubjectReader
     */
    private $subjectReader;

    /**
     * @var array
     */
    private $builders;

    /**
     * @var Webkul\MpPayPal\Helper\Data
     */
    private $_helper;

    /**
     * @var MpPaypalAdapter
     */
    protected $adapter;

    /**
     * @var string
     */
    protected $_paymentMethodToken;

    /**
     * @var \Magento\Customer\Model\CustomerFactory
     */
    protected $customerFactory;

    /**
     * Constructor
     *
     * @param SubjectReader $subjectReader
     */
    public function __construct(
        SubjectReader $subjectReader,
        \Webkul\MpPayPal\Helper\Data $helper,
        TMapFactory $tmapFactory,
        \Magento\Sales\Model\OrderFactory $orderFactory,
        \Webkul\MpPayPal\Model\MpPayPalFactory $paypalOrders,
        \Magento\Framework\Stdlib\DateTime\DateTime $date,
        \Webkul\MpPayPal\Gateway\Config\Config $modConfig,
        \Magento\Framework\Json\Helper\Data $jsonHelper,
        \Magento\Customer\Api\CustomerRepositoryInterface $customerRepo,
        MpPaypalAdapter $adapter,
        \Magento\Customer\Model\CustomerFactory $customerFactory,
        array $builders = []
    ) {
    
        $this->subjectReader = $subjectReader;
        $this->_helper = $helper;
        $this->paypalOrders = $paypalOrders;
        $this->orderFactory = $orderFactory;
        $this->_date = $date;
        $this->customerRepo = $customerRepo;
        $this->modConfig = $modConfig;
        $this->builders = $tmapFactory->create(
            [
                'array' => $builders,
                'type' => BuilderInterface::class
            ]
        );
        $this->adapter = $adapter;
        $this->customerFactory = $customerFactory;
        $this->jsonHelper = $jsonHelper;
    }

    /**
     * @inheritdoc
     */
    public function build(array $buildSubject)
    {
        $this->_helper->logDataInLogger('sellerDataBuilder '.$this->jsonHelper->jsonEncode($buildSubject));
        $paymentDO = $this->subjectReader->readPayment($buildSubject);
        
        $request = $this->buildRequestData($buildSubject);
        $payment = $paymentDO->getPayment();

        $additionalData = $payment->getAdditionalInformation();

        $paypalOrder = $this->adapter->findOrder($additionalData['orderID']);
        foreach ($paypalOrder['purchase_units'] as $purchaseUnits) {
            $sellerId = explode('sellerId_', $purchaseUnits['reference_id'])[1];
            $sellerData[] = $this->saveSellerData($paymentDO, $additionalData, $sellerId, $purchaseUnits);
        }
      
        return [
            self::SELLER => $sellerData
        ];
    }

    /**
     * save seller data for future transactions
     */
    public function saveSellerData($paymentDO, $additionalData, $sellerId, $purchaseUnits)
    {
        $order = $paymentDO->getOrder();

        $delayedTrue = 0;
        if ($this->modConfig->getPaymentMode() == \Webkul\MpPayPal\Model\Source\Disbursement::MODE_DELAYED) {
            $delayedTrue = 1;
        }

        $finalData = [
            'quote_id' => $additionalData['quoteID'],
            'delayed_payment' => $delayedTrue,
            'seller_id' => $sellerId,
            'order_id' => $order->getOrderIncrementId(),
            'paypal_order_id' => $additionalData['orderID'],
            'paypal_payer_id' => $additionalData['payerID'],
            'paypal_payment_token' => $additionalData['paymentToken'],
            'paypal_invoice_id' => $purchaseUnits['invoice_id'],
        ];

        $finalData['updated_at'] = $this->_date->gmtDate();
        $finalData['created_at'] = $this->_date->gmtDate();
        
        $paypalOrder = $this->paypalOrders->create();
    
        $paypalOrder->setData($finalData)->save();
        
        return $finalData;
    }

    /**
     * create request for paypal transaction
     *
     * @param object $buildSubject
     * @return array
     */
    private function buildRequestData($buildSubject)
    {
        $result = [];
        foreach ($this->builders as $builder) {
            // @TODO implement exceptions catching
            $result = $this->merge($result, $builder->build($buildSubject));
        }

        return $result;
    }

    /**
     * Merge function for builders
     *
     * @param array $result
     * @param array $builder
     * @return array
     */
    protected function merge(array $result, array $builder)
    {
        return array_replace_recursive($result, $builder);
    }
}
