<?php

declare(strict_types=1);

namespace FiloBlu\Refilo\Model\Exporter;

use FiloBlu\Core\Model\Configuration;
use FiloBlu\Refilo\Model\Adapter\Mongo;
use Magento\Framework\App\Config\ScopeConfigInterface;
use MongoDB\Driver\Exception\Exception;
use Symfony\Component\Console\Output\OutputInterface;


use Magento\Search\Api\Data\SynonymGroupInterface;
use Magento\Search\Model\ResourceModel\SynonymGroup\Collection;
use Magento\Search\Model\ResourceModel\SynonymGroup\CollectionFactory;
use Magento\Store\Model\StoreManagerInterface;

/**
 *
 */
class Synonyms extends AbstractExporter
{
    /**
     * @var \Magento\Search\Model\ResourceModel\SynonymGroup\CollectionFactory
     */
    private $synonymsCollectionFactory;

    /**
     * @var array|null
     */
    private $databaseMap;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    private $storeManager;

    /**
     * @param \FiloBlu\Refilo\Model\Adapter\Mongo $mongo
     * @param \FiloBlu\Core\Model\Configuration $coreConfiguration
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\Search\Model\ResourceModel\SynonymGroup\CollectionFactory $synonymsCollectionFactory
     */
    public function __construct(
        Mongo $mongo,
        Configuration $coreConfiguration,
        ScopeConfigInterface $scopeConfig,
        StoreManagerInterface $storeManager,
        CollectionFactory $synonymsCollectionFactory

    ) {
        parent::__construct($mongo, $coreConfiguration, $scopeConfig);
        $this->synonymsCollectionFactory = $synonymsCollectionFactory;
        $this->storeManager = $storeManager;
    }

    /**
     * @return iterable
     */
    public function getCollections(): iterable
    {
        yield 'synonyms';
    }

    /**
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getDatabaseByStore($storeId)
    {

        if ($this->databaseMap === null) {
            $isMultiDomain = $this->getCoreConfiguration()->isMultiDomain();

            if (!$isMultiDomain) {
                foreach ($this->storeManager->getStores() as $value) {
                    $this->databaseMap[(int)$value->getStoreId()] = $this->getDatabase();
                }
            } else {
                foreach ($this->getCoreConfiguration()->getWebsiteMapping() as $map) {
                    foreach ($map->getStoreIds() as $id) {
                        $this->databaseMap[(int)$id] = $map->getProjectId();
                    }
                }
            }
        }

        return $this->databaseMap[$storeId];
    }

    /**
     * @param OutputInterface|null $output
     * @return void
     */
    public function execute(OutputInterface $output = null)
    {
        /** @var Collection $collection */
        $collection = $this->synonymsCollectionFactory->create();

        /** @var SynonymGroupInterface $group */
        foreach ($collection->getItems() as $group) {
            $this->write($group);
        }
    }

    public function write(SynonymGroupInterface $group)
    {
        try {

            if((int)$group->getStoreId() === 0){
                foreach ($this->storeManager->getStores() as $store){

                    $bulkData = [
                        '_id' =>  $store->getCode() . '_' . $group->getId(),
                        'synonyms' =>  explode(',', $group->getSynonymGroup()??'') ?? [],
                        'store' => $store->getCode()
                    ];
                    $this->getConnection()->update(
                        '_id',
                       [ $bulkData],
                        'synonyms',
                        true,
                        $this->getDatabaseByStore($store->getStoreId())

                    );
                }
                return;
            }

            $this->getConnection()->update(
                '_id',
                [[
                    '_id' => $group->getId(),
                    'synonyms' =>  explode(',', $group->getSynonymGroup()??'') ?? [],
                    'store' => $this->storeManager->getStore($group->getStoreId())->getCode()
                ]],
                'synonyms',
                true,
                $this->getDatabaseByStore($group->getStoreId())

            );
        } catch (Exception $e) {
            echo $e->getMessage();
        }
    }

}
