<?php

namespace App\Controller;

use App\Entity\Adherent;
use App\Entity\ChangeAdherentComptoir;
use App\Entity\ChangePrestataireComptoir;
use App\Entity\Comptoir;
use App\Entity\DonAdherent;
use App\Entity\RetraitComptoirAdherent;
use App\Entity\RetraitComptoirPrestataire;
use App\Entity\VenteComptoirAdherent;
use App\Entity\VenteComptoirPrestataire;
use App\Entity\VenteEmlcComptoirAdherent;
use App\Entity\VenteEmlcComptoirPrestataire;
use App\Form\Type\ChangeAdherentComptoirFormType;
use App\Form\Type\ChangePrestataireComptoirFormType;
use App\Form\Type\ComptoirEncaisserDonAdherentFormType;
use App\Form\Type\ComptoirInfosFormType;
use App\Form\Type\RetraitComptoirAdherentFormType;
use App\Form\Type\RetraitComptoirPrestataireFormType;
use App\Form\Type\VenteComptoirAdherentFormType;
use App\Form\Type\VenteComptoirPrestataireFormType;
use App\Form\Type\VenteEmlcAdherentFormType;
use App\Form\Type\VenteEmlcPrestataireFormType;
use App\Form\Type\EncaisserCotisationAdherentFormType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class UserComptoirController extends FluxController
{
    /**
     * @Route("/user/comptoir/infos", name="comptoir_infos")
     * @IsGranted("ROLE_COMPTOIR")
     */
    public function comptoirInfosAction(Request $request)
    {
        $comptoir = $this->session->get('_comptoirgere');
        $comptoir = $this->em->getRepository(Comptoir::class)->findOneById($comptoir->getId());
        $form = $this->createForm(ComptoirInfosFormType::class, $comptoir);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $data = $form->getData();
            $this->em->persist($form->getData());
            $this->em->flush();
            $this->addFlash(
                'success',
                $this->translator->trans('Informations du comptoir bien modifiées !')
            );
            $this->session->set('_comptoirgere', $comptoir);
            $referer = $request->headers->get('referer');
            if ($referer && !$request->isXmlHttpRequest()) {
                return $this->redirect($referer);
            } elseif (!$request->isXmlHttpRequest()) {
                return new Response('', Response::HTTP_BAD_REQUEST);
            }
        }

        return $this->redirectToRoute('index');
    }

    /**
     * @Route("/user/comptoir/vente/adherent/", name="venteComptoirAdherent")
     * @IsGranted("ROLE_COMPTOIR")
     */
    public function venteComptoirAdherentAction(Request $request)
    {
        $entity = new VenteComptoirAdherent();
        $entity->setOperateur($this->getUser());
        $form = $this->createForm(VenteComptoirAdherentFormType::class, $entity);

        return $this->manageFluxForm(
            $request,
            $form
        );
    }

    /**
     * @Route("/user/comptoir/vente/prestataire/", name="venteComptoirPrestataire")
     * @IsGranted("ROLE_COMPTOIR")
     */
    public function venteComptoirPrestataireAction(Request $request)
    {
        $entity = new VenteComptoirPrestataire();
        $entity->setOperateur($this->getUser());
        $form = $this->createForm(VenteComptoirPrestataireFormType::class, $entity);

        return $this->manageFluxForm(
            $request,
            $form
        );
    }

    /**
     * @Route("/user/comptoir/retrait/adherent/", name="retraitComptoirAdherent")
     * @IsGranted("ROLE_COMPTOIR")
     */
    public function retraitComptoirAdherentAction(Request $request)
    {
        $entity = new RetraitComptoirAdherent();
        $entity->setOperateur($this->getUser());
        $form = $this->createForm(RetraitComptoirAdherentFormType::class, $entity);

        return $this->manageFluxForm(
            $request,
            $form
        );
    }

    /**
     * @Route("/user/comptoir/retrait/prestataire/", name="retraitComptoirPrestataire")
     * @IsGranted("ROLE_COMPTOIR")
     */
    public function retraitComptoirPrestataireAction(Request $request)
    {
        $entity = new RetraitComptoirPrestataire();
        $entity->setOperateur($this->getUser());
        $form = $this->createForm(RetraitComptoirPrestataireFormType::class, $entity);

        return $this->manageFluxForm(
            $request,
            $form
        );
    }

    /**
     * @Route("/user/comptoir/change/prestataire/", name="changePrestataireComptoir")
     * @IsGranted("ROLE_COMPTOIR")
     */
    public function changePrestataireComptoirAction(Request $request)
    {
        $entity = new ChangePrestataireComptoir();
        $entity->setOperateur($this->getUser());
        $form = $this->createForm(ChangePrestataireComptoirFormType::class, $entity);

        return $this->manageFluxForm(
            $request,
            $form
        );
    }

    /**
     * @Route("/user/comptoir/change/adherent/", name="changeAdherentComptoir")
     * @IsGranted("ROLE_COMPTOIR")
     */
    public function changeAdherentComptoirAction(Request $request)
    {
        $entity = new ChangeAdherentComptoir();
        $entity->setOperateur($this->getUser());
        $form = $this->createForm(ChangeAdherentComptoirFormType::class, $entity);

        return $this->manageFluxForm(
            $request,
            $form
        );
    }

    /**
     * @Route("/user/comptoir/vente/emlc/adherent/", name="venteEmlcAdherent")
     * @IsGranted("ROLE_COMPTOIR")
     */
    public function venteEmlcAdherentAction(Request $request)
    {
        $entity = new VenteEmlcComptoirAdherent();
        $entity->setOperateur($this->getUser());
        $form = $this->createForm(VenteEmlcAdherentFormType::class, $entity);

        return $this->manageFluxForm(
            $request,
            $form
        );
    }

    /**
     * @Route("/user/comptoir/vente/emlc/prestataire/", name="venteEmlcPrestataire")
     * @IsGranted("ROLE_COMPTOIR")
     */
    public function venteEmlcPrestataireAction(Request $request)
    {
        $entity = new VenteEmlcComptoirPrestataire();
        $entity->setOperateur($this->getUser());
        $form = $this->createForm(VenteEmlcPrestataireFormType::class, $entity);

        return $this->manageFluxForm(
            $request,
            $form
        );
    }

    /**
     * @Route("/user/comptoir/encaisser/cotisation/adherent/", name="comptoirEncaisserCotisation")
     * @IsGranted("ROLE_COMPTOIR")
     */
    public function comptoirEncaisserCotisationAction(Request $request)
    {
        $entity = new VenteEmlcComptoirAdherent();
        $entity->setOperateur($this->getUser());
        $form = $this->createForm(EncaisserCotisationAdherentFormType::class, $entity);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $flux = $form->getData();

            // Look for existing cotisation
            if ($reason = $this->tavCotisationUtils->preventCotisationDuplication($flux->getDestinataire())) {
                $this->addFlash(
                    'error',
                    $this->translator->trans($reason)
                );

                return $this->redirectToRoute('index');
            }

            $destinataire = $flux->getDestinataire();

            $allocationMethod = $this->tavCotisationUtils->getAppropriateAllocationMethod($destinataire);

            // Some code duplication between household_based_allowance && simplified_household_based_allowance, for better readability
            if ($allocationMethod == 'simplified_household_based_allowance') {
                /* Process: simplified allowance based on household */
                $cotisationAmount = $destinataire->getCotisationAmount();

                // Verifications
                if (is_null($cotisationAmount) || is_null($destinataire->getHouseholdCount()) ) {
                    $this->addFlash(
                        'error',
                        $this->translator->trans("Opération impossible : le profil de l'habitant.e est incomplet, veuillez le compléter dans l'interface d'administration.")
                    );

                    return $this->redirectToRoute('index');
                }

                $flux->setMontant($cotisationAmount);
                $this->em->persist($flux);
                $this->operationUtils->executeOperations($flux);

                // Create new flux based on difference with cotisation amount
                $this->tavCotisationUtils->applyHouseholdAllowance($flux);
            } else if ($allocationMethod == 'household_based_allowance') {
                /* Process: allowance based on household */
                $cotisationAmount = $destinataire->getCotisationAmount();

                // Verifications
                if (is_null($cotisationAmount) || is_null($destinataire->getHouseholdAdultCount()) ) {
                    $this->addFlash(
                        'error',
                        $this->translator->trans("Opération impossible : le profil de l'habitant.e est incomplet, veuillez le compléter dans l'interface d'administration.")
                    );

                    return $this->redirectToRoute('index');
                }

                $flux->setMontant($cotisationAmount);
                $this->em->persist($flux);
                $this->operationUtils->executeOperations($flux);

                // Create new flux based on difference with cotisation amount
                $this->tavCotisationUtils->applyHouseholdAllowance($flux);
            } else {
                /* Process: allowance based on cotisation profile with cotisation rate */
                $profile = $destinataire->getProfilDeCotisation();

                if (is_null($profile)) {
                    $this->addFlash(
                        'error',
                        $this->translator->trans('Opération impossible : l\'habitant.e n\'a pas de profil de cotisation associé.')
                    );

                    return $this->redirectToRoute('index');
                }

                $cotisationAmount = $profile->getMontant();  // Amount in € paid by the user
                $flux->setMontant($cotisationAmount);
                
                $this->em->persist($flux);
                $this->operationUtils->executeOperations($flux);

                // Apply cotisation rate, create new flux
                $this->tavCotisationUtils->applyTauxCotisation($flux);
            }

            $this->em->flush();
            
            $this->addFlash(
                'success',
                $this->translator->trans('Opération réussie !')
            );
        }

        return $this->redirectToRoute('index');
    }

    /**
     * @Route("/user/comptoir/encaisser/don/adherent/", name="comptoirEncaisserDonAdherent")
     * @IsGranted("ROLE_COMPTOIR")
     */
    public function comptoirEncaisserDonAdherentAction(Request $request)
    {
        $entity = new DonAdherent();
        $entity->setOperateur($this->getUser());
        $form = $this->createForm(ComptoirEncaisserDonAdherentFormType::class, $entity);
        $form->handleRequest($request);

        if ($form->isSubmitted()) {
            if($form->isValid()) {
                $flux = $form->getData();
                $this->em->persist($flux);
                $this->operationUtils->executeOperations($flux);
                $this->em->flush();

                $this->addFlash(
                    'success',
                    $this->translator->trans('Opération réussie !')
                );
            } else {
                $this->addFlash(
                    'error',
                    $this->translator->trans('Erreur : le don n\'a pas été enregistré.')
                );
            }
        }

        return $this->redirectToRoute('index');
    }
}
