<?php

declare(strict_types=1);

namespace FiloBlu\Refilo\Console\Command;

use Exception;
use FiloBlu\Refilo\Model\LimitedStoreManagerFactory;
use FiloBlu\Refilo\Remote\AbstractIndexer;
use FiloBlu\Refilo\Remote\IndexerConfiguration\IndexerPool;
use Magento\Framework\App\Area;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\State;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Indexer\Model\IndexerFactory;
use Magento\Store\Model\StoreManagerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Class RatingIndex
 * @package FiloBlu\Refilo\Console\Command
 */
class RunIndexer extends Command
{
    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    private $storeManager;
    /**
     * @var \FiloBlu\Refilo\Model\LimitedStoreManagerFactory
     */
    private $limitedStoreManagerFactory;
    /**
     * @var \Magento\Framework\App\State
     */
    private $state;
    /**
     * @var IndexerPool
     */
    private $indexerPool;


    /**
     * @param \Magento\Framework\App\State $state
     * @param \Magento\Indexer\Model\IndexerFactory $indexerFactory
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \FiloBlu\Refilo\Model\LimitedStoreManagerFactory $limitedStoreManagerFactory
     * @param string|null $name
     */
    public function __construct(
        State                      $state,
        StoreManagerInterface      $storeManager,
        LimitedStoreManagerFactory $limitedStoreManagerFactory,
        IndexerPool                $indexerPool,
        string                     $name = null
    )
    {
        parent::__construct($name);
        $this->storeManager = $storeManager;
        $this->limitedStoreManagerFactory = $limitedStoreManagerFactory;
        $this->state = $state;
        $this->indexerPool = $indexerPool;
    }

    /**
     * @inheritDoc
     */
    protected function configure()
    {
        $this->setName('refilo:indexer:run');
        $this->addArgument('indexer', InputArgument::REQUIRED);
        $this->setDescription('Run Indexer');
        $this->addOption('store', 's', InputOption::VALUE_REQUIRED);
        $this->addOption('id', 'i', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY);
        parent::configure();
    }

    /**
     * Execute the command
     *
     * @param InputInterface $input
     * @param OutputInterface $output
     *
     * @return int
     * @throws NoSuchEntityException
     * @throws Exception
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->state->setAreaCode(Area::AREA_CRONTAB);

        $storeCode = $input->getOption('store');
        $id = $input->getOption('id');

        $arguments = [];
        if ($storeCode) {
            $store = $this->storeManager->getStore($storeCode);
            $this->storeManager->setCurrentStore($store);
            $limitedStoreManager = $this->limitedStoreManagerFactory->create();
            $limitedStoreManager->setAllowedStores([$store->getCode() => $store]);
            $arguments = [
                'storeManager' => $limitedStoreManager
            ];
        }

        $indexerId = $input->getArgument('indexer');

        if(!$this->indexerPool->has($indexerId)){
            $output->writeln("<error>{$input->getArgument('indexer')} is not a refilo indexer</error>");
            return 1;
        }

        $indexer = $this->indexerPool->get($input->getArgument('indexer'), $arguments);
        $indexer->executeList($id);

        return 0;
    }

}
