<?php

declare(strict_types=1);

namespace FiloBlu\Refilo\Setup;

use Exception;
use FiloBlu\Refilo\Helper\Data;
use FiloBlu\Refilo\Model\Importer\Translation;
use FiloBlu\Refilo\Remote\IndexerConfiguration\IndexerConfigurationInterface;
use FiloBlu\Refilo\Remote\IndexerConfiguration\IndexerConfigurationInterfaceFactory;
use FiloBlu\Refilo\Remote\IndexerConfiguration\IndexerConfigurationRepository;
use FiloBlu\Refilo\Remote\IndexerConfiguration\IndexerResolver;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Psr\Log\LoggerInterface;

/**
 * Class RecurringData
 * @author Stefano Pallozzi <stefano.pallozzi@filoblu.com>
 * @package Vendor\Module\Setup
 */
class RecurringData implements InstallDataInterface
{
    /**
     * @var IndexerConfigurationRepository
     */
    private $indexerConfigurationRepository;
    /**
     * @var SearchCriteriaBuilder
     */
    private $searchCriteriaBuilder;
    /**
     * @var IndexerConfigurationInterfaceFactory
     */
    private $indexerConfigurationFactory;
    /**
     * @var IndexerResolver
     */
    private $indexerResolver;
    /**
     * @var Translation
     */
    private $translation;
    /**
     * @var array
     */
    private $defaultRemoteIndex;
    /**
     * @var Data
     */
    private $helperData;
    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * RecurringData constructor.
     * @param IndexerResolver $indexerResolver
     * @param IndexerConfigurationInterfaceFactory $indexerConfigurationFactory
     * @param SearchCriteriaBuilder $searchCriteriaBuilder
     * @param IndexerConfigurationRepository $indexerConfigurationRepository
     * @param TranslationsFactory $translationsFactory
     * @param Translation $translation
     * @param array $defaultRemoteIndex
     */
    public function __construct(
        IndexerResolver                      $indexerResolver,
        IndexerConfigurationInterfaceFactory $indexerConfigurationFactory,
        SearchCriteriaBuilder                $searchCriteriaBuilder,
        IndexerConfigurationRepository       $indexerConfigurationRepository,
        Translation                          $translation,
        Data                                 $helperData,
        LoggerInterface                      $logger,
        array                                $defaultRemoteIndex
    )
    {
        $this->indexerConfigurationRepository = $indexerConfigurationRepository;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
        $this->indexerConfigurationFactory = $indexerConfigurationFactory;
        $this->indexerResolver = $indexerResolver;
        $this->defaultRemoteIndex = $defaultRemoteIndex;
        $this->translation = $translation;
        $this->helperData = $helperData;
        $this->logger = $logger;
    }

    /**
     * @param ModuleDataSetupInterface $setup
     * @param ModuleContextInterface $context
     */
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $this->updateIndexer();
        $this->updateCountryTranslations();
    }

    /**
     * @return void
     */
    public function updateIndexer()
    {
        $defaultRemoteIndexIds = array_keys($this->defaultRemoteIndex);

        $searchCriteria = $this->searchCriteriaBuilder->create();

        $result = $this->indexerConfigurationRepository->getList($searchCriteria);

        $indexerIds = array_unique(array_merge($this->indexerResolver->getIndexerIds(), $defaultRemoteIndexIds));
        $existing = [];

        /** @var IndexerConfigurationInterface $indexerConfiguration */
        foreach ($result->getItems() as $indexerConfiguration) {
            $existing[] = $indexerConfiguration->getIndexerId();
        }

        $indexerToCreate = array_diff($indexerIds, $existing);

        foreach ($indexerToCreate as $indexerId) {
            $indexerConfiguration = $this->indexerConfigurationFactory->create();
            $indexerConfiguration->setIndexerId($indexerId);
            $this->indexerConfigurationRepository->save($indexerConfiguration);
        }

        $result = $this->indexerConfigurationRepository->getList($searchCriteria);

        /** @var IndexerConfigurationInterface $indexerConfiguration */
        foreach ($result->getItems() as $indexerConfiguration) {
            if ($indexerConfiguration->getIndexName()) {
                continue;
            }

            if (!isset($this->defaultRemoteIndex[$indexerConfiguration->getIndexerId()])) {
                continue;
            }

            $indexerConfiguration->setIndexName($this->defaultRemoteIndex[$indexerConfiguration->getIndexerId()]);
            $this->indexerConfigurationRepository->save($indexerConfiguration);
        }
    }

    /**
     * @return void
     */
    public function updateCountryTranslations()
    {
        foreach ($this->helperData->getLocales() as $locale) {
            try {
                $this->translation->importFromFileOnly($locale);
            } catch (Exception $e) {
                $this->logger->critical($e->getMessage());
            }
        }
    }
}
