<?php

namespace RxConnexionBundle\Controller;

use RxConnexionBundle\Entity\TicketEntity;
use RxConnexionBundle\Entity\TicketNoteEntity;
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\AuditTrailEntity;

use RxConnexionBundle\Form\TicketForm;

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

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

        //Date Filter
        $monthNow = date('n');
        $yearNow = date('Y');
        $yr=$yearNow;
        $monthFilter = array();
        $i = 0;
        for ($m=$monthNow; $m > $monthNow-12; $m--) {
            if($m < 1){
                $yr = $yearNow-1;
            }
            $month = date('F', mktime(0,0,0,$m, 1, date('Y')));
            $monthFilter[$i]['display'] = $yr.' - '.$month;
            $monthFilter[$i]['value'] = $yr.'|'.abs($m);
            $i++;
        }

        $em = $this->getDoctrine()->getManager();
        $ticketStatus = $em->getRepository('RxConnexionBundle:TicketStatusEntity')->findBy(array(
            'isDeleted' => 0
        ));

        $accountUser = $em->getRepository('RxConnexionBundle:AccountUserEntity')->findBy(array(
            'isDeleted' => 0
        ));

        return $this->render('@RxConnexion/Ticket/index.html.twig', array(
            'title' => 'Manage Endorsement',
            'page_title' => 'Manage Endorsement',
            'monthFilter'  => $monthFilter,
            'ticketStatus'  => $ticketStatus,
            'accountUser'  => $accountUser,
            'javascripts' => array('rxconnexion/admin/js/ticket/ticket.js?v=1.0.4')
        ));
    }

    /**
     * @Route("/ajax_list", name="ticket_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()) {

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

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

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

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

                if($hasUpdate) {
                    $url = $this->generateUrl('ticket_form', array(
                        'action' => 'u',
                        'id' => $id
                    ));
                    $action = "<a class='action-button-style' href='$url'>Update</a>";
                }
                $patientsWithLink = '';
                if(isset($row['patients'])){
                    $patientsWithLinks = array();
                    $patientDetails = explode(',' , $row['patients']);
                    foreach ($patientDetails as $patientDetail){
                        $patientDetailForIds = explode(';', $patientDetail);
                        $patientLink = !empty($patientDetailForIds[0]) ? $this->generateUrl('patient_detail', array(
                            'patient_id' => base64_encode($patientDetailForIds[0])
                        )) : 'javascript:void(0)';
                        $patientsWithLinks[] = isset($patientDetailForIds[1]) ? "<a href='$patientLink' target='_blank'> $patientDetailForIds[1]</a>" : '';
                    }
                    $patientsWithLink = implode('<br />' ,$patientsWithLinks);
                }
                $patientChartsWithLink = '';
                if(isset($row['patientCharts'])){
                    $patientChartsWithLinks = array();
                        $patientChartDetails = explode(',' , $row['patientCharts']);
                    foreach ($patientChartDetails as $patientChartDetail){
                        $patientChartDetailForIds = explode('-', $patientChartDetail);
                        if(!empty($patientChartDetailForIds[0])) {
                            $patientChartLink = $this->generateUrl('patient_chart_form', array(
                                'patient_id' => base64_encode($patientChartDetailForIds[2]),
                                'action' => 'u',
                                'id' => base64_encode($patientChartDetailForIds[0])
                            ));
                            $patientChartsWithLinks[] = "<a href='$patientChartLink' target='_blank'> $patientChartDetailForIds[0] - $patientChartDetailForIds[1] - $patientChartDetailForIds[3]</a>";
                        }
                    }
                    $patientChartsWithLink = implode('<br />' ,$patientChartsWithLinks);
                }

                $values = array(
                    $row['id'],
                    $row['createdAt'],
                    $row['user'],
                    $row['ticketStatus'],
                    $row['ticketSeverity'],
                    $patientsWithLink,
                    $patientChartsWithLink,
                    $row['latestNote'],
                    $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 = "ticket_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 Ticket New', 'Admin Ticket Update'))) return $authService->redirectToHome();

        $em = $this->getDoctrine()->getManager();
        $patientId = $request->get('p');
        $accountUserId = $request->get('au');
        $returnUrl = $request->get('return');
        $patient = !empty($patientId) && !is_null($patientId) ? $em->getRepository('RxConnexionBundle:PatientEntity')->find(base64_decode($patientId)) : null;
        $accountUser = !empty($accountUserId) && !is_null($accountUserId) ? $em->getRepository('RxConnexionBundle:AccountUserEntity')->find(base64_decode($accountUserId)) : null;

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

        $formOptions = array('action' => $action);
        $form = $this->createForm(TicketForm::class, $ticket, $formOptions);
        if($request->getMethod() === 'POST') {

            $ticket_form = $request->get($form->getName());
            $result = $this->processForm($ticket_form, $ticket, $form, $request);

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

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

        return $this->render('@RxConnexion/Ticket/form.html.twig', array(
            'title' => $title,
            'page_title' => $title,
            'javascripts' => array('rxconnexion/admin/js/ticket/ticket_form.js?v=1.0.2'),
            'form' => $form->createView(),
            'action' => $action,
            'ticket' => $ticket,
            'id' => $id,
            'patient' => $patient,
            'accountUser' => $accountUser,
            'returnUrl' => $returnUrl,
        ));
    }

    private function processForm($ticket_form, $ticket, $form, Request $request) {

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

        $errors = $em->getRepository('RxConnexionBundle:TicketEntity')->validate($ticket_form);

        if(!count($errors)) {

            switch($ticket_form['action']) {

                case 'n': // new

                    $form->handleRequest($request);

                    if ($form->isValid()) {

                        $em->persist($ticket);
                        $ticketNote = new TicketNoteEntity();
                        $ticketNote->setTicket($ticket);
                        $ticketNote->setNote($ticket_form['note']);
                        $em->persist($ticketNote);
                        $em->flush();

                        $newAT = new AuditTrailEntity(
                            'Ticket',
                            $em->getClassMetadata(TicketEntity::class)->getTableName(),
                            AuditTrailEntity::AXN_NEW
                        );
                        $newAT->entity = $ticket;
                        $newAT->parseDetails();
                        $em->persist($newAT);

                        $newAT = new AuditTrailEntity(
                            'Ticket Note',
                            $em->getClassMetadata(TicketEntity::class)->getTableName(),
                            AuditTrailEntity::AXN_NEW
                        );
                        $newAT->entity = $ticketNote;
                        $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(
                        'Ticket',
                        $em->getClassMetadata(TicketEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_UPDATE
                    );
                    $newAT->entity = $ticket;
                    $newAT->parseOriginalDetails();

                    $form->handleRequest($request);

                    if ($form->isValid()) {

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

                        $ticketNote = new TicketNoteEntity();
                        $ticketNote->setTicket($ticket);
                        $ticketNote->setNote($ticket_form['note']);
                        $em->persist($ticketNote);
                        $em->flush();

                        $newAT = new AuditTrailEntity(
                            'Ticket Note',
                            $em->getClassMetadata(TicketEntity::class)->getTableName(),
                            AuditTrailEntity::AXN_NEW
                        );
                        $newAT->entity = $ticketNote;
                        $newAT->parseDetails();
                        $em->persist($newAT);
                        $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(
                        'Ticket',
                        $em->getClassMetadata(TicketEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_DELETE
                    );
                    $newAT->entity = $ticket;
                    $newAT->parseDetails();
                    $em->persist($newAT);

                    $form->handleRequest($request);

                    if ($form->isValid()) {

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

                        $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("/autocomplete", name="ticket_autocomplete")
     */
    public function autocompleteAction(Request $request) {

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

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

        return new JsonResponse($result);
    }



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

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

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

        $branch = $request->get('branch');

        $ticket = $em->getRepository('RxConnexionBundle:TicketEntity')->find(base64_decode($id));
        if($ticket) {
            $formOptions = array('action' => $action);
            $form = $this->createForm(TicketForm::class, $ticket, $formOptions);
            $latestTicketNote_accountUser = null;
            if($ticket->getLatestTicketNote()){
                $latestTicketNote_accountUser = $em->getRepository('RxConnexionBundle:AccountUserEntity')->findOneBy(array('username'=> $ticket->getLatestTicketNote()->getCreatedBy()));
            }

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

                $ticket_form = $request->get($form->getName());
                $result = $this->process_reply_form($ticket_form, $ticket, $form, $request);

                if($result['success']) {
                    return $this->redirect($this->generateUrl('my_task', array(
                        'branch' => $branch,
                    ) ), 302);
                } else {
                    $form->submit($ticket_form, false);
                }
            }

            $title = 'Reply to Ticket ID: '. $ticket->getId();
            $userData = $this->get('session')->get('userData');
            $result['html'] =  $this->renderView('@RxConnexion/Ticket/reply_form.html.twig', array(
                'title' => $title,
                'page_title' => $title,
                'javascripts' => array('rxconnexion/admin/js/ticket/ticket_reply_form.js?v=1.0.0'),
                'form' => $form->createView(),
                'action' => $action,
                'ticket' => $ticket,
                'id' => $id,
                'userData' => $userData,
                'latestTicketNote_accountUser' => $latestTicketNote_accountUser,
                'branch' => $branch,
            ));
            $result['success'] = true;

            return new JsonResponse($result);
        } else {
            return new JsonResponse(['success' => false, 'msg' => 'Ticket not found']);
        }
    }

    private function process_reply_form($ticket_form, $ticket, $form, Request $request) {

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

        $errors = $em->getRepository('RxConnexionBundle:TicketEntity')->validate($ticket_form);

        if(!count($errors)) {

            switch($ticket_form['action']) {

                case 'n': // new

                    $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(
                        'Ticket',
                        $em->getClassMetadata(TicketEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_UPDATE
                    );
                    $newAT->entity = $ticket;
                    $newAT->parseOriginalDetails();

                    $form->handleRequest($request);

                    if ($form->isValid()) {

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

                        $ticketNote = new TicketNoteEntity();
                        $ticketNote->setTicket($ticket);
                        $ticketNote->setNote($ticket_form['note']);
                        $em->persist($ticketNote);
                        $em->flush();

                        $newAT = new AuditTrailEntity(
                            'Ticket Note',
                            $em->getClassMetadata(TicketEntity::class)->getTableName(),
                            AuditTrailEntity::AXN_NEW
                        );
                        $newAT->entity = $ticketNote;
                        $newAT->parseDetails();
                        $em->persist($newAT);
                        $em->flush();

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

                        $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

                    $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;
    }

}
