<?php

namespace Myvetshop\Module\Clinique\Cron;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\ResultSetMapping;
use Symfony\Component\Console\Output\OutputInterface;

class CategoryGroupAssociationCronTask implements CronTaskInterface
{
    private EntityManagerInterface $entityManager;

    public function __construct(
        EntityManagerInterface $entityManager
    ) {
        $this->entityManager = $entityManager;
    }

    public function run(OutputInterface $output): void
    {
        /** @var string|false $menuCategories */
        $menuCategories = \Configuration::get('MOD_BLOCKTOPMENU_ITEMS');

        if (!\is_string($menuCategories)) {
            return;
        }

        /** @var list<int> $menuCatIds */
        $menuCatIds = \array_values(
            \array_filter(
                \array_map(
                    fn (string $cat) => \intval(\trim(\substr($cat, 3))),
                    \array_filter(
                        \explode(',', $menuCategories),
                        fn (string $cat): bool => \strpos($cat, 'CAT') === 0
                    )
                ),
                fn (int $catId) => $catId > 0,
            )
        );

        $categories = $this->findAllChildCategories($menuCatIds);

        foreach ($categories as $cat) {
            $this->entityManager->getConnection()
                ->executeUpdate(
                    'INSERT IGNORE INTO ps_category_group (id_category, id_group)'
                    . ' SELECT :catid, id_group FROM ps_myvetshop_clinique WHERE deleted = 0',
                    [
                        'catid' => $cat,
                    ]
                );
        }
    }

    /**
     * @param list<int> $menuCatIds
     *
     * @return list<int>
     */
    private function findAllChildCategories(array $menuCatIds): array
    {
        $rsm = new ResultSetMapping();
        $rsm->addScalarResult('id_category', 'id_category');

        /** @var list<array{id_category: int}> $rows */
        $rows = $this->entityManager
            ->createNativeQuery(
                'SELECT c.id_category FROM ps_category c'
                . ' WHERE c.id_parent IN (:ids)',
                $rsm,
            )
            ->setParameter('ids', $menuCatIds)
            ->getResult();

        /** @var list<int> $childIds */
        $childIds = \array_column($rows, 'id_category');

        if (\count($childIds) > 0) {
            $childIds = \array_merge($childIds, $this->findAllChildCategories($childIds));
        }

        return \array_merge($menuCatIds, $childIds);
    }
}
