<?php

declare(strict_types=1);

namespace FiloBlu\Refilo\Model\Exporter;

use FiloBlu\Core\Model\Configuration;
use FiloBlu\Refilo\Model\Adapter\Mongo;
use Generator;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\StoreManagerInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Class AbstractCmsExporter
 * @package FiloBlu\Refilo\Model\Exporter
 */
abstract class AbstractCmsExporter extends AbstractExporter
{

    /**
     * @var StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var array
     */
    private $databaseMap = [];

    /**
     * AbstractCmsExporter constructor.
     * @param Mongo $mongo
     * @param Configuration $coreConfiguration
     * @param ScopeConfigInterface $scopeConfig
     * @param StoreManagerInterface $storeManager
     */
    public function __construct(
        Mongo $mongo,
        Configuration $coreConfiguration,
        ScopeConfigInterface $scopeConfig,
        StoreManagerInterface $storeManager
    ) {
        parent::__construct($mongo, $coreConfiguration, $scopeConfig);
        $this->storeManager = $storeManager;
    }

    public function preExecute(OutputInterface $output = null)
    {
        if ($this->getCoreConfiguration()->isMultiDomain()) {
            foreach ($this->getCoreConfiguration()->getWebsiteMapping() as $map) {
                foreach ($map->getWebsiteCodes() as $websiteCode) {
                    $this->databaseMap[$websiteCode] = $map->getProjectId();
                }

                foreach ($this->getCollections() as $collection) {
                    $this->getConnection()->deleteDocumentsByProperties(
                        $map->getProjectId(),
                        $collection,
                        ['metacode' => $this->getMetaCode()]
                    );
                }
            }

            return;
        }

        foreach ($this->getCollections() as $collection) {
            $this->getConnection()->deleteDocumentsByProperties(
                $this->getDatabase(),
                $collection,
                ['metacode' => $this->getMetaCode()]
            );
        }

        foreach ($this->storeManager->getStores() as $value) {
            $this->databaseMap[$value->getWebsite()->getCode()] = $this->getDatabase();
        }
    }

    /**
     * @return Generator
     */
    public function getCollections(): iterable
    {
        foreach ($this->storeManager->getStores() as $store) {
            yield $this->getCollectionPrefix() . $store->getCode();
        }
    }

    abstract public function getCollectionPrefix(): string;

    abstract public function getMetaCode(): string;


    /**
     * @return StoreManagerInterface
     */
    public function getStoreManager(): StoreManagerInterface
    {
        return $this->storeManager;
    }

    /**
     * @param $code
     * @return mixed
     */
    public function getDatabaseByWebsiteCode($code)
    {
        return $this->databaseMap[$code] ?? null;
    }
}
