<?php

namespace Leadlion\StockUpdates\Cron;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\InventoryApi\Api\Data\SourceItemInterfaceFactory;
use Magento\InventoryApi\Api\SourceItemsSaveInterface;
use Magento\CatalogInventory\Api\StockRegistryInterface;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Catalog\Model\Product\Action;
use Magento\Inventory\Model\SourceItem\Command\Handler\SourceItemsSaveHandler;
use Magento\InventoryCatalog\Model\ResourceModel\SetDataToLegacyStockItem;
use Magento\Framework\App\ResourceConnection;
use Magento\InventoryCatalog\Model\ResourceModel\SetDataToLegacyStockStatus;
use Psr\Log\LoggerInterface;
use Monolog\Logger as MonoLogger;
use Monolog\Handler\StreamHandler;
use Monolog\Level;

class PtcLaComanda
{
    const JOB_ID = 54181;

    /**
     * @var ResourceConnection
     */
    private $resourceConnection;

    /**
     * @var ScopeConfigInterface|Config
     */
    protected $config;
    /**
     * @var LoggerInterface
     */
    protected $logger;
    /**
     * @var CollectionFactory
     */
    protected $collectionFactory;
    /**
     * @var \Magento\InventoryApi\Api\SourceItemsSaveInterface
     */
    private $sourceItemsSaveInterface;
    /**
     * @var SourceItemInterfaceFactory
     */
    private $sourceItemFactory;
    /**
     * @var ProductRepositoryInterface
     */
    private $productRepository;
    /**
     * @var Context
     */
    private $context;

    /**
     * @var StockRegistryInterface
     */
    protected $stockRegistry;

    /**
     * @var Json
     */
    protected $serialize;

    /**
     * @var Action
     */
    private $productAction;
    
    /**
     * @var SourceItemsSaveHandler
     */
    private $sourceItemsSaveHandler;

    /**
     * @var SetDataToLegacyStockItem
     */
    private $setDataToLegacyStockItem;
    
    /**
     * @var SetDataToLegacyStockStatus
     */
    private $setDataToLegacyStockStatus;

    /**
     * ProcessProducts constructor.
     * @param State $state
     * @param Config $config
     * @param Handler $handler
     * @param CollectionFactory $collectionFactory
     */
    public function __construct(
        ScopeConfigInterface       $config,
        CollectionFactory          $collectionFactory,
        SourceItemsSaveInterface   $sourceItemsSaveInterface,
        SourceItemInterfaceFactory $sourceItemFactory,
        ProductRepositoryInterface $productRepository,
        Context                    $context,
        StockRegistryInterface     $stockRegistry,
        Json $serialize,
        Action $productAction,
        SourceItemsSaveHandler $sourceItemsSaveHandler,
        SetDataToLegacyStockItem $setDataToLegacyStockItem,
        ResourceConnection $resourceConnection,
        SetDataToLegacyStockStatus $setDataToLegacyStockStatus,
        LoggerInterface $logger
    ) {
        $this->config = $config;
        $this->collectionFactory = $collectionFactory;
        $this->sourceItemsSaveInterface = $sourceItemsSaveInterface;
        $this->sourceItemFactory = $sourceItemFactory;
        $this->productRepository = $productRepository;
        $this->context = $context;
        $this->stockRegistry = $stockRegistry;
        $this->serialize = $serialize;
        $this->productAction = $productAction;
        $this->sourceItemsSaveHandler = $sourceItemsSaveHandler;
        $this->setDataToLegacyStockItem = $setDataToLegacyStockItem;
        $this->resourceConnection = $resourceConnection;
        $this->setDataToLegacyStockStatus = $setDataToLegacyStockStatus;

        $monolog = new MonoLogger('ptccomanda');
        $monolog->pushHandler(new StreamHandler(BP . '/var/log/ptc_la_comanda.log', Level::Debug));
        $this->logger = $monolog;
    }

    public function execute()
    {
        $sourceItems = [];

        $importedSkus = $this->getImportedSkus(self::JOB_ID);
        $importedSkusSku = [];
        foreach ($importedSkus as $key => $info) {
            $importedSkusSku[$info['sku']] = $info['sku'];
        }

        //return all products by sku_fz
        $collection = $this->collectionFactory->create()
            ->addAttributeToSelect('sku_fz')
            ->addAttributeToSelect('sku')
            ->addAttributeToFilter('attribute_set_id', ['in' => [60, 64]]);

        foreach ($collection as $product) {
            if (!isset($importedSkusSku[$product->getSkuFz()])) {
                $sku = $product->getSku();
                $qty = 0;

                $this->logger->info('PTC $item: '.$sku);
                $this->logger->info('La comanda sku: ' .$product->getData('sku').' sku_fz: '. $product->getData('sku_fz'). ' qty: '. $qty);

                $isInStock = 1;

                $sourceItem = $this->sourceItemFactory->create();
                $sourceItem->setData('source_code', 'default');
                $sourceItem->setData('sku', $product->getData('sku'));
                $sourceItem->setData('quantity', $qty);
                $sourceItem->setData('status', $isInStock);
                $sourceItems[] = $sourceItem;
                
                try {
                    $this->setDataToLegacyStockItem->execute(
                        (string)$product->getData('sku'),
                        (float)$qty,
                        $isInStock
                    );
                    $this->setDataToLegacyStockStatus->execute(
                        (string)$product->getData('sku'),
                        (float)$qty,
                        $isInStock
                    );
                } catch (\Exception $e) {
                    $this->logger->info('(stockRegistry) cant save stock $product sku: ' .$product->getData('sku').$e->getMessage());
                }
            }
        }

        if (!empty($sourceItems)) {
            $this->sourceItemsSaveHandler->execute($sourceItems);
        }

        $this->logger->info('Done');
    }

    private function getImportedSkus($jobId)
    {
        $connection = $this->resourceConnection->getConnection();
        $oosProdTable = $this->resourceConnection->getTableName('leadlion_imported_skus');

        $select = $connection->select();
        $select->from(
            ['e' => $oosProdTable],
            ['id', 'job_id', 'sku','qty']
        )->where(
            'e.job_id = ?',
            $jobId
        );
        return $connection->fetchAll($select);
    }
}
