<?php

namespace RxConnexionBundle\Controller;

use RxConnexionBundle\Entity\ChatMessageEntity;
use RxConnexionBundle\Form\ChatForm;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use RxConnexionBundle\Entity\ChatEntity;
use RxConnexionBundle\Entity\AuditTrailEntity;
use RxConnexionBundle\Form\AccountForm;

/**
 * @Route("/main/chat")
 */
class ChatController extends Controller
{
    /**
     * @Route("/", name="chat")
     */
    public function indexAction(Request $request)
    {
        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Chat'))) return $authService->redirectToHome();
        $userData = $this->get('session')->get('userData');
        $conversations = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:ChatEntity')->getChatConversationList($userData['id']);


        return $this->render('@RxConnexion/Chat/index.html.twig', array(
            'stylesheets' => array('rxconnexion/admin/css/chat/chat.css?v=1.0.0'),
            'title' => 'Chat Messages',
            'page_title' => 'Manage Chat Messages',
            'javascripts' => array('rxconnexion/admin/js/chat/chat.js?v=1.0.0'),
            'conversations' => $conversations
        ));
    }

    /**
     * @Route("/ajax_list", name="chat_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 Chat Update'), false);

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

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

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

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

                $values = array(
                    $row['id'],
                    $row['code'],
                    $row['description'],
                    $row['e_mail'],
                    $row['mobile_no'],
                    $row['phone_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 = "chat_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 Chat New', 'Admin Chat Update'))) return $authService->redirectToHome();

        $em = $this->getDoctrine()->getManager();
        $chat= $em->getRepository('RxConnexionBundle:ChatEntity')->find(base64_decode($id));

        if(!$chat) {
            $chat= new ChatEntity();
        }

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

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

            $chat_form = $request->get($form->getName());
            $result = $this->processForm($chat_form, $chat, $form, $request);

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

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

        return $this->render('@RxConnexion/Chat/form.html.twig', array(
            'title' => $title,
            'page_title' => $title,
            'form' => $form->createView(),
            'action' => $action,
            'id' => $id,
            'javascripts' => array('rxconnexion/admin/js/chat/chat_form.js?v=1.0.0'),
            'chatCreatorId' => $chat->getAccountUser() ?  $chat->getAccountUser()->getId() : ''
        ));
    }

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

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

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

        return new JsonResponse($result);
    }

    /**
     * @Route("/autocomplete-accounts", name="account_autocomplete_chat_account_user_account")
     */
    public function chatAutocompleteAccountUser(Request $request) {

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

        $result = array(
            'query' => 'account_users',
            'suggestions' => $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:ChatEntity')->chatAutocompleteAccountUser($q, $userData['id'])
        );

        return new JsonResponse($result);
    }



    // === PRIVATE FUNCTIONS ===

    private function processForm($chat_form, $chat, $form, Request $request) {

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

        $errors = $em->getRepository('RxConnexionBundle:ChatEntity')->validate($chat_form,$userData);

        if(!count($errors)) {

            switch($chat_form['action']) {

                case 'n': // new

//                    $form->handleRequest($request);
                    $form->submit($chat_form, false);

                    if($form->isValid()) {
                        $userData = $this->get('session')->get('userData');
                        $accountUser = $em->getRepository('RxConnexionBundle:AccountUserEntity')->find($userData['id']);
                        $chat->setAccountUser($accountUser);
                        $em->persist($chat);
                        $em->flush();

                        /*$newAT = new AuditTrailEntity(
                            'Chat',
                            $em->getClassMetadata(ChatEntity::class)->getTableName(),
                            AuditTrailEntity::AXN_NEW
                        );
                        $newAT->entity = $chat;
                        $newAT->parseDetails();
                        $em->persist($newAT);
                        $em->flush();*/

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

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

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

                    break;

                case 'u': // update

                    /*$newAT = new AuditTrailEntity(
                        'Chat',
                        $em->getClassMetadata(ChatEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_UPDATE
                    );
                    $newAT->entity = $chat;
                    $newAT->parseOriginalDetails();*/
                    $form->submit($chat_form, false);

//                    $form->handleRequest($request);

                    if ($form->isValid()) {

                        /*$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

                    $form->submit($chat_form, false);

                    /*$newAT = new AuditTrailEntity(
                        'Chat',
                        $em->getClassMetadata(ChatEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_DELETE
                    );
                    $newAT->entity = $chat;
                    $newAT->parseDetails();
                    $em->persist($newAT);*/

                    if($form->isValid()) {

                        //$agency = $em->getRepository('RxConnexionBundle:AgencyEntity')->find($chat_form['id']);
                        //$em->remove($chat);
                        $chat->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;
    }



    // === API FUNCTIONS ===

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

        $chatId = $request->request->all()['chat_id'];
        $authService = $this->get('rx_connexion.authService');
        if($authService->isLoggedIn()) {
            $chat = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:ChatEntity')->find($chatId);
            $msgs = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:ChatMessageEntity')->findBy(array('chat'=>$chatId));

            $result['html'] = $this->renderView('@RxConnexion/Chat/chat_list.html.twig', array(
                'msgs' => $msgs,
                'chat'  => $chat
            ));
            $result['success'] = true;
        }

        return new JsonResponse($result);
    }

    /**
     * @Route("/chat-popup", name="chat_popup")
     */
    public function chat_popupAction(Request $request) {

        $chatId = $request->request->all()['chat_id'];
        $authService = $this->get('rx_connexion.authService');
        if($authService->isLoggedIn()) {
            $userData = $this->get('session')->get('userData');
            $chat = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:ChatEntity')->find($chatId);
            $msgs = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:ChatMessageEntity')->findBy(array('chat'=>$chatId));
            $chatParticipant = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:ChatParticipantEntity')->findOneBy(array('chat'=>$chatId,'accountUser'=>$userData['id']));
            $chatParticipant->setSeenLatest(true);
            $this->getDoctrine()->getManager()->flush();
            $result['html'] = $this->renderView('@RxConnexion/Chat/chat_popup.html.twig', array(
                'msgs' => $msgs,
                'chat'  => $chat
            ));
            $result['success'] = true;
        }

        return new JsonResponse($result);
    }

    /**
     * @Route("/send-message", name="chat_send_message")
     */
    public function chat_send_messageAction(Request $request) {

        $result['success'] = false;
        $result['added'] = false;

        $authService = $this->get('rx_connexion.authService');
        if($authService->isLoggedIn() && $authService->isUserHasAccesses(array('Admin Chat Send Message'))) {

            $em = $this->getDoctrine()->getManager();
            $chat_id = $request->get('chat_id');
            $refId = $request->get('refId');
            $msg = $request->get('msg');

            if(!empty($msg)) {
                $userData = $this->get('session')->get('userData');

                $chat = $em->getRepository('RxConnexionBundle:ChatEntity')->find($chat_id);
                $chatParticipant = $em->getRepository('RxConnexionBundle:ChatParticipantEntity')->findOneBy(array('chat'=>$chat_id,'accountUser' => $userData['id']));

                $chatMessage = new ChatMessageEntity();
                $chatMessage->setChat($chat);
                $chatMessage->setChatParticipant($chatParticipant);
                $chatMessage->setMessage($msg);
                $chatMessage->setIsDeleted(0);
                $em->persist($chatMessage);

                $em->flush();

                // SET LATEST SEEN OF OTHER PARTICIPANT TO FALSE
                $chatParticipants = $em->getRepository('RxConnexionBundle:ChatParticipantEntity')->findBy(array('chat'=>$chat_id));
                foreach($chatParticipants as $cp) {
                    if($cp->getAccountUser()->getId() != $userData['id']){
                        $cp->setSeenLatest(false);
                    } else {
                        $cp->setSeenLatest(true);
                    }
                    $em->flush();
                }


                $notificationService = $this->get('rx_connexion.notificationService');
                $createdAtDT = $chatMessage->getCreatedAtAsTime();
                $createdAtDate = date('Y-m-d', $createdAtDT);
                $createdAtTime = date('h:i A', $createdAtDT);
                $notificationService->send(array('event' => 'new msg sent', 'data' => array(
                    'refId' => $refId,
                    'chatId' => $chat->getId(),
                    'messageId' => $chatMessage->getId(),
                    'enMessageId' => $chatMessage->getIdEncoded(),
                    'senderId' => $chatParticipant->getAccountUser()->getId(),
                    'senderName' => $chatParticipant->getAccountUser()->getFullName(),
                    'date' => $createdAtDate,
                    'time' => $createdAtTime,
                    'msg' => $msg,
                    'receiverIds' => $em->getRepository('RxConnexionBundle:ChatEntity')->getReceiverIds($chat_id)
                )));

                $result['id'] = $chatMessage->getId();
                $dttst = new DateTimeToStringTransformer();
                $dt =  date('Y-m-d h:i A', strtotime($dttst->transform($chatMessage->getCreatedAt())));
                $result['dt'] = $dt;
                $result['added'] = true;
            }

            $result['success'] = true;
        }

        return new JsonResponse($result);
    }

    /**
     * @Route("/recent-chats", name="chat_count_recent")
     */
    public function chat_count_recentAction(Request $request) {
        $authService = $this->get('rx_connexion.authService');
        $result = array();
        if($authService->isLoggedIn()) {
            $userData = $this->get('session')->get('userData');
            $em = $this->getDoctrine()->getManager();
            $chats = $em->getRepository('RxConnexionBundle:ChatEntity')->countRecentChat($userData['id']);
            $ctr = count($chats);
            $result = array('success'=>true,'ctr'=>$ctr,'chats'=>$chats);
        }

        return new JsonResponse($result);
    }
}