<?php

namespace App\Controller;

use App\Entity\AchatMonnaieAConfirmerAdherent;
use App\Entity\AchatMonnaieAdherent;
use App\Entity\Adherent;
use App\Entity\GlobalParameter;
use App\Entity\Payment;
use App\Entity\TransactionAdherentAdherent;
use App\Entity\TransactionAdherentPrestataire;
use App\Form\Type\AchatMonnaieAConfirmerAdherentFormType;
use App\Form\Type\AchatMonnaieAdherentFormType;
use App\Form\Type\AdherentInfosFormType;
use App\Form\Type\TransactionAdherentAdherentFormType;
use App\Form\Type\TransactionAdherentPrestataireFormType;
use App\Form\Type\SetPaymentCodeFormType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class UserAdherentController extends FluxController
{
    /**
     * @Route("/adherent/infos", name="adherent_infos")
     * @IsGranted("ROLE_ADHERENT")
     */
    public function adherentInfosAction(Request $request)
    {
        $form = $this->createForm(AdherentInfosFormType::class, $this->getUser()->getAdherent());
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $this->em->persist($form->getData());
            $this->em->flush();
            $this->addFlash(
                'success',
                $this->translator->trans('Infos de l\'adhérent modifiées !')
            );
            $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("/adherent/transaction/prestataire/", name="transactionAdherentPrestataire")
     * @IsGranted("ROLE_ADHERENT")
     */
    public function transactionAdherentPrestataireAction(Request $request)
    {
        $entity = new TransactionAdherentPrestataire();
        $entity->setOperateur($this->getUser());
        $entity->setExpediteur($this->getUser()->getAdherent());
        $form = $this->createForm(TransactionAdherentPrestataireFormType::class, $entity);

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

    /**
     * @Route("/adherent/transaction/adherent/", name="transactionAdherentAdherent")
     * @IsGranted("ROLE_ADHERENT")
     */
    public function transactionAdherentAdherentAction(Request $request)
    {
        if (empty($this->getUser()) || empty($this->getUser()->getAdherent())) {
            return $this->redirectToRoute('index');
        }
        $entity = new TransactionAdherentAdherent();
        $entity->setOperateur($this->getUser());
        $entity->setExpediteur($this->getUser()->getAdherent());
        $form = $this->createForm(TransactionAdherentAdherentFormType::class, $entity);

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

    /**
     * @Route("/adherent/achat-monnaie/", name="achatMonnaieAdherent")
     * @IsGranted("ROLE_ADHERENT")
     */
    public function achatMonnaieAdherentAction(Request $request)
    {
        if (empty($this->getUser()) || empty($this->getUser()->getAdherent())) {
            return $this->redirectToRoute('index');
        }

        $entity = new AchatMonnaieAdherent();
        $form = $this->createForm(AchatMonnaieAdherentFormType::class, $entity);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            if ($form->has('payOther') && $form->get('payOther')->isClicked()) {
                return $this->redirectToRoute('achatMonnaieAConfirmerAdherent');
            } elseif ($form->has('save') && $form->get('save')->isClicked()) {
                return $this->preparePaymentAction(
                    $form,
                    Payment::TYPE_ACHAT_MONNAIE_ADHERENT
                );
            } elseif ($form->has('saveHelloAsso') && $form->get('saveHelloAsso')->isClicked()) {
                $url = $this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::HELLOASSO_URL_EMLC_ADHERENT);

                return $this->redirect($url);
            }
        }

        return $this->render('@kohinos/flux/transaction.html.twig', [
            'form' => $form->createView(),
            'title' => $this->translator->trans('Achat de monnaie locale'),
        ]);
    }

    /**
     * @Route("/adherent/paiement-cotis-tav/", name="paiementCotisTav")
     * @IsGranted("ROLE_ADHERENT")
     */
    public function paiementCotisTavAction(Request $request)
    {
        if (empty($this->getUser()) || empty($this->getUser()->getAdherent())) {
            return $this->redirectToRoute('index');
        }

        $entity = new AchatMonnaieAdherent();
        $form = $this->createForm(AchatMonnaieAdherentFormType::class, $entity);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            // TODO: set CB payment when the functionality is validated

            $flux = $form->getData();

            // Look for existing cotisation
            if ($this->tavCotisationsUtils->checkExistingCotisation($flux)) {
                $this->addFlash(
                    'error',
                    $this->translator->trans('Cotisation déjà payée ce mois-ci.')
                );

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

            $destinataire = $flux->getDestinataire();
            $profile = $destinataire->getProfilDeCotisation();

            if (is_null($profile)) {
                $this->addFlash(
                    'error',
                    $this->translator->trans('Opération impossible : vous n\'avez pas de profil de cotisation associé. Veuillez contacter un administrateur.')
                );

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

            if (null == $flux->getDon() || 0 == $flux->getDon()->getMontant()) {
                $flux->setDon(null);
            }

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

            // Apply cotisation rate, create new flux
            $this->tavCotisationsUtils->applyTauxCotisation($flux);
            
            $this->em->flush();
            $this->addFlash(
                'success',
                $this->translator->trans('Cotisation payée ! [Payzen désactivé en attent du compte]')
            );

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

        return $this->render('@kohinos/flux/transaction.html.twig', [
            'form' => $form->createView(),
            'title' => $this->translator->trans('Payer sa cotisation'),
        ]);
    }

    /**
     * @Route("/adherent/demande/achat-monnaie/", name="achatMonnaieAConfirmerAdherent")
     * @IsGranted("ROLE_ADHERENT")
     */
    public function achatMonnaieAConfirmerAdherentAction(Request $request)
    {
        if (empty($this->getUser()) || empty($this->getUser()->getAdherent())) {
            return $this->redirectToRoute('index');
        }
        $entity = new AchatMonnaieAConfirmerAdherent();
        $form = $this->createForm(AchatMonnaieAConfirmerAdherentFormType::class, $entity);

        return $this->manageFluxForm(
            $request,
            $form,
            '@kohinos/flux/demande_achat_monnaie.html.twig',
            ['title' => $this->translator->trans("Demande d'achat de monnaie locale numérique")]
        );
    }

    /**
     * @Route("/adherent/liste/demande/achat-monnaie/", name="listachatMonnaieAConfirmerAdherent")
     * @IsGranted("ROLE_ADHERENT")
     */
    public function listachatMonnaieAConfirmerAdherentAction(Request $request)
    {
        if (empty($this->getUser()) || empty($this->getUser()->getAdherent())) {
            return $this->redirectToRoute('index');
        }

        $q = $this->em->getRepository(AchatMonnaieAConfirmerAdherent::class)->findBy(['destinataire' => $this->getUser()->getAdherent()], ['createdAt' => 'DESC']);

        return $this->render('@kohinos/flux/list_demande_achat_monnaie.html.twig', [
            'datas' => $q,
        ]);
    }

    /**
     * @Route("/adherent/set-payment-code", name="adherentSetPaymentCode")
     * @IsGranted("ROLE_ADHERENT")
     */
    public function setPaymentCodeAction(Request $request)
    {
        $adherent = $this->getUser()->getAdherent();
        $form = $this->createForm(SetPaymentCodeFormType::class, $adherent);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $data = $form->getData();
            $plainCode = $data->getPaymentCode();

            if (ctype_digit($plainCode) && strlen($plainCode) >= 4 && strlen($plainCode) <= 8) {
                $encoded = crypt($plainCode, $this->getUser()->getSalt());

                $adherent->setPaymentCode($encoded);
    
                $this->em->flush();
                $this->addFlash(
                    'success',
                    $this->translator->trans('Code de paiement modifié !')
                );
            } else {
                $this->addFlash(
                    'error',
                    $this->translator->trans('Le code de paiement doit être composé de 4 à 8 chiffres.')
                );
            }
        }

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