<?php

namespace App\Factory;

use App\Entity\AchatMonnaieAConfirmerAdherent;
use App\Entity\AchatMonnaieAConfirmerPrestataire;
use App\Entity\AchatMonnaieAdherent;
use App\Entity\AchatMonnaiePrestataire;
use App\Entity\ChangeAdherentComptoir;
use App\Entity\ChangePrestataireComptoir;
use App\Entity\Comptoir;
use App\Entity\Groupe;
use App\Entity\Prestataire;
use App\Entity\Reconversion;
use App\Entity\Siege;
use App\Entity\TicketFixDestroy;
use App\Entity\TicketFixPrint;
use App\Entity\TransactionAdherentAdherent;
use App\Entity\TransactionAdherentPrestataire;
use App\Entity\TransactionPrestataireAdherent;
use App\Entity\TransactionPrestatairePrestataire;
use App\Entity\TransfertComptoirGroupe;
use App\Entity\TransfertGroupeComptoir;
use App\Entity\TransfertGroupeSiege;
use App\Entity\TransfertSiegeGroupe;
use App\Entity\User;
use App\Form\Type\AchatMonnaieAConfirmerAdherentFormType;
use App\Form\Type\AchatMonnaieAConfirmerPrestataireFormType;
use App\Form\Type\AchatMonnaieAdherentFormType;
use App\Form\Type\AchatMonnaiePrestataireFormType;
use App\Form\Type\AdherentInfosFormType;
use App\Form\Type\ChangeAdherentComptoirFormType;
use App\Form\Type\ChangePrestataireComptoirFormType;
use App\Form\Type\ComptoirInfosFormType;
use App\Form\Type\GroupeInfosFormType;
use App\Form\Type\GroupePrestataireInscriptionFormType;
use App\Form\Type\PrestataireInfosFormType;
use App\Form\Type\ReconversionFormType;
use App\Form\Type\SoldeSiegeFormType;
use App\Form\Type\TicketFixDestroyFormType;
use App\Form\Type\TicketFixPrintFormType;
use App\Form\Type\TransactionAdherentAdherentFormType;
use App\Form\Type\TransactionAdherentPrestataireFormType;
use App\Form\Type\TransactionPrestataireAdherentFormType;
use App\Form\Type\TransactionPrestatairePrestataireFormType;
use App\Form\Type\TransfertComptoirGroupeFormType;
use App\Form\Type\TransfertGroupeComptoirFormType;
use App\Form\Type\TransfertGroupeSiegeFormType;
use App\Form\Type\TransfertSiegeGroupeFormType;
use App\Form\Type\UserInfosFormType;
use App\Form\Type\VenteEmlcAdherentFormType;
use App\Form\Type\VenteEmlcPrestataireFormType;
use App\Form\Type\SetPaymentCodeFormType;
use Doctrine\ORM\EntityManagerInterface;
use FOS\UserBundle\Form\Type\ChangePasswordFormType;
use Symfony\Component\Form\FormFactoryInterface as FormF;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\RouterInterface;

class FormFactory
{
    private $ff;
    private $router;
    private $session;
    private $em;

    public function __construct(FormF $ff, RouterInterface $router, SessionInterface $session, EntityManagerInterface $em)
    {
        $this->ff = $ff;
        $this->router = $router;
        $this->session = $session;
        $this->em = $em;
    }

    public function getUserInfosForm(User $user)
    {
        if (empty($user)) {
            throw new \Exception('[FORM 0] Opération impossible !');
        }
        $form = $this->ff->create(UserInfosFormType::class, $user, ['action' => $this->router->generate('user_infos')]);

        return $form->createView();
    }

    public function getUserPasswordForm(User $user)
    {
        if (empty($user)) {
            throw new \Exception('[FORM 1] Opération impossible !');
        }
        $form = $this->ff->create(ChangePasswordFormType::class, $user, ['action' => $this->router->generate('fos_user_change_password')]);

        return $form->createView();
    }

    public function getGroupeInfosForm(User $user)
    {
        if (empty($user) || empty($this->session->get('_groupegere'))) {
            throw new \Exception('[FORM 2] Opération impossible !');
        }
        $groupe = $this->session->get('_groupegere');
        $groupe = $this->em->getRepository(Groupe::class)->findOneById($groupe->getId());
        $form = $this->ff->create(GroupeInfosFormType::class, $groupe, ['action' => $this->router->generate('groupe_infos')]);

        return $form->createView();
    }

    public function getComptoirInfosForm(User $user)
    {
        if (empty($user) || empty($this->session->get('_comptoirgere'))) {
            throw new \Exception('[FORM 3] Opération impossible !');
        }
        $comptoir = $this->session->get('_comptoirgere');
        $comptoir = $this->em->getRepository(Comptoir::class)->findOneById($comptoir->getId());
        $form = $this->ff->create(ComptoirInfosFormType::class, $comptoir, ['action' => $this->router->generate('comptoir_infos')]);

        return $form->createView();
    }

    public function getPrestataireInfosForm(User $user)
    {
        if (empty($user) || empty($this->session->get('_prestagere'))) {
            throw new \Exception('[FORM 4] Opération impossible !');
        }
        $presta = $this->session->get('_prestagere');
        $presta = $this->em->getRepository(Prestataire::class)->findOneById($presta->getId());
        // Disable enabled_filter to display all adresses
        if ($this->em->getFilters()->isEnabled('enabled_filter')) {
            $this->em->getFilters()->disable('enabled_filter');
        }
        $form = $this->ff->create(PrestataireInfosFormType::class, $presta, ['action' => $this->router->generate('prestataire_infos')]);

        return $form->createView();
    }

    public function getAdherentInfosForm(User $user)
    {
        if (empty($user) || empty($user->getAdherent())) {
            throw new \Exception('[FORM 5] Opération impossible !');
        }
        $form = $this->ff->create(AdherentInfosFormType::class, $user->getAdherent(), ['action' => $this->router->generate('adherent_infos')]);

        return $form->createView();
    }

    public function getGroupePrestataireInscriptionForm(User $user)
    {
        if (empty($user) || empty($this->session->get('_prestagere'))) {
            throw new \Exception('[FORM 6] Opération impossible !');
        }

        // At this point, the Prestataire entity is detached from the EntityManager (because we get it from the session)
        $presta = $this->session->get('_prestagere');
        // $presta now refers to the fully managed copy returned by the merge operation.
        $presta = $this->em->getRepository(Prestataire::class)->findOneById($presta->getId());

        $form = $this->ff->create(GroupePrestataireInscriptionFormType::class, $presta, ['action' => $this->router->generate('groupeprestataire_inscription')]);

        return $form->createView();
    }

    public function getTransactionAdherentAdherentForm(User $user)
    {
        if (empty($user) || empty($user->getAdherent())) {
            throw new \Exception('[FORM 7] Opération impossible !');
        }
        $entity = new TransactionAdherentAdherent();
        $entity->setOperateur($user);
        $entity->setExpediteur($user->getAdherent());
        $form = $this->ff->create(TransactionAdherentAdherentFormType::class, $entity, ['action' => $this->router->generate('transactionAdherentAdherent')]);

        return $form->createView();
    }

    public function getTransactionAdherentPrestataireForm(User $user)
    {
        if (empty($user) || empty($user->getAdherent())) {
            throw new \Exception('[FORM 8] Opération impossible !');
        }
        $entity = new TransactionAdherentPrestataire();
        $entity->setOperateur($user);
        $entity->setExpediteur($user->getAdherent());
        $form = $this->ff->create(TransactionAdherentPrestataireFormType::class, $entity, ['action' => $this->router->generate('transactionAdherentPrestataire')]);

        return $form->createView();
    }

    public function getTransactionPrestataireAdherentForm(User $user)
    {
        if (empty($user) || empty($this->session->get('_prestagere'))) {
            throw new \Exception('[FORM] Opération impossible !');
        }
        $entity = new TransactionPrestataireAdherent();
        $entity->setOperateur($user);
        $entity->setExpediteur($this->session->get('_prestagere'));
        $form = $this->ff->create(TransactionPrestataireAdherentFormType::class, $entity, ['action' => $this->router->generate('transactionPrestataireAdherent')]);

        return $form->createView();
    }

    public function getTransactionPrestatairePrestataireForm(User $user)
    {
        if (empty($user) || empty($this->session->get('_prestagere'))) {
            throw new \Exception('[FORM 9] Opération impossible !');
        }
        $entity = new TransactionPrestatairePrestataire();
        $entity->setOperateur($user);
        $entity->setExpediteur($this->session->get('_prestagere'));
        $form = $this->ff->create(TransactionPrestatairePrestataireFormType::class, $entity, ['action' => $this->router->generate('transactionPrestatairePrestataire')]);

        return $form->createView();
    }

    public function getReconversionForm(User $user)
    {
        if (empty($user) || empty($this->session->get('_prestagere'))) {
            throw new \Exception('[FORM 10] Opération impossible !');
        }
        $entity = new Reconversion();
        $entity->setExpediteur($this->session->get('_prestagere'));
        $form = $this->ff->create(ReconversionFormType::class, $entity, ['action' => $this->router->generate('transactionReconversion')]);

        return $form->createView();
    }

    public function getChangePrestataireComptoirForm(User $user)
    {
        if (empty($user) || empty($this->session->get('_comptoirgere'))) {
            throw new \Exception('[FORM 11] Opération impossible !');
        }
        $entity = new ChangePrestataireComptoir();
        $entity->setDestinataire($this->session->get('_comptoirgere'));
        $form = $this->ff->create(ChangePrestataireComptoirFormType::class, $entity, ['action' => $this->router->generate('changePrestataireComptoir')]);

        return $form->createView();
    }

    public function getChangeAdherentComptoirForm(User $user)
    {
        if (empty($user) || empty($this->session->get('_comptoirgere'))) {
            throw new \Exception('[FORM 11b] Opération impossible !');
        }
        $entity = new ChangeAdherentComptoir();
        $entity->setDestinataire($this->session->get('_comptoirgere'));
        $form = $this->ff->create(ChangeAdherentComptoirFormType::class, $entity, ['action' => $this->router->generate('changeAdherentComptoir')]);

        return $form->createView();
    }

    public function getRetraitComptoirToXForm(User $user, $type)
    {
        $type = strtolower($type);
        if (empty($user) || empty($this->session->get('_comptoirgere')) || !('adherent' == $type || 'groupe' == $type || 'prestataire' == $type)) {
            throw new \Exception('[FORM 12] Opération impossible !');
        }
        $class = "App\Entity\RetraitComptoir" . ucwords($type);
        $entity = new $class();
        $entity->setOperateur($user);
        $entity->setExpediteur($this->session->get('_comptoirgere'));
        $form = $this->ff->create('App\Form\Type\RetraitComptoir' . ucwords($type) . 'FormType', $entity, ['action' => $this->router->generate('retraitComptoir' . ucwords($type))]);

        return $form->createView();
    }

    public function getVenteComptoirToXForm(User $user, $type)
    {
        $type = strtolower($type);
        if (empty($user) || empty($this->session->get('_comptoirgere')) || !('adherent' == $type || 'groupe' == $type || 'prestataire' == $type)) {
            throw new \Exception('[FORM 12] Opération impossible !');
        }
        $class = "App\Entity\VenteComptoir" . ucwords($type);
        $entity = new $class();
        $entity->setOperateur($user);
        $entity->setExpediteur($this->session->get('_comptoirgere'));
        $form = $this->ff->create('App\Form\Type\VenteComptoir' . ucwords($type) . 'FormType', $entity, ['action' => $this->router->generate('venteComptoir' . ucwords($type))]);

        return $form->createView();
    }

    public function getTransfertComptoirGroupeForm(User $user)
    {
        if (empty($user) || empty($this->session->get('_groupegere'))) {
            throw new \Exception('[FORM 12] Opération impossible !');
        }
        $entity = new TransfertComptoirGroupe();
        $entity->setOperateur($user);
        $entity->setDestinataire($this->session->get('_groupegere'));
        $form = $this->ff->create(TransfertComptoirGroupeFormType::class, $entity, ['action' => $this->router->generate('transfertComptoirGroupe')]);

        return $form->createView();
    }

    public function getTransfertGroupeComptoirForm(User $user)
    {
        if (empty($user) || empty($this->session->get('_groupegere'))) {
            throw new \Exception('[FORM 13] Opération impossible !');
        }
        $entity = new TransfertGroupeComptoir();
        $entity->setOperateur($user);
        $entity->setExpediteur($this->session->get('_groupegere'));
        $form = $this->ff->create(TransfertGroupeComptoirFormType::class, $entity, ['action' => $this->router->generate('transfertGroupeComptoir')]);

        return $form->createView();
    }

    public function getTransfertSiegeGroupeForm(User $user)
    {
        if (empty($user) || !$user->hasRole('ROLE_ADMIN_SIEGE')) {
            throw new \Exception('[FORM 14] Opération impossible !');
        }
        $entity = new TransfertSiegeGroupe();
        $entity->setOperateur($user);
        $form = $this->ff->create(TransfertSiegeGroupeFormType::class, $entity, ['action' => $this->router->generate('transfertSiegeGroupe')]);

        return $form->createView();
    }

    public function getTransfertGroupeSiegeForm(User $user)
    {
        if (empty($user) || !$user->hasRole('ROLE_ADMIN_SIEGE')) {
            throw new \Exception('[FORM 15] Opération impossible !');
        }
        $entity = new TransfertGroupeSiege();
        $entity->setOperateur($user);
        $form = $this->ff->create(TransfertGroupeSiegeFormType::class, $entity, ['action' => $this->router->generate('transfertGroupeSiege')]);

        return $form->createView();
    }

    public function getSoldeSiegeForm(User $user)
    {
        if (empty($user) || !$user->hasRole('ROLE_ADMIN_SIEGE')) {
            throw new \Exception('[FORM 16] Opération impossible !');
        }
        $siege = $this->em->getRepository(Siege::class)->getTheOne();
        $form = $this->ff->create(SoldeSiegeFormType::class, $siege, ['action' => $this->router->generate('soldeSiege')]);

        return $form->createView();
    }

    public function getAchatMonnaieAdherentForm(User $user)
    {
        if (empty($user) || empty($user->getAdherent())) {
            throw new \Exception('[FORM 16] Opération impossible !');
        }
        $entity = new AchatMonnaieAdherent();
        $entity->setOperateur($user);

        $form = $this->ff->create(AchatMonnaieAdherentFormType::class, $entity, ['action' => $this->router->generate('achatMonnaieAdherent')]);

        return $form->createView();
    }

    public function getAchatMonnaiePrestataireForm(User $user)
    {
        if (empty($user) || empty($this->session->get('_prestagere'))) {
            throw new \Exception('[FORM 17] Opération impossible !');
        }
        $entity = new AchatMonnaiePrestataire();
        $entity->setOperateur($user);

        $form = $this->ff->create(AchatMonnaiePrestataireFormType::class, $entity, ['action' => $this->router->generate('achatMonnaiePrestataire')]);

        return $form->createView();
    }

    public function getVenteEmlcAdherentForm(User $user)
    {
        if (empty($user) || empty($this->session->get('_comptoirgere'))) {
            throw new \Exception('[FORM 18] Opération impossible !');
        }
        $entity = new AchatMonnaieAdherent();
        $entity->setOperateur($user);
        $form = $this->ff->create(VenteEmlcAdherentFormType::class, $entity, ['action' => $this->router->generate('venteEmlcAdherent')]);

        return $form->createView();
    }

    public function getVenteEmlcPrestataireForm(User $user)
    {
        if (empty($user) || empty($this->session->get('_comptoirgere'))) {
            throw new \Exception('[FORM 19] Opération impossible !');
        }
        $entity = new AchatMonnaiePrestataire();
        $entity->setOperateur($user);
        $form = $this->ff->create(VenteEmlcPrestataireFormType::class, $entity, ['action' => $this->router->generate('venteEmlcPrestataire')]);

        return $form->createView();
    }

    public function getAchatMonnaieAConfirmerAdherentForm(User $user)
    {
        if (empty($user) || empty($user->getAdherent())) {
            throw new \Exception('[FORM 20] Opération impossible !');
        }
        $entity = new AchatMonnaieAConfirmerAdherent();
        $entity->setOperateur($user);
        $form = $this->ff->create(AchatMonnaieAConfirmerAdherentFormType::class, $entity, ['action' => $this->router->generate('achatMonnaieAConfirmerAdherent')]);

        return $form->createView();
    }

    public function getAchatMonnaieAConfirmerPrestataireForm(User $user)
    {
        if (empty($user) || empty($this->session->get('_prestagere'))) {
            throw new \Exception('[FORM 21] Opération impossible !');
        }
        $entity = new AchatMonnaieAConfirmerPrestataire();
        $entity->setOperateur($user);
        $form = $this->ff->create(AchatMonnaieAConfirmerPrestataireFormType::class, $entity, ['action' => $this->router->generate('achatMonnaieAConfirmerPrestataire')]);

        return $form->createView();
    }

    public function getTicketFixPrintForm(User $user)
    {
        if (empty($user) || !$user->isGranted('ROLE_ADMIN_SIEGE')) {
            throw new \Exception('[FORM 22] Opération impossible !');
        }
        $entity = new TicketFixPrint();
        $entity->setOperateur($user);
        $form = $this->ff->create(TicketFixPrintFormType::class, $entity, ['action' => $this->router->generate('ticketFixPrint')]);

        return $form->createView();
    }

    public function getTicketFixDestroyForm(User $user)
    {
        if (empty($user) || !$user->isGranted('ROLE_ADMIN_SIEGE')) {
            throw new \Exception('[FORM 23] Opération impossible !');
        }
        $entity = new TicketFixDestroy();
        $entity->setOperateur($user);
        $form = $this->ff->create(TicketFixDestroyFormType::class, $entity, ['action' => $this->router->generate('ticketFixDestroy')]);

        return $form->createView();
    }

    public function getSetPaymentCodeForm(User $user)
    {
        if (empty($user) || !$user->isGranted('ROLE_ADHERENT')) {
            throw new \Exception('[FORM 23] Opération impossible !');
        }
        $form = $this->ff->create(SetPaymentCodeFormType::class, $user->getAdherent(), ['action' => $this->router->generate('adherentSetPaymentCode')]);

        return $form->createView();
    }
}
