<?php

namespace FiloBlu\Flow\Model\Channel\In;

use Exception;
use FiloBlu\Flow\Block\Adminhtml\Channel\Edit\Tab\Config;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Adapter\AdapterInterface;

/**
 * Class Stock
 * @package FiloBlu\Flow\Model\Channel\In
 */
class Stock extends AbstractModel
{
    /**
     * @var array|null
     */
    protected $lookupConversion = null;

    /**
     * @var AdapterInterface
     */
    protected $connection;

    /**
     * @param $data
     * @return bool
     * @throws Exception
     */
    public function insertData($data)
    {
        $parser = $this->getParser();

        if ($useMap = $this->getChannelConfig()->usesMap()) {
            if (!isset($this->map) || empty($this->map)) {
                throw  new \RuntimeException('Stock has option \'use map = yes\' but no map is provided');
            }

            $this->map = $parser->map;
        }


        $flow = $this->getFile()->getData('flow');
        $model = $this->objectManager->create("FiloBlu\Flow\Model\\{$flow}");

        if (!$model) {
            return false;
        }

        $model->setData('meta_file', $this->getFile()->getId());
        $model->setData('meta_processed', 0);

        foreach ($data as $field => $value) {

            // Have a json mapping?
            if (!$useMap) {
                $model->setData($field, $value);
                continue;
            }

            // Get the mapping
            $fieldMap = $this->map->get($field);
            // I need to skip this?
            if (isset($fieldMap['skip']) && $fieldMap['skip']) {
                continue;
            }
            // Have a destination field? Set that as a 'to field'
            $toField = $field;
            if (isset($fieldMap['to']) && $fieldMap['to']) {
                $toField = $fieldMap['to'];
            }

            $model->setData($toField, $value);
        }

        // SKU Lookup
        $lookupValue = $model->getData(Config::SKU_CONVERSION_LOOKUP_FIELD);
        if ($lookupValue) {
            $sku = $this->lookupSku($lookupValue);
            if ($sku) {
                $model->setData('sku', $sku);
            }
        }

        if (!$model->getData('magazzino')) {
            $stock_source = $this->getConfig('stock_source');
            if ($stock_source) {
                $model->setData('magazzino', $stock_source);
            } else {
                $model->setData('magazzino', 'default');
            }
        }

        $model->save();
    }

    /**
     * @param $needle
     * @return mixed|null
     */
    private function lookupSku($needle)
    {
        $attribute_code = $this->getConfig('sku_conversion_lookup');
        if ($attribute_code == Config::SKU_CONVERSION_LOOKUP_DISABLED || !$attribute_code) {
            return $needle;
        }

        $haystack = $this->getSkuConversionLookup();
        return $haystack[$needle] ?? $needle;
    }

    /**
     * @return array|null
     */
    public function getSkuConversionLookup()
    {

        if ($this->lookupConversion) {
            return $this->lookupConversion;
        }

        $attribute_code = $this->getConfig('sku_conversion_lookup');
        $catalog_product_type_id = 4;
        $sql = "SELECT CPEV.value AS 'lookup', CPE.sku FROM catalog_product_entity CPE
                LEFT JOIN catalog_product_entity_varchar CPEV ON CPE.row_id = CPEV.row_id AND CPEV.attribute_id IN (
                    SELECT attribute_id
                    FROM eav_attribute
                    WHERE attribute_code = '{$attribute_code}' AND entity_type_id = {$catalog_product_type_id}
                    )
                WHERE CPE.type_id IN ('simple','bundle','virtual')
                AND CPEV.value IS NOT NULL";
        $this->lookupConversion = $this->getConnection()->fetchPairs($sql);

        return $this->lookupConversion;
    }

    /**
     * @return \Magento\Framework\DB\Adapter\AdapterInterface
     */
    protected function getConnection()
    {
        if (!$this->connection) {
            $resource = $this->objectManager->create(ResourceConnection::class);
            $this->connection = $resource->getConnection('core_write');
        }
        return $this->connection;
    }
}
