<?php

namespace App\Listener;

use App\Entity\User;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Event\OnFlushEventArgs;
use Doctrine\ORM\Events;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\SerializerInterface;

class UnitOfWorkListener implements EventSubscriber
{
    private $em;
    private $serializer;
    private $session;

    public function __construct(EntityManagerInterface $em, SerializerInterface $serializer, Security $security, SessionInterface $session)
    {
        $this->em = $em;
        $this->serializer = $serializer;
        $this->security = $security;
        $this->session = $session;
    }

    public function getSubscribedEvents()
    {
        return [Events::onFlush];
    }

    public function onFlush(OnFlushEventArgs $args)
    {
        $em = $args->getEntityManager();
        $uow = $em->getUnitOfWork();

        if (null != $this->security->getUser()) {
            // // if (true == true) {
            // if ($this->security->getUser()->hasRole('ROLE_ADMIN')
            //     || $this->security->getUser()->hasRole('ROLE_SUPER_ADMIN')
            //     || $this->security->getUser()->hasRole('ROLE_MODERATEUR')
            // ) {
            //     // ON EDITE LES ENTITES COMME D'HABITUDE ! => pas de changements du UnitOfWork
            // } else {
            // DEBUG
            $debug = false;
            if ($debug) {
                dump('-------------------------------------------------- insert');
                dump($uow->getScheduledEntityInsertions());
                dump('-------------------------------------------------- update');
                dump($uow->getScheduledEntityUpdates());
                foreach ($uow->getScheduledEntityUpdates() as $entity) {
                    dump(get_class($entity) . ' ' . $entity->getId());
                    dump($uow->getEntityChangeSet($entity));
                }
                dump('-------------------------------------------------- delete');
                dump($uow->getScheduledEntityDeletions());
                dump('-------------------------------------------------- col update');
                dump($uow->getScheduledCollectionUpdates());
                dump('-------------------------------------------------- col delete');
                dump($uow->getScheduledCollectionDeletions());
                // exit();
            }
            $updated = $uow->getScheduledEntityUpdates();
            $deleted = $uow->getScheduledEntityDeletions();
            // $colupdated = $uow->getScheduledCollectionUpdates();
            // $coldeleted = $uow->getScheduledCollectionDeletions();

            foreach ($updated as $entity) {
                if ($entity instanceof User) {
                    $userDB = $this->em->getRepository(User::class)->findOneById($entity->getId());
                    $changeSets = $this->em->getUnitOfWork()->getEntityChangeSet($entity);

                    $hasRoleSuperAdmin = false;
                    $hasRoleAdminSiege = false;
                    $hasRemovedRoleSuperAdmin = false;
                    $hasRemovedRoleAdminSiege = false;
                    foreach ($changeSets as $key => $changeSet) {
                        if ('enabled' == $key && true == $changeSet[0] && false == $changeSet[1]) {
                            if ($entity->hasRole('ROLE_SUPER_ADMIN')) {
                                $hasRemovedRoleSuperAdmin = true;
                            }
                            if ($entity->hasRole('ROLE_ADMIN_SIEGE')) {
                                $hasRemovedRoleAdminSiege = true;
                            }
                        }
                        if ('roles' == $key) {
                            foreach ($changeSet[0] as $key => $role) {
                                if ('ROLE_SUPER_ADMIN' == $role) {
                                    $hasRoleSuperAdmin = true;
                                }
                                if ('ROLE_ADMIN_SIEGE' == $role) {
                                    $hasRoleAdminSiege = true;
                                }
                            }
                            if ($hasRoleSuperAdmin) {
                                $hasRemovedRoleSuperAdmin = true;
                            }
                            if ($hasRoleAdminSiege) {
                                $hasRemovedRoleAdminSiege = true;
                            }
                            foreach ($changeSet[1] as $key => $role) {
                                if ('ROLE_SUPER_ADMIN' == $role) {
                                    $hasRemovedRoleSuperAdmin = false;
                                }
                                if ('ROLE_ADMIN_SIEGE' == $role) {
                                    $hasRemovedRoleAdminSiege = false;
                                }
                            }
                        }
                    }
                    if ($hasRemovedRoleSuperAdmin) {
                        $usersSuperAdmin = $this->em->getRepository(User::class)->findByRole('ROLE_SUPER_ADMIN');
                        if (count($usersSuperAdmin) <= 1) {
                            $this->session->getFlashBag()->add('error', 'Impossible de désactiver ou supprimer le dernier utilisateur SUPER ADMIN, ajoutez en un autre avant !');
                            $uow->detach($entity);
                        }
                    }
                    if ($hasRemovedRoleAdminSiege) {
                        $usersAdminSiege = $this->em->getRepository(User::class)->findByRole('ROLE_ADMIN_SIEGE');
                        if (count($usersAdminSiege) <= 1) {
                            $this->session->getFlashBag()->add('error', 'Impossible de désactiver ou supprimer le dernier utilisateur ADMIN SIEGE, ajoutez en un autre avant !');
                            $uow->detach($entity);
                        }
                    }
                }
            }
            foreach ($deleted as $entity) {
                if ($entity instanceof User) {
                    if ($entity->hasRole('ROLE_SUPER_ADMIN')) {
                        $usersSuperAdmin = $this->em->getRepository(User::class)->findByRole('ROLE_SUPER_ADMIN');
                        if (count($usersSuperAdmin) <= 1) {
                            $this->session->getFlashBag()->add('error', 'Impossible de désactiver ou supprimer le dernier utilisateur SUPER ADMIN, ajoutez en un autre avant !');
                            $uow->detach($entity);
                        }
                    }
                    if ($entity->hasRole('ROLE_ADMIN_SIEGE')) {
                        $usersAdminSiege = $this->em->getRepository(User::class)->findByRole('ROLE_ADMIN_SIEGE');
                        if (count($usersAdminSiege) <= 1) {
                            $this->session->getFlashBag()->add('error', 'Impossible de désactiver ou supprimer le dernier utilisateur ADMIN SIEGE, ajoutez en un autre avant !');
                            $uow->detach($entity);
                        }
                    }
                }
            }
        }
    }
}
