<?php
declare(strict_types=1);

namespace FiloBlu\Refilo\Remote;

use Exception;
use Magento\Framework\DataObject;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Store\Api\Data\StoreInterface;

/**
 * Class AbstractStoreBasedIndexer
 * @package FiloBlu\Refilo\Remote
 */
abstract class AbstractStoreBasedIndexer extends AbstractIndexer
{

    /**
     * @param array $ids
     * @return void
     * @throws NoSuchEntityException|LocalizedException
     */
    public function executeAction(array $ids)
    {
        // Profiler::start( __METHOD__);

        try {
            $indexTemplate = $this->getGetRemoteIndexTemplate();
        } catch (Exception $exception) {
            $this->logger->error($exception->getMessage(), ['exception' => $exception]);
            return;
        }

        $previousStore = $this->getStoreManager()->getStore();

        foreach ($this->getStoreManager()->getStores() as $store) {

            if (!$store->getIsActive() || !$this->getIndexerHelper()->hasProjectId($store)) {
                continue;
            }

            // Profiler::start( 'process ' . $store->getCode());

            $website = $this->getStoreManager()->getWebsite($store->getWebsiteId());

            $collection = $indexTemplate
                ->withValue('%s', $store->getCode())
                ->withValue('%p', $this->getIndexerHelper()->getProjectId($website))
                ->render();

            $this->getStoreManager()->setCurrentStore($store);

            if ($this->getIndexerHelper()->indexerCanDelete()) {
                $this->getConnector()->delete($this->getEntitiesToRemove($ids), $collection);
            }

            $arguments = $this->dataObjectFactory->create([
                'data' => [
                    self::ARGUMENT_COLLECTION => $collection
                ]
            ]);

            iterator_to_array(
                $this->entityProviderFactory->create()
                    ->forStore($store)
                    ->withIds($ids)
                    ->attachReaderHandler($this, $arguments)
            );

            // Profiler::stop( 'process ' . $store->getCode());

        }

        $this->getStoreManager()->setCurrentStore($previousStore);

        // Profiler::stop( __METHOD__);
    }

    /**
     * @param StoreInterface $store
     * @return DataObject
     * @throws LocalizedException
     */
    public function prepareConnectorMetadata(StoreInterface $store): DataObject
    {
        $metadata = parent::prepareConnectorMetadata($store);
        $metadata->setData('database', $this->getIndexerHelper()->getProjectId($store));
        return $metadata;
    }
}
