<?php

namespace Leadlion\Autogedal\Model\Job;

use Firebear\ImportExport\Api\Data\ImportInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\Serialize\Serializer\Serialize as PhpSerializer;
use Magento\Ui\DataProvider\Modifier\PoolInterface;
use Firebear\ImportExport\Model\ResourceModel\Job\CollectionFactory;

/**
 * Class DataProvider
 */
class DataProvider extends \Firebear\ImportExport\Model\Job\DataProvider
{

    /**
     * @var
     */
    protected $collection;

    /**
     * @var DataPersistorInterface
     */
    protected $dataPersistor;

    /**
     * @var array
     */
    protected $loadedData;

    /**
     * @var PoolInterface
     */
    protected $pool;
    /**
     * @var PhpSerializer
     */
    private $phpSerializer;

    /**
     * DataProvider constructor.
     * @param string $name
     * @param string $primaryFieldName
     * @param string $requestFieldName
     * @param CollectionFactory $importCollectionFactory
     * @param DataPersistorInterface $dataPersistor
     * @param PoolInterface $pool
     * @param array $meta
     * @param array $data
     */
    public function __construct(
        $name,
        $primaryFieldName,
        $requestFieldName,
        CollectionFactory $importCollectionFactory,
        DataPersistorInterface $dataPersistor,
        PoolInterface $pool,
        PhpSerializer $phpSerializer,
        array $meta = [],
        array $data = []
    ) {
        $this->collection = $importCollectionFactory->create();
        $this->dataPersistor = $dataPersistor;
        parent::__construct($name, $primaryFieldName, $requestFieldName, $importCollectionFactory, $dataPersistor, $pool, $phpSerializer, $meta, $data);
        $this->pool = $pool;
        $this->phpSerializer = $phpSerializer;
    }

    /**
     * Get data
     *
     * @return array
     */
    public function getData()
    {
        if (isset($this->loadedData)) {
            return $this->loadedData;
        }
        /** @var \Firebear\ImportExport\Model\Job[] $items */
        $items = $this->collection->getItems();
        $mergeFields = [
            ImportInterface::BEHAVIOR_DATA,
            ImportInterface::SOURCE_DATA
        ];
        foreach ($items as $job) {
            $data = $job->getData();
            if ($maps = $job->getMap()) {
                $map = $this->scopeMaps($maps);
                $data = array_merge($data, $map);
                $data = array_merge($data, ['special_map' => $map]);
            }
            $data = array_merge($data, $this->scopeReplacings($job));

            if (!empty($job->getMapping()) && $maps = $this->phpSerializer->unserialize($job->getMapping())) {
                $map = $this->scopeCategoriesMapping($maps);
                $data = array_merge($data, $map);
                $data = array_merge($data, ['special_map_category' => $map]);

                $attributeValuesMap = $this->scopeAttributeValuesMapping($maps);
                $data = array_merge($data, $attributeValuesMap);
                $deliveryTermMap = $this->scopeDeliveryTermsMapping($maps);
                $data = array_merge($data, $deliveryTermMap);
            }

            if (!empty($job->getPriceRules())
                && $priceRules = $this->phpSerializer->unserialize($job->getPriceRules())
            ) {
                $priceRules = $this->scopePriceRules($priceRules);
                $data = array_merge($data, $priceRules);
            }

            foreach ($mergeFields as $name) {
                if ($data[$name]) {
                    $tempData = $data[$name];
                    unset($data[$name]);
                    $data += $tempData;
                }
            }
            $data = array_merge($data, $this->scopeVariations($data));
            $this->loadedData[$job->getId()] = $data;
        }

        $data = $this->dataPersistor->get('job');

        if (!empty($data)) {
            $job = $this->collection->getNewEmptyItem();
            $job->setData($data);
            $this->loadedData[$job->getId()] = $job->getData();
            $this->dataPersistor->clear('job');
        }

        return $this->loadedData;
    }

    /**
     * Highlight attribute values data inside common maps
     *
     * @param array $maps
     * @return array
     */
    protected function scopeDeliveryTermsMapping(array $maps)
    {
        $map['source_data_delivery_date_map'] = [];
        $count = 0;

        foreach ($maps as $key => $field) {
            if (is_array($field)) {
                foreach ($field as $mapField) {
                    if (isset($mapField['source_data_attribute_code_system']) &&
                        isset($mapField['source_data_qty']) &&
                        isset($mapField['source_data_delivery_date'])
                    ) {
                        $mapField['count'] = $count++;
                        $map['source_data_delivery_date_map'][] = $mapField;
                    }
                }
            }
        }

        return $map;
    }
}
