<?php

declare(strict_types=1);

namespace FiloBlu\Refilo\Setup;


use Magento\Framework\DB\AggregatedFieldDataConverter;
use Magento\Framework\DB\FieldToConvert;
use Magento\Framework\DB\Select\QueryModifierFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\PageBuilder\Model\UpgradableEntitiesPool;

/**
 *
 */
class UpgradeContentHelper
{
    /**
     * @var ModuleDataSetupInterface $moduleDataSetup
     */
    private $moduleDataSetup;

    /**
     * @var QueryModifierFactory
     */
    private $queryModifierFactory;

    /**
     * @var UpgradableEntitiesPool
     */
    private $entitiesPool;

    /**
     * @var AggregatedFieldDataConverter
     */
    private $aggregatedFieldDataConverter;

    /**
     * UpgradeContentHelper constructor.
     *
     * @param ModuleDataSetupInterface $moduleDataSetup
     * @param QueryModifierFactory $queryModifierFactory
     * @param UpgradableEntitiesPool $entitiesPool
     * @param AggregatedFieldDataConverter $aggregatedFieldDataConverter
     */
    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        QueryModifierFactory $queryModifierFactory,
        UpgradableEntitiesPool $entitiesPool,
        AggregatedFieldDataConverter $aggregatedFieldDataConverter
    ) {
        $this->moduleDataSetup = $moduleDataSetup;
        $this->queryModifierFactory = $queryModifierFactory;
        $this->entitiesPool = $entitiesPool;
        $this->aggregatedFieldDataConverter = $aggregatedFieldDataConverter;
    }

    /**
     * Executes each specified converter against all upgradable fields in the database
     *
     * @param string $contentPattern '%data-content-type="%'
     * @param array $converters
     * @throws \Magento\Framework\DB\FieldDataConversionException
     */
    public function upgrade(string $contentPattern,array $converters): void
    {
        if (count($converters)) {
            $fields = [];

            foreach ($this->entitiesPool->getEntities() as $tableName => $tableInfo) {
                foreach ($tableInfo['fields'] as $fieldName => $upgradeField) {
                    if (!$upgradeField) {
                        continue;
                    }

                    $queryModifier = $this->queryModifierFactory->create(
                        'like',
                        [
                            'values' => [
                                $fieldName => $contentPattern
                            ]
                        ]
                    );

                    foreach ($converters as $converter) {
                        $fields[] = new FieldToConvert(
                            $converter,
                            $this->moduleDataSetup->getTable($tableName),
                            $tableInfo['identifier'],
                            $fieldName,
                            $queryModifier
                        );
                    }

                }
            }

            $this->aggregatedFieldDataConverter->convert($fields, $this->moduleDataSetup->getConnection());
        }
    }
}
