<?php

namespace RxConnexionBundle\Controller;

use RxConnexionBundle\Entity\AccountUserGroupRefEntity;
use RxConnexionBundle\Entity\AccountUserHealthFacilityEntity;
use RxConnexionBundle\Entity\AccountUserOtherAccessEntity;
use RxConnexionBundle\Entity\UserAccessEntity;
use RxConnexionBundle\Entity\UserGroupAccountUserEntity;
use RxConnexionBundle\Form\AccountUserGroupRefForm;
use RxConnexionBundle\Form\UserGroupAccountUserForm;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use RxConnexionBundle\Entity\AccountUserEntity;
use RxConnexionBundle\Entity\AuditTrailEntity;
use RxConnexionBundle\Form\AccountUserForm;
use RxConnexionBundle\Form\AccountUserHealthFacilityForm;
use RxConnexionBundle\Form\AccountUserCompanyForm;

use RxConnexionBundle\Entity\AccountUserCompanyEntity;
use RxConnexionBundle\Entity\AccountUserBranchEntity;
use RxConnexionBundle\Entity\AccountUserLocationEntity;


/**
 * @Route("main/account_user")
 */
class AccountUserController extends Controller
{
    /**
     * @Route("", name="account_user")
     */
    public function indexAction() {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Account User'))) return $authService->redirectToHome();

        return $this->render('@RxConnexion/AccountUser/index.html.twig', array(
            'title' => 'Manage User',
            'page_title' => 'Manage User ',
            'javascripts' => array('rxconnexion/admin/js/accountUser/accountUser.js?v=1.0.0')
        ));
    }

    /**
     * @Route("/ajax_list", name="account_user_ajax_list")
     */
    public function ajax_list(Request $request) {

        $get = $request->query->all();

        $result = array(
            "draw" => intval($get['draw']),
            "recordsTotal" => 0,
            "recordsFiltered" => 0,
            "data" => array()
        );

        $authService = $this->get('rx_connexion.authService');
        if($authService->isLoggedIn()) {
            $userData = $this->get('session')->get('userData');

            $hasUpdate = $authService->isUserHasAccesses(array('Admin Account User Update'), false);
            $hasDetail = $authService->isUserHasAccesses(array('Admin Account User Detail'), false);

            $data = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:AccountUserEntity')->ajax_list($get, $this->get('session')->get('userData'));

            foreach($data['results'] as $row) {

                $id = base64_encode($row['id']);
                $action = '';

                if($hasUpdate) {
                    $url = $this->generateUrl('account_user_form', array(
                        'action' => 'u',
                        'id' => $id
                    ));
                    $action = "<a class='action-button-style' href='$url'>Update</a>";
                }

                if($hasDetail){
                    $detailsUrl = $this->generateUrl('account_user_detail', array(
                        'account_user_id' => base64_encode($row['id'])

                    ));
                    $action .= "<a class='action-button-style' href='$detailsUrl'>Details</a>";
                }

                if($userData['type'] === 'Super Admin') {

                    $url = $this->generateUrl('user_other_access_form', array(
                        'id' => $id,
                        'type' => base64_encode('Add')
                    ));
                    $action .= "<a class='action-button-style' href='$url'>Additional access</a>";

                    $url = $this->generateUrl('user_other_access_form', array(
                        'id' => $id,
                        'type' => base64_encode('Restrict')
                    ));
                    $action .= "<a class='action-button-style' href='$url'>Restricted access</a>";
                }

                $values = array(
                    $row['account_desc'],
                    $row['account_user_type_desc'],
                    $row['username'],
                    $row['full_name'],
                    $row['is_active'] == 1 ? 'Yes' : 'No',
                    $action
                );

                $result['data'][] = $values;
            }

            $result['recordsTotal'] = $data['total'];
            $result['recordsFiltered'] = $data['total'];
        }

        return new JsonResponse($result);
    }

    /**
     * @Route(
     *      "/form/{action}/{id}",
     *      defaults = {
     *          "action":  "n",
     *          "id": 0
     *      },
     *      requirements = {
     *          "action": "n|u"
     *      },
     *      name = "account_user_form"
     * )
     */
    public function formAction($action, $id, Request $request) {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Account User New', 'Admin Account User Update'))) return $authService->redirectToHome();

        $em = $this->getDoctrine()->getManager();

        $accountUser = $em->getRepository('RxConnexionBundle:AccountUserEntity')->find(base64_decode($id));
        if(!$accountUser) {
            $accountUser = new AccountUserEntity();
        }

        $formOptions = array('action' => $action);
        $form = $this->createForm(AccountUserForm::class, $accountUser, $formOptions);

        if($request->getMethod() === 'POST') {

            $accountUser_form = $request->get($form->getName());
            $result = $this->processForm($accountUser_form, $accountUser, $form, $request);

            if($result['success']) {
                if($result['redirect'] === 'index') {
                    return $this->redirect($this->generateUrl('account_user'), 302);
                } else if($result['redirect'] === 'form') {
                    return $this->redirect($this->generateUrl('account_user_form', array(
                        'action' => 'u',
                        'id' => base64_encode($result['id'])
                    )), 302);
                } else if($result['redirect'] === 'form with error') {
                    return $this->redirect($this->generateUrl('account_user_form'), 302);
                }
            } else {
                $form->submit($accountUser_form, false);
            }
        }

        $title = ($action === 'n' ? 'New' : 'Update') . ' User';

        return $this->render('@RxConnexion/AccountUser/form.html.twig', array(
            'title' => $title,
            'page_title' => $title,
            'javascripts' => array('rxconnexion/admin/js/accountUser/accountUser_form.js?v=1.0.0'),
            'form' => $form->createView(),
            'action' => $action,
            'id' => $id
        ));
    }

    private function processForm($accountUser_form, $accountUser, $form, Request $request) {

        $em = $this->getDoctrine()->getManager();
        $oldPass = $accountUser->getPassword();
        $errors = $em->getRepository('RxConnexionBundle:AccountUserEntity')->validate($accountUser_form);

        if(!count($errors)) {

            switch($accountUser_form['action']) {

                case 'n': // new

                    $form->handleRequest($request);

                    if ($form->isValid()) {

                        $accountUser->setPassword($this->get('rx_connexion.authService')->better_crypt(md5($accountUser_form['password']['first']), 15));
                        $em->persist($accountUser);
                        $em->flush();

                        $newAT = new AuditTrailEntity(
                            'Account',
                            $em->getClassMetadata(AccountUserEntity::class)->getTableName(),
                            AuditTrailEntity::AXN_NEW
                        );
                        $newAT->entity = $accountUser;
                        $newAT->parseDetails();
                        $em->persist($newAT);
                        $em->flush();

                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Saved.');

                        $result['redirect'] = 'index';

                    } else {

                        $this->get('session')->getFlashBag()->set('error_messages', 'Something went wrong. Please try again.');
                        $result['redirect'] = 'form with error';
                    }

                    break;

                case 'u': // update

                    $newAT = new AuditTrailEntity(
                        'Account',
                        $em->getClassMetadata(AccountUserEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_DELETE
                    );
                    $newAT->entity = $accountUser;
                    $newAT->parseOriginalDetails();

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

                        $newAT->parseDetails();
                        $em->persist($newAT);

                        if(!empty($accountUser_form['password']['first'])) {
                            $accountUser->setPassword($this->get('rx_connexion.authService')->better_crypt(md5($accountUser_form['password']['first']), 15));
                        }else{
                            $accountUser->setPassword($oldPass);
                        }

                        $em->flush();

                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Updated.');

                        $result['redirect'] = 'index';

                    } else {

                        $this->get('session')->getFlashBag()->set('error_messages', 'Something went wrong. Please try again.');
                        $result['redirect'] = 'form with error';
                    }

                    break;

                case 'd': // delete

                    $newAT = new AuditTrailEntity(
                        'Account',
                        $em->getClassMetadata(AccountUserEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_DELETE
                    );
                    $newAT->entity = $accountUser;
                    $newAT->parseDetails();
                    $em->persist($newAT);
                    $em->flush();

                    $form->handleRequest($request);

                    if ($form->isValid()) {

                        //$em->remove($accountUser);
                        $accountUser->setIsDeleted(true);
                        $accountUser->setIsActive(false);

                        $em->flush();

                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Deleted.');

                        $result['redirect'] = 'index';

                    } else {

                        $this->get('session')->getFlashBag()->set('error_messages', 'Something went wrong. Please try again.');
                        $result['redirect'] = 'form with error';
                    }

                    break;
            }

            $result['success'] = true;

        } else {

            foreach($errors as $error) {
                $this->get('session')->getFlashBag()->add('error_messages', $error);
            }

            $result['success'] = false;
        }

        return $result;
    }

    /**
     * @Route(
     *      "/detail/{account_user_id}",
     *      name = "account_user_detail"
     * )
     */
    public function detailAction($account_user_id, Request $request) {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Account User Detail'))) return $authService->redirectToHome();

        $em = $this->getDoctrine()->getManager();
        $accountUser = $em->getRepository('RxConnexionBundle:AccountUserEntity')->find(base64_decode($account_user_id));

        $title = 'Manage Account User - ' . $accountUser->getFullName();
        return $this->render('@RxConnexion/AccountUser/detail.html.twig', array(
            'title' => $title,
            'page_title' => $title,
            'javascripts' => array(
                'rxconnexion/admin/js/accountUser/accountUser_detail.js?v=1.0.0'
            ),
            'account_user_id' => $account_user_id,
            'accountUser' => $accountUser,
            'tab' => $request->query->get('tab')
        ));
    }

    /**
     * @Route("/account_user_health_facilities_ajax_list", name="account_user_health_facilities_ajax_list")
     */
    public function account_user_health_facilities_ajax_list(Request $request) {

        $get = $request->query->all();

        $result = array(
            "draw" => intval($get['draw']),
            "recordsTotal" => 0,
            "recordsFiltered" => 0,
            "data" => array()
        );

        $authService = $this->get('rx_connexion.authService');
        if($authService->isLoggedIn()) {

            $userData = $this->get('session')->get('userData');

            $hasUpdate = $authService->isUserHasAccesses(array('Admin Account User Health Facility Update'), false);

            $data = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:AccountUserHealthFacilityEntity')->ajax_list($get, $userData);

            foreach($data['results'] as $row) {

                $id = base64_encode($row['id']);
                $action = '';

                if($hasUpdate) {
                    $action = "<a class='action-button-style href-health-facility-form' data-action='u' data-id='$id'>Update</a>";
                }

                $values = array(
                    $row['health_facility_id'],
                    $row['company_description'],
                    $row['branch_description'],
                    $row['description'],
                    $row['mobile_no'],
                    $row['phone_no'],
                    $row['email'],
                    $row['startDate'],
                    $row['endDate'],
                    $action
                );

                $result['data'][] = $values;
            }

            $result['recordsTotal'] = $data['total'];
            $result['recordsFiltered'] = $data['total'];
        }

        return new JsonResponse($result);
    }

    /**
     * @Route(
     *      "/health_facility/form/{account_user_id}/{action}/{id}",
     *      defaults = {
     *          "action":  "n",
     *          "id": 0
     *      },
     *      requirements = {
     *          "action": "n|u"
     *      },
     *      name = "account_user_health_facilities_form"
     * )
     */
    public function account_user_health_facilities_formAction($account_user_id, $action, $id, Request $request) {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Account User Health Facility New', 'Admin Account User Health Facility Update'))) return $authService->redirectToHome();

        $em = $this->getDoctrine()->getManager();

        $accountUserHealthFacility = $em->getRepository('RxConnexionBundle:AccountUserHealthFacilityEntity')->find(base64_decode($id));
        if(!$accountUserHealthFacility) {
            $accountUserHealthFacility = new AccountUserHealthFacilityEntity();
        }

        $formOptions = array(
            'action' => $action,
            'account_user_id' => $account_user_id
        );
        $form = $this->createForm(AccountUserHealthFacilityForm::class, $accountUserHealthFacility, $formOptions);

        $title = $action === 'n' ? 'Add Branch' : 'Update ' . $accountUserHealthFacility->getHealthFacility()->getDescription()    ;

        $result['html'] =  $this->renderView('@RxConnexion/AccountUser/account_user_health_facility_form.html.twig', array(
            'title' => $title,
            'page_title' => $title,
            'form' => $form->createView(),
            'account_user_id' => $account_user_id,
            'action' => $action,
            'id' => $id
        ));
        $result['success'] = true;
        return new JsonResponse($result);
    }

    /**
     * @Route(
     *      "/account_user_health_facilities/save_action",
     *      name = "account_user_health_facilities_save"
     * )
     */
    public function account_user_health_facilities_saveAction(Request $request) {

        $result['success'] = false;
        $result['successMessages'] = array();
        $result['errorMessages'] = array();

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Account User Health Facility New', 'Admin Account User Health Facility Update'))) return $authService->redirectToHome();

        $accountUserHealthFacility_form = $request->get('account_user_health_facility');
        $em = $this->getDoctrine()->getManager();
        $accountUserHealthFacility = $em->getRepository('RxConnexionBundle:AccountUserHealthFacilityEntity')->find($accountUserHealthFacility_form['id']);
        if(!$accountUserHealthFacility) {
            $accountUserHealthFacility = new AccountUserHealthFacilityEntity();
        }
        $formOptions = array(
            'action' => $accountUserHealthFacility_form['action'],
            'account_user_id' => $accountUserHealthFacility_form['account_user']
        );
        $form = $this->createForm(AccountUserHealthFacilityForm::class, $accountUserHealthFacility, $formOptions);
        $errors = $em->getRepository('RxConnexionBundle:AccountUserHealthFacilityEntity')->validate($accountUserHealthFacility_form);

        if(!count($errors)) {

            switch($accountUserHealthFacility_form['action']) {

                case 'n': // new

                    $form->handleRequest($request);

                    if($form->isValid()) {

                        $em->persist($accountUserHealthFacility);
                        $em->flush();

                        $newAT = new AuditTrailEntity(
                            'Account User Branch',
                            $em->getClassMetadata(AccountUserHealthFacilityEntity::class)->getTableName(),
                            AuditTrailEntity::AXN_NEW
                        );
                        $newAT->entity = $accountUserHealthFacility;
                        $newAT->parseDetails();
                        $em->persist($newAT);
                        $em->flush();

                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Saved.');
                        $result['success'] = true;
                        $result['successMessages'][] = 'Record Successfully Saved.';

                    } else {
                        $result['errorMessages'][] = 'Something went wrong. Please try again.';
                    }

                    break;

                case 'u': // update

                    $em->persist($accountUserHealthFacility);
                    $em->flush();

                    $newAT = new AuditTrailEntity(
                        'Account User Branch',
                        $em->getClassMetadata(AccountUserHealthFacilityEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_UPDATE
                    );
                    $newAT->entity = $accountUserHealthFacility;
                    $newAT->parseOriginalDetails();

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

                        $newAT->parseDetails();
                        $em->persist($newAT);

                        $em->flush();
                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Updated.');
                        $result['success'] = true;
                        $result['successMessages'][] = 'Record Successfully Updated.';
                    }else{
                        $result['errorMessages'][] = 'Something went wrong. Please try again.';
                    }

                    break;

                case 'd': // delete

                    $newAT = new AuditTrailEntity(
                        'Account User Branch',
                        $em->getClassMetadata(AccountUserHealthFacilityEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_DELETE
                    );
                    $newAT->entity = $accountUserHealthFacility;
                    $newAT->parseDetails();
                    $em->persist($newAT);

                    $form->handleRequest($request);

                    if ($form->isValid()) {

                        //$em->remove($accountUserHealthFacility);
                        $accountUserHealthFacility->setIsDeleted(true);

                        $em->flush();

                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Deleted.');

                        $result['success'] = true;
                        $result['successMessages'][] = 'Record Successfully Deleted.';

                    } else {

                        $result['errorMessages'][] = 'Something went wrong. Please try again.';
                    }

                    break;
            }
        } else {

            foreach ($errors as $error) {
                $result['errorMessages'][] = $error;
            }
        }
        return new JsonResponse($result);
    }

    /**
     * @Route("/account_user_company_ajax_list", name="account_user_company_ajax_list")
     */
    public function account_user_company_ajax_list(Request $request) {

        $get = $request->query->all();

        $result = array(
            "draw" => intval($get['draw']),
            "recordsTotal" => 0,
            "recordsFiltered" => 0,
            "data" => array()
        );

        $authService = $this->get('rx_connexion.authService');
        if($authService->isLoggedIn()) {

            $userData = $this->get('session')->get('userData');

            $hasUpdate = $authService->isUserHasAccesses(array('Admin Account User Company Update'), false);

            $data = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:AccountUserCompanyEntity')->ajax_list($get, $userData);

            foreach($data['results'] as $row) {

                $id = base64_encode($row['id']);
                $action = '';

                if($hasUpdate) {
                    $action = "<a class='action-button-style href-company-form' data-action='u' data-id='$id'>Update</a>";
                }

                $values = array(
                    $row['id'],
                    $row['company_description'],
                    $row['startDate'],
                    $row['endDate'],
                    $action
                );

                $result['data'][] = $values;
            }

            $result['recordsTotal'] = $data['total'];
            $result['recordsFiltered'] = $data['total'];
        }

        return new JsonResponse($result);
    }

    /**
     * @Route(
     *      "/account_user_company/form/{account_user_id}/{action}/{id}",
     *      defaults = {
     *          "action":  "n",
     *          "id": 0
     *      },
     *      requirements = {
     *          "action": "n|u"
     *      },
     *      name = "account_user_company_form"
     * )
     */
    public function account_user_company_formAction($account_user_id, $action, $id, Request $request) {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Account User Company New', 'Admin Account User Company Update'))) return $authService->redirectToHome();

        $em = $this->getDoctrine()->getManager();

        $accountUserCompany = $em->getRepository('RxConnexionBundle:AccountUserCompanyEntity')->find(base64_decode($id));
        if(!$accountUserCompany) {
            $accountUserCompany = new AccountUserCompanyEntity();
        }

        $formOptions = array(
            'action' => $action,
            'account_user_id' => $account_user_id
        );
        $form = $this->createForm(AccountUserCompanyForm::class, $accountUserCompany, $formOptions);

        $title = $action === 'n' ? 'Add Company' : 'Update ' . $accountUserCompany->getCompany()->getDescription()    ;

        $result['html'] =  $this->renderView('@RxConnexion/AccountUser/account_user_company_form.html.twig', array(
            'title' => $title,
            'page_title' => $title,
            'form' => $form->createView(),
            'account_user_id' => $account_user_id,
            'action' => $action,
            'id' => $id
        ));
        $result['success'] = true;
        return new JsonResponse($result);
    }

    /**
     * @Route(
     *      "/account_user_company/save_action",
     *      name = "account_user_company_save"
     * )
     */
    public function account_user_company_saveAction(Request $request) {

        $result['success'] = false;
        $result['successMessages'] = array();
        $result['errorMessages'] = array();

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Account User Company New', 'Admin Account User Company Update'))) return $authService->redirectToHome();

        $accountUserCompany_form = $request->get('account_user_company');
        $em = $this->getDoctrine()->getManager();
        $accountUserCompany = $em->getRepository('RxConnexionBundle:AccountUserCompanyEntity')->find($accountUserCompany_form['id']);
        if(!$accountUserCompany) {
            $accountUserCompany = new AccountUserCompanyEntity();
        }
        $formOptions = array(
            'action' => $accountUserCompany_form['action'],
            'account_user_id' => $accountUserCompany_form['account_user']
        );
        $form = $this->createForm(AccountUserCompanyForm::class, $accountUserCompany, $formOptions);
        $errors = $em->getRepository('RxConnexionBundle:AccountUserCompanyEntity')->validate($accountUserCompany_form);

        if(!count($errors)) {

            switch($accountUserCompany_form['action']) {

                case 'n': // new

                    $form->handleRequest($request);

                    if($form->isValid()) {

                        $em->persist($accountUserCompany);
                        $em->flush();

                        $newAT = new AuditTrailEntity(
                            'Account User Company',
                            $em->getClassMetadata(AccountUserCompanyEntity::class)->getTableName(),
                            AuditTrailEntity::AXN_NEW
                        );
                        $newAT->entity = $accountUserCompany;
                        $newAT->parseDetails();
                        $em->persist($newAT);
                        $em->flush();

                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Saved.');
                        $result['success'] = true;
                        $result['successMessages'][] = 'Record Successfully Saved.';

                    } else {
                        $result['errorMessages'][] = 'Something went wrong. Please try again.';
                    }

                    break;

                case 'u': // update

                    $em->persist($accountUserCompany);
                    $em->flush();

                    $newAT = new AuditTrailEntity(
                        'Account User Company',
                        $em->getClassMetadata(AccountUserCompanyEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_UPDATE
                    );
                    $newAT->entity = $accountUserCompany;
                    $newAT->parseOriginalDetails();

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

                        $newAT->parseDetails();
                        $em->persist($newAT);

                        $em->flush();
                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Updated.');
                        $result['success'] = true;
                        $result['successMessages'][] = 'Record Successfully Updated.';
                    }else{
                        $result['errorMessages'][] = 'Something went wrong. Please try again.';
                    }

                    break;

                case 'd': // delete

                    $newAT = new AuditTrailEntity(
                        'Account User Company',
                        $em->getClassMetadata(AccountUserHealthFacilityEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_DELETE
                    );
                    $newAT->entity = $accountUserCompany;
                    $newAT->parseDetails();
                    $em->persist($newAT);

                    $form->handleRequest($request);

                    if ($form->isValid()) {

                        //$em->remove($accountUserHealthFacility);
                        $accountUserCompany->setIsDeleted(true);

                        $em->flush();

                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Deleted.');

                        $result['success'] = true;
                        $result['successMessages'][] = 'Record Successfully Deleted.';

                    } else {

                        $result['errorMessages'][] = 'Something went wrong. Please try again.';
                    }

                    break;
            }
        } else {

            foreach ($errors as $error) {
                $result['errorMessages'][] = $error;
            }
        }
        return new JsonResponse($result);
    }

    /**
     * @Route("/access", name="user_access")
     */
    public function accessAction() {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin User Access'))) return $authService->redirectToHome();

        $em = $this->getDoctrine()->getManager();

        $accountUserType = $em->getRepository('RxConnexionBundle:AccountUserTypeEntity')->userTypeAccessList();

        $userTypes = array();

        foreach($accountUserType as $userType) {
            $userTypes[] = array('description' => $userType['description'], 'value' => base64_encode($userType['description']));
        }

        return $this->render('@RxConnexion/AccountUser/access.html.twig', array(
            'title' => 'Manage User Access',
            'page_title' => 'Manage User Access',
            'userTypes' => $userTypes
        ));
    }

    /**
     * @Route("/access_form/{userType}", name="user_access_form")
     */
    public function access_formAction($userType) {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin User Access'))) return $authService->redirectToHome();

        $userTypeDecoded = base64_decode($userType);
        $userAccessDescriptions = array();
        $em = $this->getDoctrine()->getManager();
        $userAccesses = $em->getRepository('RxConnexionBundle:UserAccessEntity')->findBy(array('type' => $userTypeDecoded));

        foreach($userAccesses as $userAccess) {
            $userAccessDescriptions[] = $userAccess->getDescription();
        }

        $accesses = $authService->getAccesses();

        return $this->render('@RxConnexion/AccountUser/access_form.html.twig', array(
            'title' => 'Manage User Access - ' . $userTypeDecoded,
            'page_title' => 'Manage User Access - ' . $userTypeDecoded,
            'stylesheets' => array('rxconnexion/admin/css/user/access_form.css'),
            'hasBackToTop' => true,
            'userType' => $userType,
            'userAccessDescriptions' => $userAccessDescriptions,
            'accesses' => $accesses
        ));
    }

    /**
     * @Route("/access_form_process", name="user_access_form_process")
     */
    public function access_form_processAction(Request $request) {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin User Access'))) return $authService->redirectToHome();

        set_time_limit(0);

        $userType = $request->get('userType');
        $userTypeDecoded = base64_decode($userType);
        $accesses = $request->get('accesses');

        $em = $this->getDoctrine()->getManager();
        $recordCtr = 0;
        $essDescriptions = array();
        $userAccesses = $em->getRepository('RxConnexionBundle:UserAccessEntity')->findBy(array('type' => $userTypeDecoded));

        foreach($accesses as $ess) {

            if(isSet($ess['isChecked'])) {

                $essDescriptions[] = $ess['description'];

                $essExist = false;
                foreach($userAccesses as $userAccess) {
                    if($userAccess->getDescription() === $ess['description']) {
                        $essExist = true;
                        break;
                    }
                }

                if(!$essExist) {

                    $newUserAccess = new UserAccessEntity();
                    $newUserAccess->setType($userTypeDecoded);
                    $newUserAccess->setDescription($ess['description']);
                    $em->persist($newUserAccess);

                    $recordCtr++;
                    if($recordCtr % 50 === 0) $em->flush();
                }
            }
        }

        if($recordCtr > 0 && $recordCtr % 50 > 0) $em->flush();

        $recordCtr = 0;
        foreach($userAccesses as $userAccess) {

            if(!in_array($userAccess->getDescription(), $essDescriptions)) {

                $em->remove($userAccess);

                $recordCtr++;
                if($recordCtr % 50 === 0) $em->flush();
            }
        }

        if($recordCtr > 0 && $recordCtr % 50 > 0) $em->flush();

        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Saved.');

        return $this->redirect($this->generateUrl('user_access_form', array(
            'userType' => $userType
        )), 302);
    }

    /**
     * @Route("/other_access_form/{id}/{type}", name="user_other_access_form")
     */
    public function other_access_formAction($id, $type) {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin User Access'))) return $authService->redirectToHome();

        $typeDecoded = base64_decode($type);
        $userAccessDescriptions = array();
        $em = $this->getDoctrine()->getManager();
        $user = $em->getRepository('RxConnexionBundle:AccountUserEntity')->find(base64_decode($id));

        $userOtherAccesses = $user->getUserOtherAccessesByType($typeDecoded);
        foreach($userOtherAccesses as $userOtherAccess) {
            $userAccessDescriptions[] = $userOtherAccess->getDescription();
        }

        $accesses = $authService->getAccesses();

        return $this->render('@RxConnexion/AccountUser/other_access_form.html.twig', array(
            'title' => $typeDecoded . ' Access - ' . $user->getFullName(),
            'page_title' => $typeDecoded . ' Access - ' . $user->getFullName(),
            'stylesheets' => array('rxconnexion/admin/css/user/access_form.css'),
            'hasBackToTop' => true,
            'userAccessDescriptions' => $userAccessDescriptions,
            'accesses' => $accesses,
            'id' => $id,
            'type' => $type
        ));
    }

    /**
     * @Route("/other_access_form_process", name="user_other_access_form_process")
     */
    public function other_access_form_processAction(Request $request) {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin User Access'))) return $authService->redirectToHome();

        set_time_limit(0);

        $id = $request->get('id');
        $type = $request->get('type');
        $typeDecoded = base64_decode($type);
        $accesses = $request->get('accesses');

        $em = $this->getDoctrine()->getManager();
        $recordCtr = 0;
        $essDescriptions = array();
        $user = $em->getRepository('RxConnexionBundle:AccountUserEntity')->find(base64_decode($id));
        $userOtherAccesses = $user->getUserOtherAccessesByType($typeDecoded);

        foreach($accesses as $ess) {

            if(isSet($ess['isChecked'])) {

                $essDescriptions[] = $ess['description'];

                $essExist = false;
                foreach($userOtherAccesses as $userOtherAccess) {
                    if($userOtherAccess->getDescription() === $ess['description']) {
                        $essExist = true;
                        break;
                    }
                }

                if(!$essExist) {

                    $newUserOtherAccess = new AccountUserOtherAccessEntity();
                    $newUserOtherAccess->setAccountUser($user);
                    $newUserOtherAccess->setType($typeDecoded);
                    $newUserOtherAccess->setDescription($ess['description']);
                    $em->persist($newUserOtherAccess);

                    $recordCtr++;
                    if($recordCtr % 50 === 0) $em->flush();
                }
            }
        }

        if($recordCtr > 0 && $recordCtr % 50 > 0) $em->flush();

        $recordCtr = 0;
        foreach($userOtherAccesses as $userOtherAccess) {

            if(!in_array($userOtherAccess->getDescription(), $essDescriptions)) {

                $em->remove($userOtherAccess);

                $recordCtr++;
                if($recordCtr % 50 === 0) $em->flush();
            }
        }

        if($recordCtr > 0 && $recordCtr % 50 > 0) $em->flush();

        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Saved.');

        return $this->redirect($this->generateUrl('user_other_access_form', array(
            'id' => $id,
            'type' => $type
        )), 302);
    }

    /**
     * @Route("/change_password", name="user_change_password")
     */
    public function change_passwordAction(Request $request) {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();

        if($request->getMethod() === 'POST') {

            $em = $this->getDoctrine()->getManager();
            $user = $authService->getUser();
            $errors = array();
            $oldPassword = $request->get('old_password');
            $newPassword = $request->get('new_password');
            $confirmNewPassword = $request->get('confirm_new_password');

            if(empty($oldPassword)) $errors[] = 'Please enter your old password.';
            else if($user->getPassword() !== crypt(md5($oldPassword), $user->getPassword())) $errors[] = 'Your old password is incorrect.';
            if(empty($newPassword)) $errors[] = 'Please enter your new password.';
            if(empty($confirmNewPassword)) $errors[] = 'Please confirm your new password.';
            if($newPassword !== $confirmNewPassword) $errors[] = 'New password and confirm new password does not matched.';

            if(!count($errors)) {

                $user->setPassword($authService->better_crypt(md5($newPassword), 15));
                $em->flush();

                $this->get('session')->getFlashBag()->set('success_messages', 'You have successfully changed your password.');

                return $this->redirect($this->generateUrl('main'), 302);

            } else {

                foreach($errors as $error) {
                    $this->get('session')->getFlashBag()->add('error_messages', $error);
                }
            }
        }

        return $this->render('@RxConnexion/AccountUser/change_password.html.twig', array(
            'title' => 'Change Password',
            'page_title' => 'Change Password'
        ));
    }

    /**
     * @Route("/autocomplete", name="account_user_autocomplete")
     */
    public function autocompleteAction(Request $request) {

        $q = $request->get('query');

        $result = array(
            'query' => 'account_users',
            'suggestions' => $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:AccountUserEntity')->autocomplete_suggestions($q)
        );

        return new JsonResponse($result);
    }

    /**
     * @Route("/autocomplete", name="account_user_active_autocomplete")
     */
    public function autocompleteUsersAction(Request $request) {

        $q = $request->get('query');

        $result = array(
            'query' => 'account_users',
            'suggestions' => $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:AccountUserEntity')->moa_autocomplete_suggestions($q)
        );

        return new JsonResponse($result);
    }

    /**
     * @Route("/account_user_group_ajax_list", name="account_user_user_group_ajax_list")
     */
    public function user_group_ajax_listAction(Request $request) {

        $get = $request->query->all();

        $result = array(
            "draw" => intval($get['draw']),
            "recordsTotal" => 0,
            "recordsFiltered" => 0,
            "data" => array()
        );

        $authService = $this->get('rx_connexion.authService');
        if($authService->isLoggedIn()) {

            $userData = $this->get('session')->get('userData');

            $hasUpdate = $authService->isUserHasAccesses(array('Admin Account User Group Update'), false);

            $data = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:UserGroupAccountUserEntity')->account_user_ajax_list($get, $userData);

            foreach($data['results'] as $row) {

                $id = base64_encode($row['id']);
                $action = '';

                if($hasUpdate) {
                    $action = "<a class='action-button-style href-userGroup-form' data-action='u' data-id='$id'>Update</a>";
                }

                $values = array(
                    $row['id'],
                    $row['userGroup_description'],
                    $row['startDate'],
                    $row['endDate'],
                    $action
                );

                $result['data'][] = $values;
            }

            $result['recordsTotal'] = $data['total'];
            $result['recordsFiltered'] = $data['total'];
        }

        return new JsonResponse($result);
    }

    /**
     * @Route(
     *      "/account_user_group_form/form/{account_user_id}/{action}/{id}",
     *      defaults = {
     *          "action":  "n",
     *          "id": 0
     *      },
     *      requirements = {
     *          "action": "n|u"
     *      },
     *      name = "account_user_account_user_group_form"
     * )
     */
    public function account_user_group_formAction($account_user_id, $action, $id, Request $request) {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Account User Group New', 'Admin Account User Group Update'))) return $authService->redirectToHome();

        $em = $this->getDoctrine()->getManager();

        $userGroupAccountUser = $em->getRepository('RxConnexionBundle:UserGroupAccountUserEntity')->find(base64_decode($id));
        if(!$userGroupAccountUser) {
            $userGroupAccountUser = new UserGroupAccountUserEntity();
        }

        $formOptions = array(
            'action' => $action,
            'account_user_id' => $account_user_id
        );
        $form = $this->createForm(UserGroupAccountUserForm::class, $userGroupAccountUser, $formOptions);

        $title = $action === 'n' ? 'New Group' : 'Update ' . $userGroupAccountUser->getUserGroup()->getDescription()    ;

        $result['html'] =  $this->renderView('@RxConnexion/AccountUser/account_user_group_form.html.twig', array(
            'title' => $title,
            'page_title' => $title,
            'form' => $form->createView(),
            'account_user_id' => $account_user_id,
            'action' => $action,
            'id' => $id
        ));
        $result['success'] = true;
        return new JsonResponse($result);
    }

    /**
     * @Route(
     *      "/account_user_group/save_action",
     *      name = "account_user_user_group_save"
     * )
     */
    public function account_user_group_saveAction(Request $request) {

        $result['success'] = false;
        $result['successMessages'] = array();
        $result['errorMessages'] = array();

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Account User Group New', 'Admin Account User Group Update'))) return $authService->redirectToHome();

        $accountUserCompany_form = $request->get('userGroupAccountUser');

        $em = $this->getDoctrine()->getManager();
        $userGroupAccountUser = $em->getRepository('RxConnexionBundle:UserGroupAccountUserEntity')->find($accountUserCompany_form['id']);
        if(!$userGroupAccountUser) {
            $userGroupAccountUser = new UserGroupAccountUserEntity();
        }
        $formOptions = array(
            'action' => $accountUserCompany_form['action'],
            'account_user_id' => $accountUserCompany_form['account_user']
        );
        $form = $this->createForm(UserGroupAccountUserForm::class, $userGroupAccountUser, $formOptions);
        $errors = $em->getRepository('RxConnexionBundle:UserGroupAccountUserEntity')->validate($accountUserCompany_form);

        if(!count($errors)) {

            switch($accountUserCompany_form['action']) {

                case 'n': // new

                    $form->handleRequest($request);

                    if($form->isValid()) {

                        $em->persist($userGroupAccountUser);
                        $em->flush();

                        /*$newAT = new AuditTrailEntity(
                            'Account User Company',
                            $em->getClassMetadata(AccountUserCompanyEntity::class)->getTableName(),
                            AuditTrailEntity::AXN_NEW
                        );
                        $newAT->entity = $userGroupAccountUser;
                        $newAT->parseDetails();
                        $em->persist($newAT);
                        $em->flush();*/

                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Saved.');
                        $result['success'] = true;
                        $result['successMessages'][] = 'Record Successfully Saved.';

                    } else {
                        $result['errorMessages'][] = 'Something went wrong. Please try again.';
                    }

                    break;

                case 'u': // update

                    /*$em->persist($userGroupAccountUser);
                    $em->flush();*/

                    /*$newAT = new AuditTrailEntity(
                        'Account User Company',
                        $em->getClassMetadata(AccountUserCompanyEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_UPDATE
                    );
                    $newAT->entity = $userGroupAccountUser;
                    $newAT->parseOriginalDetails();*/

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

                        /*$newAT->parseDetails();
                        $em->persist($newAT)*/;

                        $em->flush();
                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Updated.');
                        $result['success'] = true;
                        $result['successMessages'][] = 'Record Successfully Updated.';
                    }else{
                        $result['errorMessages'][] = 'Something went wrong. Please try again.';
                    }

                    break;

                case 'd': // delete

                    /*$newAT = new AuditTrailEntity(
                        'Account User Company',
                        $em->getClassMetadata(AccountUserHealthFacilityEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_DELETE
                    );
                    $newAT->entity = $userGroupAccountUser;
                    $newAT->parseDetails();
                    $em->persist($newAT);*/

                    $form->handleRequest($request);

                    if ($form->isValid()) {

                        $em->remove($userGroupAccountUser);
                        //$userGroupAccountUser->setIsDeleted(true);

                        $em->flush();

                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Deleted.');

                        $result['success'] = true;
                        $result['successMessages'][] = 'Record Successfully Deleted.';

                    } else {

                        $result['errorMessages'][] = 'Something went wrong. Please try again.';
                    }

                    break;
            }
        } else {

            foreach ($errors as $error) {
                $result['errorMessages'][] = $error;
            }
        }
        return new JsonResponse($result);
    }
}
