<?php

namespace App\Controller;

use App\Entity\Adherent;
use App\Entity\CotisationAdherent;
use App\Entity\CotisationPrestataire;
use App\Entity\GlobalParameter;
use App\Entity\Payment;
use App\Entity\Prestataire;
use App\Entity\User;
use App\Enum\MoyenEnum;
use App\Form\Type\CotiserFormType;
use App\Form\Type\DonAdherentFormType;
use App\Form\Type\DonPrestataireFormType;
use App\Form\Type\UserInfosFormType;
use App\Utils\CotisationUtils;
use App\Utils\OperationUtils;
use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Translation\TranslatorInterface;

class UserController extends AbstractController
{
    private $em;
    private $translator;
    private $security;
    private $operationUtils;
    private $cotisationUtils;

    public function __construct(EntityManagerInterface $em, TranslatorInterface $translator, Security $security, OperationUtils $operationUtils, CotisationUtils $cotisationUtils)
    {
        $this->em = $em;
        $this->translator = $translator;
        $this->security = $security;
        $this->operationUtils = $operationUtils;
        $this->cotisationUtils = $cotisationUtils;
    }

    /**
     * @Route("/cotiser", name="cotiser", defaults={"type": "null"})
     * @Route("/cotiser/next", name="cotisernextyear", defaults={"type": "nextyear"})
     * @IsGranted("ROLE_USER")
     */
    public function cotiserAction($type, Request $request)
    {
        $options = [];
        $payment_type = '';
        if ($this->security->isGranted('ROLE_ADHERENT')) {
            $options['data_class'] = CotisationAdherent::class;
            $options['don_class'] = DonAdherentFormType::class;
            $payment_type = Payment::TYPE_COTISATION_ADHERENT;
        } elseif ($this->security->isGranted('ROLE_PRESTATAIRE')) {
            $options['data_class'] = CotisationPrestataire::class;
            $options['don_class'] = DonPrestataireFormType::class;
            $payment_type = Payment::TYPE_COTISATION_PRESTA;
        }

        $form = $this->createForm(CotiserFormType::class, null, $options);
        $form->handleRequest($request);
        if ('nextyear' === $type) {
            $nextYear = new \DateTime('+1 year');
            $startDate = $this->cotisationUtils->isCotisationValid($this->getUser());
            $endDate = new \DateTime(date('Y-m-d H:i:s', strtotime('+1 year', strtotime($startDate->format('Y-m-d H:i:s')))));
            $kohYear = (string) $endDate->format('Y');
        } else {
            $now = new \DateTime();
            $kohYear = (string) $now->format('Y');
        }

        if ($form->isSubmitted()) {
            $cotisation = $form->getData();
            if ($form->isValid()) {
                //Manage don if null => delete it !
                if ($cotisation->getDon() && 0 == $cotisation->getDon()->getMontant()) {
                    $cotisation->setDon(null);
                }
                if ('nextyear' === $type) {
                    // Cotiser pour l'année suivante
                    $startDate = $this->cotisationUtils->isCotisationValid($this->getUser());
                    $cotisation->getCotisationInfos()->setDebut($startDate);
                    $endDate = new \DateTime(date('Y-m-d H:i:s', strtotime('+1 year', strtotime($startDate->format('Y-m-d H:i:s')))));
                    $cotisation->getCotisationInfos()->setFin($endDate);
                    $cotisation->getCotisationInfos()->setAnnee((string) $endDate->format('Y'));
                }
                if (MoyenEnum::MOYEN_EMLC == $cotisation->getMoyen()) {
                    try {
                        $cotisation->setRecu(true);
                        $this->operationUtils->executeOperations($cotisation);
                        $this->addFlash(
                            'success',
                            // "Cotisation pour l'année {$cotisation->getCotisationInfos()->getAnnee()} bien reçue. Merci !"
                            $this->translator->trans('Cotisation bien reçue. Merci !')
                        );
                    } catch (\Exception $e) {
                        $this->addFlash(
                            'error',
                            $this->translator->trans('Problème avec la cotisation !') . ' ' . $e->getMessage()
                        );
                    }

                    return $this->redirectToRoute('index');
                } elseif (MoyenEnum::MOYEN_HELLOASSO == $cotisation->getMoyen()) {
                    if ($this->security->isGranted('ROLE_ADHERENT')) {
                        $url = $this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::HELLOASSO_URL_COTISATION_ADHERENT);
                    } else {
                        $url = $this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::HELLOASSO_URL_COTISATION_PRESTATAIRE);
                    }

                    return $this->redirect($url);
                } elseif (MoyenEnum::MOYEN_CB == $cotisation->getMoyen()) {
                    // Redirect to payment page
                    return $this->forward('App\Controller\FluxController::preparePaymentAction', [
                        'form' => $form,
                        'type' => $payment_type,
                    ]);
                }
            } else {
                $this->addFlash(
                    'error',
                    $this->translator->trans('Problème avec la cotisation !') . ' ' . $form->getErrors()
                );
            }
        }

        return $this->render('@kohinos/cotiser.html.twig', [
            'form' => $form->createView(),
            'koh_year' => $kohYear,
        ]);
    }

    /**
     * @Route("/userinfos", name="user_infos")
     * @IsGranted("ROLE_USER")
     */
    public function userInfosAction(Request $request)
    {
        $form = $this->createForm(UserInfosFormType::class, $this->getUser());
        $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'utilisateur modifiée !")
            );
            $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');
        // return $this->render('@kohinos/presta/infos.html.twig', array(
        //     'form' => $form->createView()
        // ));
    }

    /**
     * @Route("/account/user", name="myaccount")
     * @IsGranted("ROLE_USER")
     */
    public function myaccountAction(Request $request)
    {
        return $this->render('@kohinos/common/myaccount.html.twig', [
        ]);
    }

    /**
     * @Route("/search/adherent", methods="GET", name="searchadherent")
     * @IsGranted("ROLE_USER")
     */
    public function searchAdherentAction(Request $request)
    {
        $term = $request->get('term');
        $result = $this->em->getRepository(Adherent::class)->findsByData(['email' => $term, 'name' => $term]);
        $arrayData = [];
        foreach ($result as $adherent) {
            $arrayData[] = ['id' => $adherent->getId(), 'text' => $adherent->__toString()];
        }

        return new JsonResponse(['results' => $arrayData]);
    }

    /**
     * @Route("/user/achatMonnaieAConfirmer", name="achatMonnaieAConfirmer")
     * @IsGranted({"ROLE_ADHERENT", "ROLE_PRESTATAIRE"})
     */
    public function achatMonnaieAConfirmerAction(Request $request)
    {
        $obj = $this->operationUtils->getCurrentAccountable($this->security->getUser());
        if ($obj instanceof Prestataire) {
            return $this->redirectToRoute('achatMonnaieAConfirmerPrestataire');
        } elseif ($obj instanceof Adherent) {
            return $this->redirectToRoute('achatMonnaieAConfirmerAdherent');
        }

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

    /**
     * @Route("/user/listachatMonnaieAConfirmer", name="listachatMonnaieAConfirmer")
     * @IsGranted({"ROLE_ADHERENT", "ROLE_PRESTATAIRE"})
     */
    public function listachatMonnaieAConfirmerAction(Request $request)
    {
        $obj = $this->operationUtils->getCurrentAccountable($this->security->getUser());
        if ($obj instanceof Prestataire) {
            return $this->redirectToRoute('listachatMonnaieAConfirmerPrestataire');
        } elseif ($obj instanceof Adherent) {
            return $this->redirectToRoute('listachatMonnaieAConfirmerAdherent');
        }

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