<?php

namespace App\Controller;

use App\Entity\Adherent;
use App\Entity\Comptoir;
use App\Entity\ContactComptoir;
use App\Entity\ContactPrestataire;
use App\Entity\CotisationAdherent;
use App\Entity\CotisationPrestataire;
use App\Entity\EtatPrestataire;
use App\Entity\Geoloc;
use App\Entity\GeolocPrestataire;
use App\Entity\Groupe;
use App\Entity\Import;
use App\Entity\Prestataire;
use App\Entity\Rubrique;
use App\Entity\Siege;
use App\Entity\TypePrestataire;
use App\Entity\User;
use App\Entity\Usergroup;
use App\Enum\CurrencyEnum;
use App\Enum\FluxEnum;
use App\Enum\ImportEnum;
use App\Enum\MoyenEnum;
use App\Events\MLCEvents;
use App\Form\Type\ImportFormType;
use App\Utils\CustomEntityManager;
use App\Utils\OperationUtils;
use Behat\Transliterator\Transliterator;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use FOS\UserBundle\Event\UserEvent;
use FOS\UserBundle\Model\UserManagerInterface;
use FOS\UserBundle\Util\TokenGeneratorInterface;
use Sonata\AdminBundle\Controller\CRUDController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Translation\TranslatorInterface;

class ImportController extends CRUDController
{
    protected $header;
    protected $warnings;
    protected $errors;
    protected $nberrors;
    protected $nbsuccess;
    protected $success;
    protected $lineErrors;
    protected $em;
    protected $file;
    protected $security;
    protected $userManager;
    protected $translator;
    protected $tokenGenerator;
    protected $operationUtils;
    protected $test;

    public function __construct(CustomEntityManager $em, Security $security, UserManagerInterface $userManager, TranslatorInterface $translator, TokenGeneratorInterface $tokenGenerator, EventDispatcherInterface $eventDispatcher, OperationUtils $operationUtils)
    {
        $this->header = null;
        $this->warnings = [];
        $this->errors = [];
        $this->nberrors = 0;
        $this->nbsuccess = 0;
        $this->lineErrors = [];
        $this->em = $em;
        $this->security = $security;
        $this->userManager = $userManager;
        $this->translator = $translator;
        $this->tokenGenerator = $tokenGenerator;
        $this->eventDispatcher = $eventDispatcher;
        $this->operationUtils = $operationUtils;
        $this->sendemail = false;
        $this->test = false;
    }

    public function createAction()
    {
        $import = new Import();
        $userLogguedIn = $this->em->merge($this->getUser());
        $import->setUser($userLogguedIn);
        $form = $this->createForm(ImportFormType::class, $import);
        $form->handleRequest($this->getRequest());

        if ($form->isSubmitted() && $form->isValid()) {
            $this->em->getConnection()->getConfiguration()->setSQLLogger(null);
            gc_collect_cycles();
            $import = $form->getData();
            $media = $import->getMedia();
            $type = $import->getType();
            $this->sendemail = (bool) $import->getSendemail();
            $this->test = (bool) $import->getTest();

            // $this->em->getConnection()->beginTransaction(); // suspend auto-commit
            try {
                // Sauvegarder l'import en base de données avant l'essai d'import
                $this->em->persist($import);
                $this->em->flush();
                $idimport = $import->getId();

                $this->importFromCSV($type, $media);

                $import = $this->em->getRepository(Import::class)->findOneById($idimport);
                $import->setEnabled(true);

                $import->setSuccess(json_encode($this->success));
                $import->setWarnings(json_encode($this->warnings));
                $import->setErrors(json_encode($this->errors));
                $import->setNbentityadded($this->nbsuccess);
                $import->setNbentityerror($this->nberrors);
                $this->em->persist($import);
                $this->em->flush();

                // $this->em->getConnection()->commit(); // commit all !

                if (empty($this->errors)) {
                    if ($this->test) {
                        $this->addFlash(
                            'success',
                            '(TEST) Import effectué avec succès !'
                        );
                    } else {
                        $this->addFlash(
                            'success',
                            'Import effectué avec succès !'
                        );
                    }
                } else {
                    $this->addFlash(
                        'error',
                        "Il y a eu des erreurs lors de l'import !"
                    );
                }
            } catch (Exception $e) {
                // $this->em->getConnection()->rollBack(); // Rollback all previous commit !
                $this->addFlash(
                    'error',
                    "Il y a eu une erreur lors de l'import : " . $e->getMessage()
                );
            }

            return $this->redirect($this->admin->generateUrl('show', ['id' => $import->getId()]));
        }

        return $this->renderWithExtraParams('@kohinos/admin/import.html.twig', [
            'action' => 'list',
            'form' => $form->createView(),
            'errors' => $this->errors,
            'warnings' => $this->warnings,
            'success' => $this->success,
            'linkcsverror' => (count($this->lineErrors) > 0) ? $this->generateUrl('getcsv', ['header' => $this->header, 'data' => array_values($this->lineErrors)]) : null,
            'csvparams' => $this->getParameter('app.import.header'),
        ]);
    }

    private function importFromCSV($type, $media)
    {
        // Turning off doctrine default logs queries for saving memory
        $this->em->getConnection()->getConfiguration()->setSQLLogger(null);

        // Get file provider
        $provider = $this->container->get($media->getProviderName());

        $csvRows = $this->parseCSV($provider->getFilesystem()->getAdapter()->getDirectory(), $provider->getReferenceImage($media));
        if (!mb_detect_encoding(implode(';', $csvRows[1]), 'UTF-8', true)) {
            $this->errors['error'] = $this->translator->trans("Le fichier n'est pas encodé en UTF-8 !");

            return [];
        }
        $this->header = implode(';', array_values($csvRows[0]));

        $config = $this->getParameter('app.import.header');

        $result = null;
        if (ImportEnum::IMPORT_ADHERENT == $type) {
            $result = $this->importAdherent($csvRows);
        } elseif (ImportEnum::IMPORT_PRESTATAIRE == $type) {
            $result = $this->importPrestataire($csvRows);
        } elseif (ImportEnum::IMPORT_GROUPE == $type) {
            $result = $this->importGroupe($csvRows);
        } elseif (ImportEnum::IMPORT_COMPTOIR == $type) {
            $result = $this->importComptoir($csvRows);
        } elseif (ImportEnum::IMPORT_OPERATION == $type) {
            $result = $this->importOperations($csvRows);
        } else {
            // Ne devrait jamais arriver, mais sait-on jamais !
            $this->errors['error'] = $this->translator->trans('Choisir un type de données à importer !');
        }

        return $result;
    }

    /**
     * Open and parse .CSV file.
     *
     * @param string $filePath        Path of the file
     * @param string $fileName        Name of the file
     * @param bool   $ignoreFirstLine If true, ignore first line
     *
     * @return array Array of parsed values with array's key = firstline
     */
    private function parseCSV($filePath, $fileName, $ignoreFirstLine = false)
    {
        $csv = new \SplFileObject($filePath . '/' . $fileName);

        $rows = [];
        $firstline = null;
        if (($handle = fopen($csv->getRealPath(), 'r')) !== false) {
            $i = 0;
            while (($data = fgetcsv($handle, null, ';')) !== false) {
                ++$i;
                if (1 == $i) {
                    $firstline = $data;
                    $rows[] = $data;
                    if ($ignoreFirstLine) {
                        continue;
                    }
                } else {
                    if (count($firstline) != count($data)) {
                        $this->addError($data, $i, 'Ligne entière', $this->translator->trans("La ligne ne contient pas le bon nombre d'éléments requis !"));
                        ++$this->nberrors;
                        continue;
                    }
                    $rows[] = array_combine(array_values($firstline), array_values($data));
                }
            }
            fclose($handle);
        }

        return $rows;
    }

    private function importComptoir($csvRows)
    {
        // Iterate over the reader and write each row to the database
        //idmlc;groupe;nom;description;adresse;cpostal;ville;latitude;longitude;compte;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1;contact1;phone1;email1;contact2;phone2;email2
        $line = 1;
        foreach ($csvRows as $row) {
            if (1 == $line) {
                ++$line;
                continue;
            }
            if (!(array_key_exists('groupe', $row) && array_key_exists('nom', $row))) {
                $this->addError($row, $line, 'nom & groupe', $this->translator->trans("Les colonnes 'nom' et 'groupe' sont obligatoires !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }

            $groupe = array_key_exists('groupe', $row) ? $row['groupe'] : '';
            $nom = array_key_exists('nom', $row) ? $row['nom'] : '';
            if (empty($groupe)) {
                $this->addError($row, $line, 'groupe', $this->translator->trans("Le 'groupe' est obligatoire !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            if (empty($nom)) {
                $this->addError($row, $line, 'nom', $this->translator->trans("Le 'nom' est obligatoire !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            $idmlc = array_key_exists('idmlc', $row) ? $row['idmlc'] : '';
            $description = array_key_exists('description', $row) ? $row['description'] : '';
            $adresse = array_key_exists('adresse', $row) ? $row['adresse'] : '';
            $cpostal = array_key_exists('cpostal', $row) ? $row['cpostal'] : '';
            $ville = array_key_exists('ville', $row) ? $row['ville'] : '';
            $latitude = array_key_exists('latitude', $row) ? $row['latitude'] : '';
            $longitude = array_key_exists('longitude', $row) ? $row['longitude'] : '';
            $compte = array_key_exists('compte', $row) ? $row['compte'] : '';

            $groupeFound = $this->em->getRepository(Groupe::class)->findOneBy(['slug' => $this->slugify($groupe)]);
            if (empty($groupeFound)) {
                $groupeFound = new Groupe();
                $groupeFound->setName($groupe);
                $groupeFound->setSiege($this->em->getRepository(Siege::class)->getTheOne());
                if (!$this->test) {
                    $this->em->persist($groupeFound);
                }
                $this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ') . $groupe);
            }
            $comptoir = $this->em->getRepository(Comptoir::class)->findOneBy(['slug' => $this->slugify($nom), 'groupe' => $groupeFound]);
            if (empty($comptoir)) {
                $comptoir = new Comptoir();
                $comptoir->setIdmlc($idmlc);
                $comptoir->setGroupe($groupeFound);
                $comptoir->setName($nom);
                if (!empty($description)) {
                    $comptoir->setContent($description);
                } else {
                    $this->addWarning($row, $line, 'description', 'empty');
                }
                if (!empty($compte)) {
                    $comptoir->setCompte($this->tofloat($compte));
                } else {
                    $this->addWarning($row, $line, 'compte', 'empty');
                }
                if (!empty($adresse) || !empty($cpostal) || !empty($ville)) {
                    $geolocFound = new Geoloc();
                    $geolocFound->setAdresse($adresse);
                    $geolocFound->setCpostal($cpostal);
                    $geolocFound->setVille($ville);
                    if (!empty($latitude) && !empty($longitude)) {
                        $geolocFound->setLat(floatval(str_replace(',', '.', $latitude)));
                        $geolocFound->setLon(floatval(str_replace(',', '.', $longitude)));
                    }
                    $comptoir->setGeoloc($geolocFound);
                }
                // Importer les contacts du comptoir s'ils existent (par défaut en public)
                $cptContact = 1;
                while (array_key_exists('contact' . $cptContact, $row) && $cptContact < 10) {
                    $contact = array_key_exists('contact' . $cptContact, $row) ? $row['contact' . $cptContact] : '';
                    $phone = array_key_exists('phone' . $cptContact, $row) ? $row['phone' . $cptContact] : '';
                    $email = array_key_exists('email' . $cptContact, $row) ? $row['email' . $cptContact] : '';
                    if (!empty(trim($contact))) {
                        $contactC = $this->em->getRepository(ContactComptoir::class)->findOneBy(['comptoir' => $comptoir, 'name' => $contact]);
                        if (empty($contactComptoir)) {
                            $contactC = new ContactComptoir();
                        }
                        $contactC->setComptoir($comptoir);
                        $contactC->setEnabled(true);
                        $contactC->setName($contact);
                        $contactC->setTel($phone);
                        $contactC->setEmail($email);
                        if (!$this->test) {
                            $this->em->persist($contactC);
                        }
                        $this->addSuccess($row, $line, 'contact', $this->translator->trans('Contact ajouté : ') . $contactC);
                    } else {
                        break;
                    }
                    ++$cptContact;
                }

                // Importer les gestionnaires de comptoir s'ils existent
                $groupeGestionnaire = $this->em->getRepository(Usergroup::class)->findOneByName('Comptoir');
                $gestionnaires = $this->importGestionnaires($row, $line, $groupeGestionnaire);
                $comptoir->setGestionnaires($gestionnaires);

                $this->addSuccess($row, $line, 'comptoir', $this->translator->trans('Comptoir ajouté : ') . $nom);
                ++$this->nbsuccess;
                if (!$this->test) {
                    $this->em->persist($comptoir);
                    $this->em->flush();
                    // $this->em->clear();
                }
            } else {
                $this->addError($row, $line, 'nom', $this->translator->trans('Le comptoir avec ce nom {name} existe déjà !', ['name' => $nom]));
                ++$this->nberrors;
            }

            ++$line;
        }
        ksort($this->errors);
        ksort($this->warnings);
    }

    private function importGroupe($csvRows)
    {
        // Iterate over the reader and write each row to the database
        // idmlc;nom;description;compte;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1
        $line = 1;
        foreach ($csvRows as $row) {
            if (1 == $line) {
                ++$line;
                continue;
            }
            $name = array_key_exists('nom', $row) ? $row['nom'] : '';
            if (empty($name)) {
                $this->addError($row, $line, 'nom', $this->translator->trans("Le 'nom' est obligatoire !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            $idmlc = array_key_exists('idmlc', $row) ? $row['idmlc'] : '';
            $description = array_key_exists('description', $row) ? $row['description'] : '';
            $compte = array_key_exists('compte', $row) ? $row['compte'] : '';
            $groupe = null;
            if (!empty($idmlc)) {
                $groupe = $this->em->getRepository(Groupe::class)->findOneBy(['idmlc' => $idmlc]);
            }
            if (empty($groupe)) {
                $groupe = $this->em->getRepository(Groupe::class)->findOneBy(['slug' => $this->slugify($name)]);
            }
            if (empty($groupe)) {
                $groupe = new Groupe();
                $groupe->setIdmlc($idmlc);
                $groupe->setSiege($this->em->getRepository(Siege::class)->getTheOne());
                if (!empty($name)) {
                    $groupe->setName($name);
                } else {
                    $this->addWarning($row, $line, 'name', 'empty');
                }
                if (!empty($content)) {
                    $groupe->setContent($content);
                } else {
                    $this->addWarning($row, $line, 'content', 'empty');
                }
                if (!empty($compte)) {
                    $groupe->setCompte($this->tofloat($compte));
                } else {
                    $this->addWarning($row, $line, 'compte', 'empty');
                }
                // Importer les gestionnaires du groupe s'ils existent
                $groupeGestionnaire = $this->em->getRepository(Usergroup::class)->findOneByName('Gestionnaire de Groupe');
                $gestionnaires = $this->importGestionnaires($row, $line, $groupeGestionnaire);
                $groupe->setGestionnaires($gestionnaires);

                $this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ') . $name);
                ++$this->nbsuccess;
                if (!$this->test) {
                    $this->em->persist($groupe);
                    $this->em->flush();
                    // $this->em->clear();
                }
            } else {
                $this->addError($row, $line, 'name', $this->translator->trans("Le groupe avec ce nom '" . $name . "' existe déjà !"));
                ++$this->nberrors;
            }
            ++$line;
        }
        ksort($this->errors);
        ksort($this->warnings);
    }

    private function importGroupePrestataire($csvRows)
    {
        // @TODO
    }

    private function importPrestataire($csvRows)
    {
        // Iterate over the reader and write each row to the database
        // idmlc;groupe;adresse;cpostal;ville;raison;metier;statut;responsable;iban;siret;web;horaires;description;rubriques;tags;tauxreconversion;cotisations;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1;contact1;phone1;email1;contact2;phone2;email2
        $line = 1;
        foreach ($csvRows as $row) {
            $hasError = false;
            if (1 == $line) {
                ++$line;
                continue;
            }
            if (!array_key_exists('groupe', $row)) {
                $this->addError($row, $line, 'groupe', $this->translator->trans("La colonne 'groupe' est obligatoire !"));
            }
            if (!array_key_exists('adresse', $row)) {
                $this->addError($row, $line, 'adresse', $this->translator->trans("La colonne 'adresse' est obligatoire !"));
            }
            if (!array_key_exists('cpostal', $row)) {
                $this->addError($row, $line, 'cpostal', $this->translator->trans("La colonne 'cpostal' est obligatoire !"));
            }
            if (!array_key_exists('ville', $row)) {
                $this->addError($row, $line, 'ville', $this->translator->trans("La colonne 'ville' est obligatoire !"));
            }
            if (!array_key_exists('raison', $row)) {
                $this->addError($row, $line, 'raison', $this->translator->trans("La colonne 'raison' est obligatoire !"));
            }
            if (!(array_key_exists('groupe', $row) && array_key_exists('adresse', $row) && array_key_exists('cpostal', $row) && array_key_exists('ville', $row) && array_key_exists('raison', $row))) {
                ++$line;
                ++$this->nberrors;
                continue;
            }
            $groupe = array_key_exists('groupe', $row) ? $row['groupe'] : '';
            $adresse = array_key_exists('adresse', $row) ? $row['adresse'] : '';
            $cpostal = array_key_exists('cpostal', $row) ? $row['cpostal'] : '';
            $ville = array_key_exists('ville', $row) ? $row['ville'] : '';
            $raison = array_key_exists('raison', $row) ? $row['raison'] : '';
            if (empty($groupe)) {
                $this->addError($row, $line, 'groupe', $this->translator->trans("Le 'groupe' est obligatoire !"));
            }
            if (empty($adresse)) {
                $this->addError($row, $line, 'adresse', $this->translator->trans("Le 'adresse' est obligatoire !"));
            }
            if (empty($cpostal)) {
                $this->addError($row, $line, 'cpostal', $this->translator->trans("Le 'cpostal' est obligatoire !"));
            }
            if (empty($ville)) {
                $this->addError($row, $line, 'ville', $this->translator->trans("Le 'ville' est obligatoire !"));
            }
            if (empty($raison)) {
                $this->addError($row, $line, 'raison', $this->translator->trans("Le 'raison' est obligatoire !"));
            }
            if (empty($groupe) || empty($adresse) || empty($cpostal) || empty($ville) || empty($raison)) {
                ++$this->nberrors;
                ++$line;
                continue;
            }
            $idmlc = array_key_exists('idmlc', $row) ? $row['idmlc'] : '';
            $metier = array_key_exists('metier', $row) ? $row['metier'] : '';
            $statut = array_key_exists('statut', $row) ? $row['statut'] : '';
            $responsable = array_key_exists('responsable', $row) ? $row['responsable'] : '';
            $iban = array_key_exists('iban', $row) ? $row['iban'] : '';
            $siret = array_key_exists('siret', $row) ? $row['siret'] : '';
            $web = array_key_exists('web', $row) ? $row['web'] : '';
            $horaires = array_key_exists('horaires', $row) ? $row['horaires'] : '';
            $description = array_key_exists('description', $row) ? $row['description'] : '';
            $rubriques = array_key_exists('rubriques', $row) ? $row['rubriques'] : '';
            $tags = array_key_exists('tags', $row) ? $row['tags'] : '';
            $tauxreconversion = array_key_exists('tauxreconversion', $row) ? $row['tauxreconversion'] : '';
            $cotisations = array_key_exists('cotisations', $row) ? $row['cotisations'] : '';

            $prestataire = null;
            if (!empty($idmlc)) {
                $prestataire = $this->em->getRepository(Prestataire::class)->findOneBy(['idmlc' => $idmlc]);
            }
            if (empty($prestataire)) {
                $prestataire = $this->em->getRepository(Prestataire::class)->findOneBy(['slug' => $this->slugify($raison)]);
            }
            if (empty($prestataire)) {
                $prestataire = new Prestataire();
                $prestataire->setTypeprestataire($this->em->getRepository(TypePrestataire::class)->findOneBy(['slug' => 'prestataire']));
                $prestataire->setIdmlc($idmlc);

                if (!empty($raison)) {
                    $prestataire->setRaison($raison);
                } else {
                    $this->addWarning($row, $line, 'raison', 'empty');
                }
                if (!empty($metier)) {
                    $prestataire->setMetier($metier);
                } else {
                    $this->addWarning($row, $line, 'metier', 'empty');
                }
                if (!empty($statut)) {
                    $prestataire->setStatut($statut);
                } else {
                    $this->addWarning($row, $line, 'statut', 'empty');
                }
                if (!empty($responsable)) {
                    $prestataire->setResponsable($responsable);
                } else {
                    $this->addWarning($row, $line, 'responsable', 'empty');
                }
                if (!empty($iban)) {
                    $prestataire->setIban($iban);
                } else {
                    $this->addWarning($row, $line, 'iban', 'empty');
                }
                if (!empty($siret)) {
                    $prestataire->setSiret($siret);
                } else {
                    $this->addWarning($row, $line, 'siret', 'empty');
                }
                if (!empty($web)) {
                    $prestataire->setWeb($web);
                } else {
                    $this->addWarning($row, $line, 'web', 'empty');
                }
                if (!empty($horaires)) {
                    $prestataire->setHoraires($horaires);
                } else {
                    $this->addWarning($row, $line, 'horaires', 'empty');
                }
                if (!empty($description)) {
                    $prestataire->setDescription($description);
                } else {
                    $this->addWarning($row, $line, 'description', 'empty');
                }

                $cptContact = 1;
                while (array_key_exists('contact' . $cptContact, $row) && $cptContact < 10) {
                    $contact = array_key_exists('contact' . $cptContact, $row) ? $row['contact' . $cptContact] : '';
                    $phone = array_key_exists('phone' . $cptContact, $row) ? $row['phone' . $cptContact] : '';
                    $email = array_key_exists('email' . $cptContact, $row) ? $row['email' . $cptContact] : '';
                    if (!empty(trim($contact))) {
                        $contactC = $this->em->getRepository(ContactPrestataire::class)->findOneBy(['prestataire' => $prestataire, 'name' => $contact]);
                        if (empty($contactC)) {
                            $contactC = new ContactPrestataire();
                        }
                        $contactC->setPrestataire($prestataire);
                        $contactC->setEnabled(true);
                        $contactC->setName($contact);
                        $contactC->setTel($phone);
                        $contactC->setEmail($email);
                        if (!$this->test) {
                            $this->em->persist($contactC);
                        }
                        $this->addSuccess($row, $line, 'contact', $this->translator->trans('Contact ajouté : ') . $contact);
                    } else {
                        break;
                    }
                    ++$cptContact;
                }
                // Importer les gestionnaires du prestataire s'ils existent
                $groupeGestionnaire = $this->em->getRepository(Usergroup::class)->findOneByName('Prestataire');
                $gestionnaires = $this->importGestionnaires($row, $line, $groupeGestionnaire);
                if (!$this->test) {
                    $prestataire->setUsers($gestionnaires);
                }

                if (!empty($groupe)) {
                    $groupeFound = $this->em->getRepository(Groupe::class)->findOneBy(['slug' => $this->slugify($groupe)]);
                    if (empty($groupeFound)) {
                        $groupeFound = new Groupe();
                        $groupeFound->setName($groupe);
                        $groupeFound->setSiege($this->em->getRepository(Siege::class)->getTheOne());
                        if (!$this->test) {
                            $this->em->persist($groupeFound);
                        }
                        $this->addWarning($row, $line, 'groupe', $this->translator->trans('Groupe introuvable, création du groupe : ') . $groupe);
                    }
                    $prestataire->setGroupe($groupeFound);
                } else {
                    $this->addWarning($row, $line, 'groupe', 'empty');
                }
                if (!empty($cotisations)) {
                    $cotisationArray = explode(',', $cotisations);
                    if (count($cotisationArray) > 0) {
                        foreach ($cotisationArray as $cotisationDetails) {
                            $cotisation = new CotisationPrestataire();
                            $now = new DateTime();
                            $cotisation->setRecu(true);
                            $cotisation->setReference('Import du ' . $now->format('d/m/Y H:i'));
                            $userLogguedIn = $this->em->merge($this->getUser());
                            $cotisation->setOperateur($userLogguedIn);
                            $cotisation->setRole('ROLE_SUPER_ADMIN');
                            $cotisation->setExpediteur($prestataire);
                            $cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE);
                            $cotisationDetailsArray = explode(':', $cotisationDetails);
                            if (1 == count($cotisationDetailsArray)) {
                                $cotisation->setMontant(intval($cotisationDetails));
                                $cotisation->getCotisationInfos()->setDebut($now);
                                $cotisation->getCotisationInfos()->setFin(new DateTime('+ 1 year'));
                            } else {
                                $cotisation->setMontant(intval($cotisationDetailsArray[0]));
                                $cotisation->getCotisationInfos()->setAnnee($cotisationDetailsArray[1]);
                                $cotisation->getCotisationInfos()->setDebut(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]) . '0101'));
                                $cotisation->getCotisationInfos()->setFin(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]) . '1231'));
                            }
                            if (!$this->test) {
                                $this->em->persist($cotisation);
                            }
                            $this->addSuccess($row, $line, 'cotisations', $this->translator->trans('Cotisation(s) ajoutée(s) ligne : ') . $line);
                        }
                    }
                } else {
                    $this->addWarning($row, $line, 'cotisations', 'empty');
                }
                if (!empty($rubriques)) {
                    $rubriquesArray = explode(',', $rubriques);
                    foreach ($rubriquesArray as $rubrique) {
                        $rubriqueFound = $this->em->getRepository(Rubrique::class)->findOneBy(['slug' => $this->slugify($rubrique)]);
                        if (empty($rubriqueFound)) {
                            $rubriqueFound = new Rubrique();
                            $rubriqueFound->setName($rubrique);
                            if (!$this->test) {
                                $this->em->persist($rubriqueFound);
                            }
                            $this->addSuccess($row, $line, 'rubrique', $this->translator->trans('Rubrique ajoutée : ') . $rubrique);
                        }
                        $prestataire->addRubrique($rubriqueFound);
                    }
                } else {
                    $this->addWarning($row, $line, 'rubriques', 'empty');
                }
                if (!empty($tags)) {
                    $tagsArray = explode(',', $tags);
                    foreach ($tagsArray as $tag) {
                        $tagFound = $this->em->getRepository(EtatPrestataire::class)->findOneBy(['slug' => $this->slugify($tag)]);
                        if (empty($tagFound)) {
                            $tagFound = new EtatPrestataire();
                            $tagFound->setName($tag);
                            if (!$this->test) {
                                $this->em->persist($tagFound);
                            }
                            $this->addSuccess($row, $line, 'tag', $this->translator->trans('Tag ajouté : ') . $tag);
                        }
                        $prestataire->addEtat($tagFound);
                    }
                } else {
                    $this->addWarning($row, $line, 'tags', 'empty');
                }
                if (!empty($adresse) || !empty($cpostal) || !empty($ville)) {
                    // $geolocFound = $this->em->getRepository(Geoloc::class)->findOneBy([
                    //     'adresse' => $adresse,
                    //     'cpostal' => $cpostal,
                    //     'ville' => $ville
                    // ]);
                    // if (!empty($geolocFound)) {
                    //     $geolocP = $this->em->getRepository(GeolocPrestataire::class)->findOneBy([
                    //         'name' => 'Adresse',
                    //         'prestataire' => $prestataire,
                    //         'geoloc' => $geolocFound
                    //     ]);
                    //     if (empty($geolocP)) {
                    //         $geolocP = new GeolocPrestataire();
                    //         $geolocP->setName('Adresse');
                    //         $geolocP->setPrestataire($prestataire);
                    //         $geolocP->setGeoloc($geolocFound);
                    //         $prestataire->addGeoloc($geolocP);
                    //     }
                    // } else {
                    $geolocP = new GeolocPrestataire();
                    $geolocP->setName('Adresse');
                    $geolocP->setPrestataire($prestataire);
                    $geolocFound = new Geoloc();
                    $geolocFound->setEnabled(true);
                    $geolocFound->setAdresse($adresse);
                    $geolocFound->setCpostal($cpostal);
                    $geolocFound->setVille($ville);
                    $geolocP->setGeoloc($geolocFound);
                    $prestataire->addGeoloc($geolocP);
                    // }
                    if (!$this->test) {
                        $this->em->persist($geolocP);
                        $this->em->flush();
                    }
                }
            } else {
                $this->addError($row, $line, 'name', $this->translator->trans("Le prestataire avec cette raison '" . $raison . "' existe déjà, impossible de le réimporter !"));
                ++$this->nberrors;
                $hasError = true;
            }
            if (!$hasError) {
                $this->addSuccess($row, $line, 'user', $this->translator->trans('Prestataire ajouté : ') . $prestataire->__toString());
                ++$this->nbsuccess;
                if (!$this->test) {
                    $this->em->persist($prestataire);
                    $this->em->flush();
                    $this->em->clear();
                }
            }

            ++$line;
        }
        ksort($this->errors);
        ksort($this->warnings);
    }

    private function importAdherent($csvRows)
    {
        // Iterate over the reader and write each row to the database
        // idmlc;groupe;email;prenom;nom;phone;mobile;adresse;cpostal;ville;cotisations
        $line = 1;
        $now = new DateTime();
        foreach ($csvRows as $row) {
            $hasError = false;
            if (1 == $line) {
                ++$line;
                continue;
            }
            // gc_collect_cycles();
            $idmlc = array_key_exists('idmlc', $row) ? $row['idmlc'] : '';
            $groupe = array_key_exists('groupe', $row) ? $row['groupe'] : '';
            $firstname = array_key_exists('prenom', $row) ? $row['prenom'] : '';
            $lastname = array_key_exists('nom', $row) ? $row['nom'] : '';
            $email = array_key_exists('email', $row) ? $row['email'] : '';
            $phone = array_key_exists('phone', $row) ? $row['phone'] : '';
            $mobile = array_key_exists('mobile', $row) ? $row['mobile'] : '';
            $adresse = array_key_exists('adresse', $row) ? $row['adresse'] : '';
            $cpostal = array_key_exists('cpostal', $row) ? $row['cpostal'] : '';
            $ville = array_key_exists('ville', $row) ? $row['ville'] : '';
            $cotisations = array_key_exists('cotisations', $row) ? $row['cotisations'] : '';

            if (empty($email)) {
                $this->addError($row, $line, 'email', $this->translator->trans("La colonne 'email' est obligatoire !"));
                ++$line;
                ++$this->nberrors;
                continue;
            }

            $adherent = null;
            if (!empty($idmlc)) {
                $adherent = $this->em->getRepository(Adherent::class)->findOneBy(['idmlc' => $idmlc]);
            }
            if (empty($adherent)) {
                $userFound = $this->em->getRepository(User::class)->findOneBy(['email' => $email]);
                if (!empty($userFound)) {
                    $adherent = $userFound->getAdherent();
                }
            }
            if (empty($adherent)) {
                $adherent = new Adherent();
                $user = $this->userManager->createUser();
                $user->setUsername($email);
                $user->setEmail($email);
                $user->setConfirmationToken($this->tokenGenerator->generateToken());
                $user->setEnabled(true);
                $user->setPassword(md5(random_bytes(10)));
                $usergroupe = $this->em->getRepository(Usergroup::class)->findOneByName('Adherent');
                $user->addPossiblegroup($usergroupe);
                $user->setGroups([$usergroupe]);
                $user->setAdherent($adherent);
                $adherent->setUser($user);
            } else {
                $this->addWarning($row, $line, 'email', $this->translator->trans("L'adherent avec cet email '" . $email . "' existe déjà, on tente une mise à jour !"));
                $user = $adherent->getUser();
            }
            $adherent->setIdmlc($idmlc);
            if (!empty($firstname)) {
                $user->setFirstname($firstname);
            } else {
                $this->addWarning($row, $line, 'prenom', 'empty');
            }
            if (!empty($lastname)) {
                $user->setLastname($lastname);
            } else {
                $this->addWarning($row, $line, 'nom', 'empty');
            }
            if (!empty($phone)) {
                $user->setPhone($phone);
            } else {
                $this->addWarning($row, $line, 'phone', 'empty');
            }
            if (!empty($mobile)) {
                $user->setMobile($mobile);
            } else {
                $this->addWarning($row, $line, 'mobile', 'empty');
            }
            if (!empty($groupe)) {
                $groupeFound = $this->em->getRepository(Groupe::class)->findOneBy(['slug' => $this->slugify($groupe)]);
                if (empty($groupeFound)) {
                    $groupeFound = new Groupe();
                    $groupeFound->setName($groupe);
                    $groupeFound->setSiege($this->em->getRepository(Siege::class)->getTheOne());
                    if (!$this->test) {
                        $this->em->persist($groupeFound);
                        $this->em->flush();
                    }
                    $this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ') . $groupe);
                }
                if ($adherent->getGroupe() != $groupeFound) {
                    $adherent->setGroupe($groupeFound);
                }
            } else {
                $this->addWarning($row, $line, 'groupe', 'empty');
            }
            if (!$this->test) {
                $this->em->persist($adherent);
            }

            if (!empty($cotisations)) {
                $cotisationArray = explode(',', $cotisations);
                if (count($cotisationArray) > 0) {
                    foreach ($cotisationArray as $cotisationDetails) {
                        $cotisationDetailsArray = explode(':', $cotisationDetails);
                        $cotisationFound = null;

                        if (!empty($adherent->getId())) {
                            if (1 == count($cotisationDetailsArray)) {
                                $cotisationFound = $this->em->getRepository(CotisationAdherent::class)->isCotisationAdherentExist($adherent, intval($cotisationDetails), date('Y'));
                            } else {
                                $cotisationFound = $this->em->getRepository(CotisationAdherent::class)->isCotisationAdherentExist($adherent, intval($cotisationDetailsArray[0]), $cotisationDetailsArray[1]);
                            }
                        }
                        if (!empty($cotisationFound)) {
                            $this->addWarning($row, $line, 'cotisation', $this->translator->trans("Cotisation déjà trouvée pour l'année ") . (1 == count($cotisationDetailsArray)) ? date('Y') : $cotisationDetailsArray[1]);
                            unset($cotisationFound);
                        } else {
                            $cotisation = new CotisationAdherent();
                            $cotisation->setRecu(true);
                            $cotisation->setReference('Import du ' . $now->format('d/m/Y H:i'));
                            $userLogguedIn = $this->em->merge($this->getUser());
                            $cotisation->setOperateur($userLogguedIn);
                            $cotisation->setRole('ROLE_ADHERENT');
                            $cotisation->setExpediteur($adherent);
                            $mlcPrestataire = $this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true]);
                            $cotisation->setDestinataire($mlcPrestataire);
                            $cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE);
                            if (1 == count($cotisationDetailsArray)) {
                                $cotisation->setMontant(intval($cotisationDetails));
                                $cotisation->getCotisationInfos()->setAnnee(date('Y'));
                                $cotisation->getCotisationInfos()->setDebut($now);
                                $cotisation->getCotisationInfos()->setFin(new DateTime('+ 1 year'));
                            } else {
                                $cotisation->setMontant(intval($cotisationDetailsArray[0]));
                                $cotisation->getCotisationInfos()->setAnnee($cotisationDetailsArray[1]);
                                $cotisation->getCotisationInfos()->setDebut(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]) . '0101'));
                                $cotisation->getCotisationInfos()->setFin(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]) . '1231'));
                            }
                            if (!$this->test) {
                                $this->em->persist($cotisation);
                            }
                        }
                        // if (!$this->test) {
                        //     try {
                        //         $this->operationUtils->executeOperations($cotisation);
                        //         $this->addSuccess($row, $line, 'cotisations', $this->translator->trans('Cotisation(s) ajoutée(s) ligne : ') . $line);
                        //     } catch (\Exception $e) {
                        //         $this->addError($row, $line, 'cotisations', $this->translator->trans('Cotisation problème : ') . $e->getMessage());
                        //     }
                        // }
                        $this->addSuccess($row, $line, 'cotisations', $this->translator->trans('Cotisation(s) ajoutée(s) ligne : ') . $line);
                    }
                }
            } else {
                $this->addWarning($row, $line, 'cotisations', 'empty');
            }
            if (!empty($adresse) || !empty($cpostal) || !empty($ville)) {
                $geolocFound = $this->em->getRepository(Geoloc::class)->findOneBy([
                    'adresse' => $adresse,
                    'cpostal' => $cpostal,
                    'ville' => $ville,
                ]);
                if (empty($geolocFound)) {
                    $geolocFound = new Geoloc();
                    $geolocFound->setAdresse($adresse);
                    $geolocFound->setCpostal($cpostal);
                    $geolocFound->setVille($ville);
                    $adherent->setGeoloc($geolocFound);
                    if (!$this->test) {
                        $this->em->persist($geolocFound);
                    }
                    $this->addSuccess($row, $line, 'adresse', $this->translator->trans('Adhérent : nouvelle adresse : ') . $geolocFound->__toString());
                }
            }

            if (!$hasError) {
                $this->addSuccess($row, $line, 'user', $this->translator->trans('Adhérent bien ajouté ligne : ') . $line);
                ++$this->nbsuccess;
                $user->setPasswordRequestedAt(new \DateTime());
                if (!$this->test) {
                    if ($this->sendemail) {
                        $this->eventDispatcher->dispatch(MLCEvents::REGISTRATION_ADHERENT, new UserEvent($user, $this->getRequest()));
                    }
                }
            }
            $this->em->flush();
            $this->em->clear();
            gc_collect_cycles();
            ++$line;
        }
        ksort($this->errors);
        ksort($this->warnings);
    }

    private function importOperations($csvRows)
    {
        // Iterate over the reader and write each row to the database
        //exp_idmlc|exp;exp_type;dest_idmlc|dest;dest_type;user_email;montant;devise;date;type;moyen;reference;tauxreconversion;data
        $line = 1;
        foreach ($csvRows as $row) {
            if (1 == $line) {
                ++$line;
                continue;
            }
            if (!(array_key_exists('exp_idmlc', $row) || array_key_exists('exp', $row))) {
                $this->addError($row, $line, 'exp_idmlc or exp', $this->translator->trans("La colonne 'exp_idmlc' ou 'exp' est obligatoire !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            if (!(array_key_exists('dest_idmlc', $row) || array_key_exists('dest', $row))) {
                $this->addError($row, $line, 'dest_idmlc or dest', $this->translator->trans("La colonne 'dest_idmlc'ou 'dest' est obligatoire !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            if (!array_key_exists('exp_type', $row)) {
                $this->addError($row, $line, 'exp_type', $this->translator->trans("La colonne 'exp_type' est obligatoire !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            if (!array_key_exists('dest_type', $row)) {
                $this->addError($row, $line, 'dest_type', $this->translator->trans("La colonne 'dest_type' est obligatoire !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            if (!array_key_exists('montant', $row)) {
                $this->addError($row, $line, 'montant', $this->translator->trans("La colonne 'montant' est obligatoire !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            if (!array_key_exists('devise', $row)) {
                $this->addError($row, $line, 'devise', $this->translator->trans("La colonne 'devise' est obligatoire !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            if (!array_key_exists('date', $row)) {
                $this->addError($row, $line, 'date', $this->translator->trans("La colonne 'date' est obligatoire !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            if (!array_key_exists('type', $row)) {
                $this->addError($row, $line, 'type', $this->translator->trans("La colonne 'type' est obligatoire !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            $exp_id = array_key_exists('exp_idmlc', $row) ? $row['exp_idmlc'] : '';
            $exp_name = array_key_exists('exp', $row) ? $row['exp'] : '';
            $exp_type = array_key_exists('exp_type', $row) ? $row['exp_type'] : '';
            $dest_id = array_key_exists('dest_idmlc', $row) ? $row['dest_idmlc'] : '';
            $dest_name = array_key_exists('dest', $row) ? $row['dest'] : '';
            $dest_type = array_key_exists('dest_type', $row) ? $row['dest_type'] : '';
            if (!in_array($exp_type, ImportEnum::getAvailableOperators())) {
                $this->addError($row, $line, 'exp_type', $this->translator->trans("La colonne 'exp_type' n'est pas valide !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            if (!in_array($dest_type, ImportEnum::getAvailableOperators())) {
                $this->addError($row, $line, 'dest_type', $this->translator->trans("La colonne 'dest_type' n'est pas valide !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            $exp = $this->getEntityFromData($exp_type, $exp_id, $exp_name);
            if (null === $exp) {
                $this->addError($row, $line, 'exp', $this->translator->trans("L'expediteur est introuvable !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            $dest = $this->getEntityFromData($dest_type, $dest_id, $dest_name);
            if (null === $dest) {
                $this->addError($row, $line, 'dest', $this->translator->trans('Le destinataire est introuvable !'));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            $montant = $row['montant'];
            if (!preg_match('/^[0-9]*([\.,][0-9]*)?$/', $montant)) {
                $this->addError($row, $line, 'montant', $this->translator->trans("La colonne 'montant' est invalide !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            // $currency = $row['devise'];
            // if (!in_array($currency, CurrencyEnum::getAvailableTypes())) {
            //     $this->addError($row, $line, 'currency', $this->translator->trans("La colonne 'currency' est invalide !"));
            //     ++$this->nberrors;
            //     ++$line;
            //     continue;
            // }
            $dateCsv = $row['date'];
            $date = DateTime::createFromFormat('Y-m-d H:i', $dateCsv);
            if (false === $date) {
                $this->addError($row, $line, 'date', $this->translator->trans("La date est invalide (format attendu : 'YYYY-mm-dd HH:ii', exemple 2020-11-29 11:53) !"));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            $typeFlux = $row['type'];
            if (!in_array($typeFlux, FluxEnum::getAvailableTypes())) {
                $this->addError($row, $line, 'type', $this->translator->trans('Le type de flux est invalide (types attendus : ' . implode(', ', FluxEnum::getAvailableTypes()) . ') !'));
                ++$this->nberrors;
                ++$line;
                continue;
            }
            $moyen = $row['moyen'];
            if (!in_array($moyen, MoyenEnum::getAvailableTypes())) {
                $this->addError($row, $line, 'moyen', $this->translator->trans('Le moyen est invalide (moyens attendus : ' . implode(', ', MoyenEnum::getAvailableTypes()) . ') !'));
                ++$this->nberrors;
                ++$line;
                continue;
            }

            $reference = array_key_exists('reference', $row) ? $row['reference'] : '';
            $tauxreconversion = array_key_exists('tauxreconversion', $row) ? $row['tauxreconversion'] : '';
            $data = array_key_exists('data', $row) ? $row['data'] : '';

            //@TODO : enregistrer les données passées dans flux et operation avec un flag historical
            $fluxClass = FluxEnum::getClassName($typeFlux);
            $flux = new $fluxClass();
            $flux->setHistorical(true);
            $flux->setOperateur($this->getUser());
            $flux->setRole($this->getUser()->getGroups()[0]->__toString());
            $flux->setExpediteur($exp);
            $flux->setDestinataire($dest);
            $flux->setMoyen($moyen);
            $flux->setMontant($montant);
            $flux->setReference($reference);
            $flux->setTauxreconversion($tauxreconversion);
            if (is_string($data)) {
                $flux->setData([$data]);
            } elseif (is_array($data)) {
                $flux->setData($data);
            }

            if (!$this->test) {
                try {
                    $this->em->persist($flux);
                    $this->em->flush();
                    $flux->setCreatedAt($date);
                    $this->em->persist($flux);
                    $this->em->flush();

                    $operations = $flux->getAllOperations($this->em);
                    foreach ($operations as $operation) {
                        $operation->setHistorical(true);
                        $this->em->persist($operation);
                        $this->em->flush();
                        $operation->setCreatedAt($date);
                        $this->em->persist($operation);
                        $this->em->flush();
                    }
                } catch (Exception $e) {
                    $this->addError($row, $line, 'all', $this->translator->trans("L'enregistrement du flux a posé problème ! " . $e->getMessage()));
                    ++$this->nberrors;
                    ++$line;
                    continue;
                }
            } else {
                $this->addSuccess($row, $line, 'all', $this->translator->trans('Flux ajouté : ') . $flux->__toString());
            }
        }
    }

    private function getEntityFromData(string $type, string $idmlc, string $idNameOrEmail)
    {
        $entity = null;
        $idNameOrEmailSlug = $this->slugify($idNameOrEmail);
        if ('prestataire' == $type) {
            if (!empty($idNameOrEmail)) {
                $entity = $this->em->getRepository(Prestataire::class)->findOneBy(['slug' => $idNameOrEmailSlug]);
            } elseif (!empty($idmlc)) {
                $entity = $this->em->getRepository(Prestataire::class)->findOneBy(['idmlc' => $idmlc]);
            }
        } elseif ('adherent' == $type) {
            if (!empty($idNameOrEmail)) {
                $userFound = $this->em->getRepository(User::class)->findOneBy(['username' => $idNameOrEmail]);
                if (!empty($userFound)) {
                    $entity = $userFound->getAdherent();
                }
            } elseif (!empty($idmlc)) {
                $entity = $this->em->getRepository(Adherent::class)->findOneBy(['idmlc' => $idmlc]);
            }
        } elseif ('siege' == $type && 'siege' == $exp_id) {
            $siege = $this->em->getRepository(Siege::class)->getTheOne();
        } elseif ('groupe' == $type) {
            if (!empty($idNameOrEmail)) {
                $entity = $this->em->getRepository(Groupe::class)->findOneBy(['slug' => $idNameOrEmailSlug]);
            } elseif (!empty($idmlc)) {
                $entity = $this->em->getRepository(Groupe::class)->findOneBy(['idmlc' => $idmlc]);
            }
        } elseif ('comptoir' == $type) {
            if (!empty($idNameOrEmail)) {
                $entity = $this->em->getRepository(Comptoir::class)->findOneBy(['slug' => $idNameOrEmailSlug]);
            } elseif (!empty($idmlc)) {
                $entity = $this->em->getRepository(Comptoir::class)->findOneBy(['idmlc' => $idmlc]);
            }
        }

        return $entity;
    }

    /**
     * Import manager of comptoir / groupe / presta.
     *
     * @param array     $row    Value of line imported
     * @param Usergroup $groupe Groupe add to manager imported
     *
     * @return User Manager created
     */
    private function importGestionnaires($row, $line, Usergroup $groupe)
    {
        $cptGestionnaire = 1;
        $users = new ArrayCollection();
        $usergroupe = $this->em->getRepository(Usergroup::class)->findOneByName('Adherent');
        while (array_key_exists('gestionnaire_email' . $cptGestionnaire, $row) && !empty($row['gestionnaire_email' . $cptGestionnaire]) && $cptGestionnaire < 10) {
            $email = array_key_exists('gestionnaire_email' . $cptGestionnaire, $row) ? $row['gestionnaire_email' . $cptGestionnaire] : '';

            $userFound = $this->em->getRepository(User::class)->findOneBy(['email' => $email]);
            if (!empty($userFound)) {
                $userFound->addPossiblegroup($groupe);
                if (!$this->test) {
                    $users[] = $userFound;
                    $this->em->persist($userFound);
                } else {
                    $this->em->detach($userFound);
                }
                $this->addSuccess($row, $line, 'gestionnaire', $this->translator->trans('Rôle ' . $groupe . ' ajouté à l\'utilisateur ') . $userFound);
            } else {
                $nom = array_key_exists('gestionnaire_nom' . $cptGestionnaire, $row) ? $row['gestionnaire_nom' . $cptGestionnaire] : '';
                $prenom = array_key_exists('gestionnaire_prenom' . $cptGestionnaire, $row) ? $row['gestionnaire_prenom' . $cptGestionnaire] : '';
                $phone = array_key_exists('gestionnaire_phone' . $cptGestionnaire, $row) ? $row['gestionnaire_phone' . $cptGestionnaire] : '';
                $mobile = array_key_exists('gestionnaire_mobile' . $cptGestionnaire, $row) ? $row['gestionnaire_mobile' . $cptGestionnaire] : '';

                $adherent = new Adherent();
                $user = new User(); // $this->userManager->createUser();
                $user->setConfirmationToken($this->tokenGenerator->generateToken());
                $user->setEnabled(true);
                $user->setPassword(md5(random_bytes(10)));
                $user->addPossiblegroup($usergroupe);
                $user->addPossiblegroup($groupe);
                $user->setGroups([$groupe]);
                $user->setFirstname($prenom);
                $user->setLastname($nom);
                $user->setPhone($phone);
                $user->setMobile($mobile);
                $user->setEmail($email);
                $user->setUsername($email);
                $user->setAdherent($adherent);
                $adherent->setUser($user);
                $users[] = $user;
                $this->addSuccess($row, $line, 'gestionnaire', $this->translator->trans('Nouvel adhérent/gestionnaire' . $adherent . ' bien ajouté ligne : ') . $line);
                if (!$this->test) {
                    $this->em->persist($user);
                    $this->userManager->updateUser($user);
                    $this->em->persist($adherent);
                    $this->em->flush();
                    // $this->em->clear();
                    gc_collect_cycles();
                }
            }
            if (!$this->test && $this->sendemail) {
                $this->eventDispatcher->dispatch(MLCEvents::REGISTRATION_ADHERENT, new UserEvent($user, $this->getRequest()));
            }
            ++$cptGestionnaire;
        }

        return $users;
    }

    private function addSuccess($row, $line, $key, $message = '')
    {
        $csvline = implode(';', array_values($row));
        $this->success[$line][$key] = $message;
    }

    private function addError($row, $line, $key, $err = '')
    {
        $this->lineErrors[$line] = implode(';', array_values($row));
        $this->errors[$line][$key] = (array_key_exists($key, $row) ? (!empty($row[$key]) ? '"' . $row[$key] . '"' : '') : '') . ' [' . $err . ']';
    }

    private function addWarning($row, $line, $key, $err = '')
    {
        $csvline = implode(';', array_values($row));
        if ('empty' == $err) {
            $errString = $this->translator->trans('Valeur vide !');
            $this->warnings[$line][$key] = '[' . $errString . ' ]';
        } elseif ('invalid' == $err) {
            $errString = $this->translator->trans('Valeur invalide !');
            $this->warnings[$line][$key] = '"' . (array_key_exists($key, $row) ? $row[$key] : '') . '" [' . $errString . ']';
        } elseif ('' != $err) {
            $this->warnings[$line][$key] = '"' . (array_key_exists($key, $row) ? $row[$key] : '') . '" [' . $err . ']';
        }
    }

    private function tofloat($num)
    {
        $dotPos = strrpos($num, '.');
        $commaPos = strrpos($num, ',');
        $sep = (($dotPos > $commaPos) && $dotPos) ? $dotPos :
            ((($commaPos > $dotPos) && $commaPos) ? $commaPos : false);

        if (!$sep) {
            return floatval(preg_replace('/[^0-9]/', '', $num));
        }

        return floatval(
            preg_replace('/[^0-9]/', '', substr($num, 0, $sep)) . '.' .
            preg_replace('/[^0-9]/', '', substr($num, $sep + 1, strlen($num)))
        );
    }

    private function slugify($string)
    {
        $string = Transliterator::transliterate($string, '-');

        return Transliterator::urlize($string, '-');
    }
}
