<?php

namespace App\Repository;

use App\Entity\Mod;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
 * @extends ServiceEntityRepository<Mod>
 */
class ModRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Mod::class);
    }

    /**
     * Retourne tous les mods qui ne sont pas une dépendance (directe ou indirecte)
     * du mod passé en paramètre, et qui n'est pas le mod lui-même.
     */
    public function findAvailableDependances(Mod $mod): array
    {
        $excludedIds = $this->collectDependencyIds($mod, []);
        $excludedIds[] = $mod->getId();

        $qb = $this->createQueryBuilder('m');

        if (!empty($excludedIds)) {
            $qb->where('m.id NOT IN (:excludedIds)')
                ->setParameter('excludedIds', $excludedIds);
        }

        return $qb->getQuery()->getResult();
    }

    /**
     * Collecte récursivement les IDs de toutes les dépendances d'un mod.
     *
     * @param int[] $visited IDs déjà visités (évite les cycles infinis)
     * @return int[]
     */
    private function collectDependencyIds(Mod $mod, array $visited): array
    {
        $ids = [];

        foreach ($mod->getDependances() as $dependance) {
            $depId = $dependance->getId();

            // Evite les boucles infinies en cas de dépendances cycliques
            if (in_array($depId, $visited, true)) {
                continue;
            }

            $visited[] = $depId;
            $ids[]     = $depId;
            $ids       = array_merge($ids, $this->collectDependencyIds($dependance, $visited));
        }

        return $ids;
    }


    //    /**
    //     * @return Mod[] Returns an array of Mod objects
    //     */
    //    public function findByExampleField($value): array
    //    {
    //        return $this->createQueryBuilder('m')
    //            ->andWhere('m.exampleField = :val')
    //            ->setParameter('val', $value)
    //            ->orderBy('m.id', 'ASC')
    //            ->setMaxResults(10)
    //            ->getQuery()
    //            ->getResult()
    //        ;
    //    }

    //    public function findOneBySomeField($value): ?Mod
    //    {
    //        return $this->createQueryBuilder('m')
    //            ->andWhere('m.exampleField = :val')
    //            ->setParameter('val', $value)
    //            ->getQuery()
    //            ->getOneOrNullResult()
    //        ;
    //    }
}
