<?php declare(strict_types=1);

namespace Newland\Toubiz\Sync\Neos\Command\MigrationPair;

use Doctrine\ORM\Query;
use Newland\Toubiz\Sync\Neos\Domain\Repository\CategoryRepository;
use Neos\Flow\Annotations as Flow;
use Symfony\Component\Console\Output\OutputInterface;

class CategoryPairs extends MigrationPairFinder
{

    /**
     * @var CategoryRepository
     * @Flow\Inject()
     */
    protected $categoryRepository;

    /** @var array<string, string> */
    protected $originalIdPairs;

    public function __construct(OutputInterface $output, string $path)
    {
        parent::__construct($output, '', '');
        $this->originalIdPairs = json_decode(file_get_contents($path), true);
    }

    public function findMigrationPairs(string $language, array $idsToIgnore): \Generator
    {
        $pairs = [ ];

        $message = sprintf('[%s] Fixed category mapping', $language);
        foreach ($this->loopWithBar($this->originalIdPairs, $message) as $oldOriginalId => $newOriginalId) {
            if (!is_string($newOriginalId) || strpos($newOriginalId, '!!unmapped!!') === 0) {
                continue;
            }

            $oldUid = $this->categoryUid($oldOriginalId, $language);
            $newUid = $this->categoryUid($newOriginalId, $language);
            if ($oldUid && $newUid) {
                yield $oldUid => $newUid;
            }
        }

        return $pairs;
    }


    private function categoryUid(string $originalId, string $language): ?string
    {
        return $this->categoryRepository->withLanguage($language, function () use ($originalId) {
            $query = $this->categoryRepository
                ->createQueryBuilder('category')
                ->select('category.Persistence_Object_Identifier AS uid')
                ->setMaxResults(1);

            $query->where($query->expr()->eq('category.originalId', ':originalId'));

            return $query->getQuery()->execute(
                compact('originalId'),
                Query::HYDRATE_ARRAY
            )[0]['uid'] ?? null;
        });
    }
}
