<?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\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;
    }

    /**
     * @inheritdoc
     */
    public function build(array $buildSubject)
    {
        $paymentDO = $this->subjectReader->readPayment($buildSubject);
        
        $request = $this->buildRequestData($buildSubject);
        
        $sellerData[] = $this->saveSellerData($paymentDO);
      
        return [
            self::SELLER => $sellerData
        ];
    }

    /**
     * save seller data for future transactions
     *
     * @param object $paymentDO
     * @param array $finalCart
     * @return void
     */
    public function saveSellerData($paymentDO)
    {
        $payment = $paymentDO->getPayment();
        $order = $paymentDO->getOrder();
        $additionalData = $payment->getAdditionalInformation();
        $seller = $this->customerRepo->get($additionalData['sellerEmail']);
        $delayedTrue = 0;
        if ($this->modConfig->getPaymentMode() == \Webkul\MpPaypal\Model\Source\Disbursement::MODE_DELAYED) {
            $delayedTrue = 1;
        }
        $collection = $this->paypalOrders->create()->getCollection()
        ->addFieldToFilter('quote_id', $additionalData['quoteID'])
        ->addFieldToFilter('seller_id', $seller->getId())->getFirstItem();

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

        if ($collection->getId()) {

            $collection->setUpdatedAt($this->_date->gmtDate())->save();
            return $finalData;

        }

        $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 braintree 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);
    }
}
