<?php

namespace App\Controller;

use App\Entity\Commune;
use App\Entity\Department;
use App\Entity\User;
use App\Entity\Ministry;
use App\Entity\Menu;
use App\Entity\Document;
use App\Entity\Newsletter;
use App\Form\UserType;
use App\Form\User2Type;
use App\Form\ResettingType;
use App\Form\MenuType;
use App\Form\SettingsType;
use App\Form\DocumentType;
use App\Form\StaticFileType;
use App\Service\SettingsManager;
use Craue\ConfigBundle\Util\Config as CraueConfig;
use PhpParser\Node\Stmt\Nop;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;

use Symfony\Component\Routing\RouterInterface;

class AdminController extends AbstractController
{
    private $craueConfig;

    public function __construct(CraueConfig $craueConfig)
    {
        $this->craueConfig = $craueConfig;
    }

    /**
     * @Route("/app/users", name="app_users")
    
     */
    //  @IsGranted({"ROLE_ADMIN"})
    public function usersAction(Request $request)
    {
        $users = $this->getDoctrine()
            ->getRepository(User::class)
            ->findBy([], ['id' => 'DESC']);

        return $this->render('admin/user_list.html.twig', [
            'users' => $users,
        ]);
    }

    /**
     * @Route("/app/users/new", name="app_user_new")
    
     */
    //  @IsGranted({"ROLE_ADMIN"})
    public function userAddAction(Request $request, UserPasswordEncoderInterface $passwordEncoder)
    {
        $user = new User();
        $user->setEnabled(true);

        $form = $this->createForm(UserType::class, $user, [
            'sessionYear' => $request->getSession()->get('_year'),
        ]);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $user = $form->getData();
            $user->addRole($form->get('role')->getData());

            $user->setPassword(
                $passwordEncoder->encodePassword(
                    $user,
                    'SigOdd@2o3o'
                )
            );

            $this->getDoctrine()->getManagerForClass(User::class)->persist($user);
            $this->getDoctrine()->getManagerForClass(User::class)->flush();

            $this->addFlash('success', "Utilisateur ajouté avec succès");

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

        return $this->render('admin/user_form.html.twig', [
            'form' => $form->createView(),
            'user' => $user,
            'show' => true,
            'type' => -1,
        ]);
    }

    /**
     * @Route("/app/users/{id}", name="app_user")
    
     */
    //  @IsGranted({"ROLE_ADMIN"})
    public function userAction($id, Request $request)
    {
        $user = $this->getDoctrine()
            ->getRepository(User::class)
            ->findOneBy(['id' => $id]);

        // Roles that can be edited by admin
        $editableRoles = ['ROLE_ADMIN', 'ROLE_MANAGER','ROLE_INSTAD','ROLE_CSPAT', 'ROLE_DDD','ROLE_DPP', 'ROLE_FOCAL'];

        $originalRoles = array_filter($user->getRoles(), function($role) use ($editableRoles) {
            return in_array($role, $editableRoles);
        });

        $type=null;
        $structure=null;
        if($user->hasRole('ROLE_DDD')||$user->hasRole('ROLE_CSPAT')){
            $type=2;
            $structure=$this->getDoctrine()->getRepository(Department::class)->findOneBy(['id' => $user->getDepartment()->getId()]);
        }else if($user->getCommune()){
            $type=1;
            $structure=$this->getDoctrine()->getRepository(Commune::class)->findOneBy(['id' => $user->getCommune()->getId()]);
        }else if($user->hasRole('ROLE_MANAGER')){
            $type=-1;
            $structure= null;
        }else{
            $type=0;
            $structure=$user->getDirection() ? $user->getDirection()->getMinistry() : null;
        }

        $editForm = $this->createForm(UserType::class, $user, [
            'with_roles' => true,
            'editable_roles' => $editableRoles,
            'type' => $type,
            'structure' => $structure,
        ]);

        $editForm->handleRequest($request);

        if ($editForm->isSubmitted() && $editForm->isValid()) {

            $user = $editForm->getData();

            $roles = $editForm->get('roles')->getData();

            $rolesToRemove = array_diff($originalRoles, $roles);

            foreach ($rolesToRemove as $role) {
                $user->removeRole($role);
            }

            foreach ($roles as $role) {
                if (!$user->hasRole($role)) {
                    $user->addRole($role);
                }
            }

            $this->getDoctrine()->getManagerForClass(User::class)->persist($user);
            $this->getDoctrine()->getManagerForClass(User::class)->flush();

            /*$this->addFlash(
                'notice',
                'global.changesSaved'
            );*/
            $this->addFlash('success', 'Utilisateur modifié avec succès');
            return $this->redirectToRoute('app_users');
        }

        return $this->render('admin/user_form.html.twig', [
            'form' => $editForm->createView(),
            'user' => $user,
            'show' => false,
            'type' => $type,
        ]);
    }

    /**
     * @Route("/app/users/{id}/profile", name="app_user_profile")
     */
    public function userProfileAction($id, Request $request, UserPasswordEncoderInterface $passwordEncoder)
    {
        $user = $this->getDoctrine()
            ->getRepository(User::class)
            ->findOneBy(['id' => $id]);

        $form = $this->createForm(User2Type::class, $user);
        $form_reset = $this->createForm(ResettingType::class);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $user = $form->getData();

            $this->getDoctrine()->getManagerForClass(User::class)->flush();
            $this->addFlash('success', 'Modification effectuée avec succès');
            return $this->redirectToRoute('app_user_profile', ['id' => $user->getId()]);
        }

        $form_reset->handleRequest($request);
        if ($form_reset->isSubmitted() && $form_reset->isValid()) {

            $old=$passwordEncoder->encodePassword($user,$form_reset->get('password')->getData());
            if($old==$user->getPassword()){
            $user->setPassword(
                $passwordEncoder->encodePassword(
                    $user,
                    $form_reset->get('plainPassword')->getData()
                )
            );

            $this->getDoctrine()->getManagerForClass(User::class)->persist($user);
            $this->getDoctrine()->getManagerForClass(User::class)->flush();

            return $this->redirectToRoute('app_logout');
            }else{
                $this->addFlash('error', "Une erreur s'est produite");
                return $this->redirectToRoute('app_user_profile', ['id' => $user->getId()]);
            };
        }

        return $this->render('admin/user_profile.html.twig', [
            'user' => $user,
            'form' => $form->createView(),
            'form_reset' => $form_reset->createView(),
        ]);
    }

    /** 
     * @Route("/app/users/{id}/resetting", name="app_user_resetting")
     */
    public function userResettingAction($id, Request $request, UserPasswordEncoderInterface $passwordEncoder)
    {
        $user = $this->getDoctrine()
            ->getRepository(User::class)
            ->findOneBy(['id' => $id]);
            
        $form = $this->createForm(ResettingType::class);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $old=$passwordEncoder->encodePassword($user,$form->get('password')->getData());
            if($old==$user->getPassword()){
            $user->setPassword(
                $passwordEncoder->encodePassword(
                    $user,
                    $form->get('plainPassword')->getData()
                )
            );

            $this->getDoctrine()->getManagerForClass(User::class)->persist($user);
            $this->getDoctrine()->getManagerForClass(User::class)->flush();

            return $this->redirectToRoute('app_logout');
            }else{
                $this->addFlash('error', 'Une erreur s\'est produite');
                return $this->redirectToRoute('app_user_profile');
            }
        }

        return $this->render('admin/user_resetting.html.twig', [
            'form' => $form->createView()
        ]);
    }


    /**
     * @Route("/app/user/{id}/delete", name="app_user_delete")
     * 
     */
    //@IsGranted({"ROLE_ADMIN"})
    public function deleteUserAction($id, Request $request)
    {
        try {
            $user = $this->getDoctrine()->getRepository(User::class)->find($id);
            $this->getDoctrine()->getManager()->remove($user);
            $this->getDoctrine()->getManager()->flush();
        } catch (\Exception $e) {
            dd($e);
            $this->addFlash('error', 'Une erreur s\'est produite. Veuillez réssayer ou contacter le développeur');
            return $this->redirectToRoute('app_users');
        }
        $this->addFlash('success', 'Utilisateur supprimé avec succès');
        return $this->redirectToRoute('app_users');
    }

    /**
     * @Route("/app/user/{id}/reinit", name="app_user_reinit")
     * 
     */
    //@IsGranted({"ROLE_ADMIN"})
    public function reinitUserAction($id, Request $request, UserPasswordEncoderInterface $passwordEncoder, SettingsManager $settingsManager)
    {
        try {
            $user = $this->getDoctrine()->getRepository(User::class)->find($id);
            $user->setPassword(
                $passwordEncoder->encodePassword(
                    $user,
                    'SigOdd@2o3o'
                )
            );
            $this->getDoctrine()->getManagerForClass(User::class)->persist($user);
            $this->getDoctrine()->getManager()->flush();

            /*if($user){
                $link = $this->generateUrl(
                    'app_reinitialisation', [
                        'id'=>$settingsManager->encryptid($user->getId())
                    ],
                    UrlGeneratorInterface::ABSOLUTE_URL
                );

                $content='
                    <h3>SIG-ODD</h3>
                    <p>Votre mot de passe a été réinitialisé avec succès. Utilisez le lien suivant pour créer un nouveau mot de passe.</p>
                    <a href=" '.$link.' ">Réinitialiser votre mot de passe.</a>';
                    
                    $email = (new Email())
                    ->from('noreply.sigodd@gouv.bj')
                    ->to($user->getEmail())
                    ->subject('Réinitialisation du mot de passe')
                    ->html($content);

                $mailer->send($email);
            }*/
        } catch (\Exception $e) {
            $this->addFlash('error', 'Une erreur s\'est produite. Veuillez réssayer ou contacter le développeur');
            return $this->redirectToRoute('app_users');
        }
        $this->addFlash('success', 'Mot de passe reinitialisé avec succès');
        return $this->redirectToRoute('app_users');
    }

    
    /**
     * @Route("/app/documents", name="app_documents")
     * 
     */
    //@IsGranted({"ROLE_ADMIN"})
    public function documentsAction()
    {
        $documents = $this->getDoctrine()->getRepository(Document::class)->findAll();

        return $this->render('admin/document_list.html.twig', [
            'documents' => $documents,
        ]);
    }


    /**
     * @Route("/app/documents/new", name="app_document_new")
     * 
     */
    //@IsGranted({"ROLE_ADMIN"})
    public function newDocumentAction(Request $request)
    {
        $document = new Document();

        $form = $this->createForm(DocumentType::class, $document);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $document = $form->getData();

            $this->getDoctrine()->getManagerForClass(Document::class)->persist($document);
            $this->getDoctrine()->getManagerForClass(Document::class)->flush();

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

        return $this->render('admin/document_form.html.twig', [
            'document' => $document,
            'form' => $form->createView(),
        ]);
    }

    /**
     * @Route("/app/documents/{id}", name="app_document")
    
     */
    //  @IsGranted({"ROLE_ADMIN"})
    public function documentAction($id, Request $request)
    {
        $document = $this->getDoctrine()
            ->getRepository(Document::class)
            ->findOneBy(['id' => $id]);

        $form = $this->createForm(DocumentType::class, $document);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $document = $form->getData();

            $this->getDoctrine()->getManagerForClass(Document::class)->flush();

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

        return $this->render('admin/document_form.html.twig', [
            'document' => $document,
            'form' => $form->createView(),
        ]);
    }

    /**
     * @Route("/app/settings", name="app_settings")
     
     */
    // @IsGranted({"ROLE_ADMIN"})
    public function settingsAction(Request $request, SettingsManager $settingsManager)
    {
        $settings = $settingsManager->asEntity();
        $form = $this->createForm(SettingsType::class, $settings);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {

            $data = $form->getData();

            foreach ($data as $name => $value) {
                $settingsManager->set($name, $value);
            }

            $settingsManager->flush();

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

        return $this->render('admin/settings.html.twig', [
            'timezone' => ini_get('date.timezone'),
            'form' => $form->createView(),
        ]);
    }


    /**
     * @Route("/app/menus", name="app_menus")
     
     */
    // @IsGranted({"ROLE_ADMIN"})
    public function menusAction()
    {
        $menus = $this->getDoctrine()->getRepository(Menu::class)->findAll();

        return $this->render('admin/menu_list.html.twig', [
            'menus' => $menus,
        ]);
    }

    /**
     * @Route("/app/menus/new", name="app_menu_new")
     
     */
    // @IsGranted({"ROLE_ADMIN"})
    public function newMenuAction(Request $request, RouterInterface $router)
    {
        $menu = new Menu();

        $routes = [];
        $routeCollection = $router->getRouteCollection()->all();
        foreach ($routeCollection as $key => $route) {
            if ( (substr($route->getPath(), 0, 5) == '/app/') ) {
                $routes[$route->getPath()] = $key;
            }
        }

        $form = $this->createForm(MenuType::class, $menu, [
            'routes' => $routes,
        ]);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $menu = $form->getData();

            $this->getDoctrine()->getManagerForClass(Menu::class)->persist($menu);
            $this->getDoctrine()->getManagerForClass(Menu::class)->flush();

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

        return $this->render('admin/menu_form.html.twig', [
            'menu' => $menu,
            'form' => $form->createView(),
        ]);
    }

    /**
     * @Route("/app/menus/{id}", name="app_menu")
     
     */
    // @IsGranted({"ROLE_ADMIN"})
    public function menuAction($id, Request $request, RouterInterface $router)
    {
        $menu = $this->getDoctrine()
            ->getRepository(Menu::class)
            ->findOneBy(['id' => $id]);

        $routes = [];
        $routeCollection = $router->getRouteCollection()->all();
        foreach ($routeCollection as $key => $route) {
            if ( (substr($route->getPath(), 0, 5) == '/app/') ) {
                $routes[$route->getPath()] = $key;
            }
        }

        $form = $this->createForm(MenuType::class, $menu, [
            'routes' => $routes,
        ]);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $menu = $form->getData();

            $this->getDoctrine()->getManagerForClass(Menu::class)->flush();

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

        return $this->render('admin/menu_form.html.twig', [
            'menu' => $menu,
            'form' => $form->createView(),
        ]);
    }

    /**
     * @Route("/app/gestion1", name="app_gestion1")
    
     */
    public function gestionAction(Request $request)
    {
        return $this->redirect($request->headers->get('referer'));
    }

    /**
     * @Route("/app/newsletter", name="app_newsletter")
    
     */
    public function newsletterAction(Request $request)
    {
        if($request->request->get('newsletter_email')){
            $email = $this->getDoctrine()->getRepository(Newsletter::class)->findOneBy(['email' => $request->request->get('newsletter_email')]);
            if($email){
                $message="Vous êtes déjà inscrit à notre newsletter. Merci pour la confiance.";
            }else{
                $newsletter = new Newsletter();
                $newsletter->setCreatedAt(new \DateTime("now"));
                $newsletter->setEmail($request->request->get('newsletter_email'));
                $newsletter->setStatus(true);
                $this->getDoctrine()->getManager()->persist($newsletter);
                $this->getDoctrine()->getManager()->flush();
                $message="Inscription à la newsletter de la DGCS-ODD réussie. Merci pour la confiance.";
            }
            return $this->render('frontend/newsletter.html.twig', [
                'message' => $message,
            ]);
        }else{
            return $this->redirectToRoute('index');
        }
        

    }

    /**
     * @Route("/app/files", name="app_files")
    
     */
    //  @IsGranted({"ROLE_ADMIN"})
    public function filesAction()
    {
        $files = []; //$this->getDoctrine()->getRepository(Menu::class)->findAll();
        $dirname = '../templates/html/';
        $dir = opendir($dirname);

        while($filename = readdir($dir)) {
            if($filename != '.' && $filename != '..' && !is_dir($dirname.$filename)) {
                $filenames[] = $filename;
            }
        }
        closedir($dir);

        return $this->render('admin/file_list.html.twig', [
            'filenames' => $filenames,
        ]);
    }


    /**
     * @Route("/app/files/{filename}", name="app_filename")
    
     */
    //  @IsGranted({"ROLE_ADMIN"})
    public function fileAction($filename, Request $request, RouterInterface $router)
    {
        $filename = '../templates/html/'.$filename;
        $handle = fopen($filename, "rb");
        $content = fread($handle, filesize($filename));
        fclose($handle);

        $form = $this->createForm(StaticFileType::class, null,[
            'content' => $content
        ]);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $content = $form->get('content')->getData();

            if (is_writable($filename)) {

                if (!$handle = fopen($filename, 'w')) {
                    $this->addFlash('error', "Impossible d'ouvrir le fichier ($filename)");
                     exit;
                }

                if (fwrite($handle, $content) === FALSE) {
                    $this->addFlash('error', "Impossible d'écrire dans le fichier ($filename)");
                    exit;
                }
            
                $this->addFlash('notice', "L'écriture dans le fichier ($filename) a réussi");
            
                fclose($handle);
            
            } else {
                echo "Le fichier $filename n'est pas accessible en écriture.";
            }

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

        return $this->render('admin/file_form.html.twig', [
            'filename' => $filename,
            'form' => $form->createView(),
        ]);
    }

    /**
     * @Route("/app/contacts", name="app_contacts")
     */
    public function contactsAction(Request $request)
    {
        $request->getSession()->set('_application', 2);
        $users = $this->getDoctrine()->getRepository(USer::class)->findAll();

        return $this->render('admin/contact_list.html.twig', [
            'users' => $users,
        ]);
    }

    /**
     * @Route("/app/config/dashboard", name="app_config_dashboard")
     */
    public function configDashboardAction(Request $request, SettingsManager $settingsManager)
    {
        $odd=1; $cible=2; $indicateur=3;
        $request->getSession()->set('_application', 2);

        return $this->render('admin/dashboard.html.twig', [
            'odds' => $settingsManager->compter(2030,$odd),
            'aspirations' => $settingsManager->compter(2063,$odd),
            'cibles' => $settingsManager->compter(2030,$cible),
            'objectifs' => $settingsManager->compter(2063,$cible),
            'indicateurs' => $settingsManager->compter(2030,$indicateur),
            'domaines' => $settingsManager->compter(2063,$indicateur),
            'indicateurscommunaux' => $settingsManager->compter(2030,$indicateur,true),
            'users' => $settingsManager->compterUser('all'),
            'admins' => $settingsManager->compterUser('ROLE_ADMIN'),
            'managers' => $settingsManager->compterUser('ROLE_MANAGER'),
            'dpp' => $settingsManager->compterUser('ROLE_DPP'),
            'focaux' => $settingsManager->compterUser('ROLE_FOCAL'),
        ]);
    }

    /**
     * @Route("/app/message", name="app_send_message")
     */
    public function sendMessageAction(Request $request)
    {
        return $this->redirectToRoute('app_send_message');
    }

    /**
     * @Route("/app/manuel", name="app_manuel")
     * 
     */
    public function manuelAction(Request $request)
    {
        $manuel='';
        if ($this->isGranted('ROLE_MANAGER')){
            $manuel="Manuel_SI-ODD-Administrateur.pdf";
        }else{
            $commune=$request->getSession()->get('_commune');
            $ministry = $request->getSession()->get('_ministry');
            $departement = $request->getSession()->get('_departement');
            if($commune){
                $manuel = "Manuel_SI-ODD-Commune.pdf";
            }else if($ministry){
                $manuel="Manuel_SI-ODD-Ministere.pdf";
            }else if($departement){
                $manuel="Manuel_SI-ODD-DDD-CSPAT.pdf";
            }
        }
        $filename = $this->getParameter('kernel.project_dir') . "/public/Manuels/".$manuel;
        
        header("Content-type: application/octet-stream");                       
        header("Content-Disposition:inline;filename='".basename($filename)."'");            
        header('Content-Length: ' . filesize($filename));
        header("Cache-control: private"); //use this to open files directly                     
        readfile($filename);

    }


    /**
     * @Route("/admin/statistique/ministeres", name="statistiques_ministeres")
     */
    public function statistiqueMinisteres(Request $request, SettingsManager $settingsManager)
    {
        $year = $settingsManager->getYear($request->getSession()->get('_year') );
        $ministeres = $this->getDoctrine()->getRepository(Ministry::class)->ministryByYear($year->getName());

        $validepf=0;
        $nonvalidepf=0;
        $validedpp=0;
        $nonvalidedpp=0;

        $validepf2=0;
        $nonvalidepf2=0;
        $validedpp2=0;
        $nonvalidedpp2=0;

        foreach($ministeres as $ministere){
            $structure = $settingsManager->getStructureYear($year->getName(), $ministere);
            if($structure && $structure->getFocal()){
                $validepf++;
            }else{
                $nonvalidepf++;
            }
            if($structure && $structure->getDpp()){
                $validedpp++;
            }else{
                $nonvalidedpp++;
            }


            if($structure && $structure->getFocal2()){
                $validepf2++;
            }else{
                $nonvalidepf2++;
            }
            if($structure && $structure->getDpp2()){
                $validedpp2++;
            }else{
                $nonvalidedpp2++;
            }
        }
    
        return $this->render('statistiques/ministeres.html.twig', [
            'ministeres' => $ministeres,
            'year' => $year,
            'validepf' => $validepf,
            'nonvalidepf' => $nonvalidepf,
            'validedpp' => $validedpp,
            'nonvalidedpp' => $nonvalidedpp,
            'validepf2' => $validepf2,
            'nonvalidepf2' => $nonvalidepf2,
            'validedpp2' => $validedpp2,
            'nonvalidedpp2' => $nonvalidedpp2,
        ]);
    }

    /**
     * @Route("/admin/statistique/communes", name="statistiques_communes")
     */
    public function statistiquesCommunes(Request $request, SettingsManager $settingsManager)
    {
        $year = $settingsManager->getYear($request->getSession()->get('_year') );
        $communes = $this->getDoctrine()->getRepository(Commune::class)->findAll();

        $validepf=0;
        $nonvalidepf=0;
        $validedpp=0;
        $nonvalidedpp=0;

        foreach($communes as $commune){
            $structure = $settingsManager->getStructureYear($year->getName(), null, $commune);
            if($structure && $structure->getFocal2()){
                $validepf++;
            }else{
                $nonvalidepf++;
            }
            if($structure && $structure->getDpp2()){
                $validedpp++;
            }else{
                $nonvalidedpp++;
            }
        }

        return $this->render('statistiques/communes.html.twig', [
            'communes' => $communes,
            'year' => $year,
            'validepf' => $validepf,
            'nonvalidepf' => $nonvalidepf,
            'validedpp' => $validedpp,
            'nonvalidedpp' => $nonvalidedpp,
        ]);
    }
    
}
