<?php

namespace App\DataFixtures;

use App\Entity\CarteFractal;
use App\Entity\User;
use App\Entity\ClasseurFractal;
use App\Entity\MembreFractal;
use App\Entity\CollectionFractal;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Persistence\ObjectManager;
use function Symfony\Component\Clock\now;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;

class AppFixtures extends Fixture implements DependentFixtureInterface
{
    public function getDependencies()
    {
        return [
            UserFixtures::class,
        ];
    }
    /**
     * Generates initialization data for ClasseurFractal,CarteFractal and MembreFractal
     * @return \\Generator
     */
    private static function classeurDataGenerator() {
        // ClasseurFractal : name
        yield ['FractalsDeClement'];
        yield ['FractalsDeMicheline'];
        yield ['FractalsDeBernard'];
    }
    private static function cartesGenerator() {
        // CarteFractal : type,desc,prix,classeurname
        yield ["Niveau 2","Mandelbrot",100,"FractalsDeMicheline"];
        yield ["Niveau 3","Sierpenski",200,"FractalsDeMicheline"];
        yield ["Niveau -1","Fractal",1000,"FractalsDeBernard"];
        yield ["Niveau 1","BuddhaBrot",10,"FractalsDeClement"];
    }
    public static function memberDataGenerator() {
        // MembreFractal : usermail,pseudo,classeurname
        yield ["clement@yahoo.fr","clement","FractalsDeClement"];
        yield ["bernard@yahoo.fr","bernard","FractalsDeBernard"];
        yield ["micheline@yahoo.fr","micheline","FractalsDeBernard"];
    }
    public static function collectionDataGenerator() {
        // CollectionFractal : name,[cartetypes],membrename,ispublic
        yield ["Des supers cartes fractales",["Niveau 1"],"clement",true];
        yield ["Des cartes fractales pas fou fou",["Niveau -1","Niveau 3"],"clement",false];
    }
    public function load(ObjectManager $manager){
        // Génération des classeurs
        foreach (self::classeurDataGenerator() as [$name]) {
            $classeur = new ClasseurFractal();
            $classeur->setName($name);
        // Ajout du classeur à la file d'attente d'ajout à la base de données
            $manager->persist($classeur);
        // Création d'une référence pour chaque classeur par leur nom. $this->getReferance($name) permettra par la suite de récupérer le classeur.
            $this->addReference($name,$classeur);
        }

        foreach (self::cartesGenerator() as [$type, $desc, $prix, $classeurname]) {
        // Récupération du classeur dans lequel sera entreposée la carte
            $classeur = $this->getReference($classeurname);
        // Génération des cartes
            $carte = new CarteFractal();
            $carte->setDescription($desc);
            $carte->setType($type);
            $carte->setPrix($prix);
            $carte->setDate(now());
        // Ajout de la carte au classeur
            $classeur->addCartesfractal($carte);
            $this->addReference($type,$carte);
        // Ajout de la carte à la file d'attente
            $manager->persist($carte);
        }

        foreach (self::memberDataGenerator() as [$usermail,$pseudo,$classeurname]) {
        // Génération des membres
            $membre = new MembreFractal();
            $membre->setPseudo($pseudo);
        // Lien MembreFractal<->User
            if ($usermail) {
                $user = $manager->getRepository(User::class)->findOneByEmail($usermail);
                $membre->setUser($user);
            }
        
        // Association d'un classeur au membre (ManyToOne)
            if ($classeurname != null) {
                $classeur = $this->getReference($classeurname);
                $classeurs = new ArrayCollection();
                $classeurs->add($classeur);
                $membre->setClasseursfractal($classeurs);
                $classeur->setMembreFractal($membre);
            }
        // Création d'une référence pour chaque membre par leur pseudo
            $this->addReference($pseudo,$membre);
        // Ajout du membre et mise à jour des classeurs dans la file d'attente
            $manager->persist($membre);
            $manager->persist($classeur);
        }

        foreach (self::collectionDataGenerator() as [$name,$cartenames,$membername,$ispublic]) {
        // Génération des collections
            $collection = new CollectionFractal();
            $collection->setName($name);
            $collection->setMembrefractal($this->getReference($membername));
            $collection->setIspublic($ispublic);
        // Ajout des cartes à la collection dans laquelle elles seront installées
            foreach ($cartenames as $cartename) {
                $collection->addCartesFractal($this->getReference($cartename));
            }
        // Ajout des collections à la file d'attente
            $manager->persist($collection);
        }
        // Traitement de la file d'attente et ajout à la base de données
        $manager->flush();
    }
}