<?php

namespace Leadlion\Autogedal\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer;
use Magento\CatalogImportExport\Model\Import\Product as ImportProduct;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Catalog\Model\Product\Action;

class DeliveryTerm implements ObserverInterface
{
    const MANUFACTURER = 'manufacturer';
    const QTY = 'qty';
    const TERMEN_LIVRARE = 'termen_livrare';
    const URL_KEY_ATTRIBUTE_CODE = 'url_key';

    /**
     * @var array
     */
    protected $import;
    protected $resource;
    protected $productRepository;
    /**
     * @var Action
     */
    private $productAction;

    public function __construct(
        \Magento\Framework\App\ResourceConnection $resource,
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
        Action $productAction
    ) {
        $this->productRepository = $productRepository;
        $this->resource = $resource;
        $this->productAction = $productAction;
    }

    /**
     * @param Observer $observer
     */
    public function execute(Observer $observer)
    {
        try {
            $this->import = $observer->getEvent()->getAdapter();
            $parameters = $this->import->getParameters();
            if (isset($parameters['job_id']) &&
                isset($parameters['delivery_terms']) &&
                !empty($parameters['delivery_terms'])
            ) {
                $deliveryTerms = $parameters['delivery_terms'];
                $deliveryTermsByManufacturer = [];
                foreach ($deliveryTerms as $key => $info) {
                    $deliveryTermsByManufacturer[$info['source_data_attribute_code_system']][] = [
                        'qty' => $info['source_data_qty'],
                        'compare' => $info['compare'],
                        'delivery_term' => $info['source_data_delivery_date']
                    ];
                }
                if ($products = $observer->getEvent()->getBunch()) {
                    $products = $this->prepareProducts($products);
                    foreach ($products as $product) {
                        if (isset($product[self::MANUFACTURER]) &&
                            $product[self::MANUFACTURER] &&
                            isset($deliveryTermsByManufacturer[$product[self::MANUFACTURER]]) &&
                            isset($product[self::QTY])
                        ) {
                            $prodAttrDeliveryTermValue =
                                $this->getDeliveryTermAttrValue(
                                    $product[self::QTY],
                                    $deliveryTermsByManufacturer[$product[self::MANUFACTURER]]
                                );
                            try {
                                // $product = $this->productRepository->getById($product['entity_id']);
                                // $product->setData(self::TERMEN_LIVRARE, $prodAttrDeliveryTermValue);
                                // $this->productRepository->save($product);
                                $this->productAction->updateAttributes(
                                    [$product['entity_id']],
                                    [self::TERMEN_LIVRARE => $prodAttrDeliveryTermValue],
                                    0
                                );
                            } catch (NoSuchEntityException $e) {
                                continue;
                            } catch (\Exception $e) {
                                continue;
                            }
                        }
                    }

                }
            }
        } catch (\Exception $e) {
            $this->addLogWriteln($e->getMessage(), 'error');
        }
    }

    private function getDeliveryTermAttrValue($productQty, $manufacturerRulesInfo)
    {
        $deliveryTermValue=null;
        foreach ($manufacturerRulesInfo as $key => $info) {
            $comparisons = $info['compare'];
            switch ($comparisons) {
                case 'eq':
                    if ($productQty == $info['qty']) {
                        $deliveryTermValue = $info['delivery_term'];
                    }
                    break;
                case 'gteq':
                    if ($productQty >= $info['qty']) {
                        $deliveryTermValue = $info['delivery_term'];
                    }
                    break;
                case 'gt':
                    if ($productQty > $info['qty']) {
                        $deliveryTermValue = $info['delivery_term'];
                    }
                    break;
                case 'lt':
                    if ($productQty < $info['qty']) {
                        $deliveryTermValue = $info['delivery_term'];
                    }
                    break;
                case 'lteq':
                    if ($productQty <= $info['qty']) {
                        $deliveryTermValue = $info['delivery_term'];
                    }
                    break;
                default:
                    $deliveryTermValue = null;
                    break;
            }
        }

        return $deliveryTermValue;
    }

    /**
     * @param array $rowData
     * @return array|null
     */
    private function getProductId(array $rowData)
    {
        $newSku = $this->import->getNewSku($rowData[ImportProduct::COL_SKU]);
        if (empty($newSku) || !isset($newSku['entity_id'])) {
            return null;
        }
        if ($this->import->getRowScope($rowData) == ImportProduct::SCOPE_STORE
            && empty($rowData[self::URL_KEY_ATTRIBUTE_CODE])) {
            return null;
        }
        $rowData['entity_id'] = $newSku['entity_id'];
        return $rowData['entity_id'];
    }

    /**
     * @param $debugData
     * @param null $type
     */
    private function addLogWriteln($debugData, $type = null)
    {
        if (method_exists($this->import, 'addLogWriteln')
            && method_exists($this->import, 'getOutput')
        ) {
            $this->import->addLogWriteln(
                $debugData,
                $this->import->getOutput(),
                $type
            );
        }
    }

    /**
     * @param $rows
     * @return mixed
     */
    protected function prepareProducts($rows)
    {
        foreach ($rows as &$row) {
            $row['entity_id'] = $this->getProductId($row);
        }

        return $rows;
    }
}
