<?php

namespace RxConnexionBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;

use RxConnexionBundle\Entity\AuditTrailEntity;

use RxConnexionBundle\Entity\AddInventoryEntity;
use RxConnexionBundle\Entity\CheckTranEntity;
use RxConnexionBundle\Form\AddInventoryForm;

use RxConnexionBundle\Entity\AddInventoryItemEntity;
use RxConnexionBundle\Form\AddInventoryItemForm;

use RxConnexionBundle\Entity\AddInventoryPaymentEntity;
use RxConnexionBundle\Form\AddInventoryPaymentForm;

/**
 * @Route("/admin/add_inventory")
 */
class AddInventoryController extends Controller
{
    /**
     * @Route("", name="add_inventory")
     */
    public function indexAction() {

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

        return $this->render('@RxConnexion/AddInventory/index.html.twig', array(
            'title' => 'Add Inventory',
            'page_title' => 'Add Inventory',
            'javascripts' => array('rxconnexion/admin/js/addInventory/addInventory.js')
        ));
    }

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

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

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

        if($this->get('rx_connexion.authService')->isLoggedIn()) {
            $result = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:AddInventoryEntity')->ajax_list($get, $this->get('session')->get('userData'));
        }

        return new JsonResponse($result);
    }

    /**
     * @Route(
     *      "/form/{action}/{id}",
     *      defaults = {
     *          "action":  "n",
     *          "id": 0
     *      },
     *      requirements = {
     *          "action": "n|u"
     *      },
     *      name = "add_inventory_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 Add Inventory New', 'Admin Add Inventory Update'))) return $authService->redirectToHome();

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

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

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

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

            $addInventory_form = $request->get($form->getName());
            $result = $this->processForm($addInventory_form, $addInventory, $form, $request);

            if($result['success']) {
                if($result['redirect'] === 'index') {
                    return $this->redirect($this->generateUrl('add_inventory'), 302);
                } else if($result['redirect'] === 'item') {
                    return $this->redirect($this->generateUrl('add_inventory_item', array(
                        'addInventory_id' => base64_encode($result['id'])
                    )), 302);
                } else if($result['redirect'] === 'form') {
                    return $this->redirect($this->generateUrl('add_inventory_form', array(
                        'action' => 'u',
                        'id' => base64_encode($result['id'])
                    )), 302);
                } else if($result['redirect'] === 'form with error') {
                    return $this->redirect($this->generateUrl('add_inventory_form'), 302);
                }
            }
        }

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

        return $this->render('@RxConnexion/AddInventory/form.html.twig', array(
            'title' => $title,
            'page_title' => $title,
            'form' => $form->createView(),
            'javascripts' => array('rxconnexion/admin/js/addInventory/addInventory_form.js'),
            'action' => $action,
            'id' => $id
        ));
    }

    private function processForm($addInventory_form, $addInventory, $form, Request $request) {

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

        $errors = $em->getRepository('RxConnexionBundle:AddInventoryEntity')->validate($addInventory_form);

        if(!count($errors)) {

            switch($addInventory_form['action']) {

                case 'n': // new

                    $form->handleRequest($request);

                    if ($form->isValid()) {

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

//                        $newAT = new AuditTrailEntity(
//                            'Device',
//                            $em->getClassMetadata(DeviceEntity::class)->getTableName(),
//                            AuditTrailEntity::AXN_NEW
//                        );
//                        $newAT->entity = $device;
//                        $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(
//                        'Device',
//                        $em->getClassMetadata(DeviceEntity::class)->getTableName(),
//                        AuditTrailEntity::AXN_UPDATE
//                    );
//                    $newAT->entity = $device;
//                    $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['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

                    $addInventory = $em->getRepository('RxConnexionBundle:AddInventoryEntity')->find($addInventory_form['id']);
                    $em->remove($addInventory);

//                    $newAT = new AuditTrailEntity();
//                    $newAT->setUser($em->getReference('RxConnexionBundle:UserEntity', base64_decode($_COOKIE['userId'])));
//                    $newAT->entity = $addInventory;
//                    $newAT->setRefTable('add_inventory');
//                    $newAT->parseInformation('Delete');
//                    $em->persist($newAT);

                    $em->flush();

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

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

                    break;
            }

            $result['success'] = true;

        } else {

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

            $result['success'] = false;
        }

        return $result;
    }

    /**
     * @Route(
     *      "/item/index/{addInventory_id}",
     *      name = "add_inventory_item"
     * )
     */
    public function itemAction($addInventory_id) {

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

        $em = $this->getDoctrine()->getManager();
        $addInventory = $em->getRepository('RxConnexionBundle:AddInventoryEntity')->find(base64_decode($addInventory_id));

        return $this->render('@RxConnexion/AddInventory/item.html.twig', array(
            'title' => 'Add Inventory Items',
            'page_title' => 'Add Inventory Items',
            'javascripts' => array('rxconnexion/admin/js/addInventory/addInventoryItem.js'),
            'addInventory_id' => $addInventory_id,
            'addInventory' => $addInventory
        ));
    }

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

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

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

        if($this->get('rx_connexion.authService')->isLoggedIn()) {
            $result = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:AddInventoryItemEntity')->ajax_list($get, $this->get('session')->get('userData'));
        }

        return new JsonResponse($result);
    }

    /**
     * @Route("/item/form", name="add_inventory_item_form")
     */
    public function item_formAction(Request $request) {

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

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) $result['errorMessages'][] = 'You have not logged in. Please reload the page.';
        if(!$authService->isUserHasAccesses(array('Admin Add Inventory Item New', 'Admin Add Inventory Item Update'))) $result['errorMessages'][] = 'You don\'t have the right to make the action. Please contact the administrator.';

        if(!count($result['errorMessages'])) {

            $result['success'] = true;
            $em = $this->getDoctrine()->getManager();
            $addInventory_id = $request->query->get('addInventory_id');
            $id = $request->query->get('id');
            $action = $request->query->get('action');

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

            $formOptions = array(
                'action' => $action,
                'addInventory' => base64_decode($addInventory_id)
            );
            $form = $this->createForm(AddInventoryItemForm::class, $addInventoryItem, $formOptions);

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

            $result['html'] = $this->renderView('@RxConnexion/AddInventory/item_form.html.twig', array(
                'page_title' => $title,
                'form' => $form->createView(),
                'action' => $action,
                'id' => $id
            ));
        }

        return new JsonResponse($result);
    }

    /**
     * @Route("/item/form_action", name="add_inventory_item_form_action")
     */
    public function item_form_actionAction(Request $request) {

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

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) $result['errorMessages'][] = 'You have not logged in. Please reload the page.';
        if(!$authService->isUserHasAccesses(array('Admin Add Inventory Item New', 'Admin Add Inventory Item Update'))) $result['errorMessages'][] = 'You don\'t have the right to make the action. Please contact the administrator.';

        if(!count($result['errorMessages'])) {

            $em = $this->getDoctrine()->getManager();
            $addInventoryItem_form = $request->get('addInventoryItem');

            $addInventoryItem = $em->getRepository('RxConnexionBundle:AddInventoryItemEntity')->find($addInventoryItem_form['id']);
            if (!$addInventoryItem) {
                $addInventoryItem = new AddInventoryItemEntity();
            }

            $formOptions = array(
                'action' => $addInventoryItem_form['action'],
                'addInventory' => $addInventoryItem_form['addInventory'],
            );
            $form = $this->createForm(AddInventoryItemForm::class, $addInventoryItem, $formOptions);

            $errors = $em->getRepository('RxConnexionBundle:AddInventoryItemEntity')->validate($addInventoryItem_form);

            if(!count($errors)) {
                switch($addInventoryItem_form['action']) {

                    case 'n': // new

                        $form->handleRequest($request);

                        if ($form->isValid()) {

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

//                        $newAT = new AuditTrailEntity(
//                            'Device',
//                            $em->getClassMetadata(DeviceEntity::class)->getTableName(),
//                            AuditTrailEntity::AXN_NEW
//                        );
//                        $newAT->entity = $device;
//                        $newAT->parseDetails();
//                        $em->persist($newAT);
//                        $em->flush();

                            $result['success'] = true;
                            $result['successMessages'][] = 'Record Successfully Saved.';
                            $result['redirect'] = 'index';

                        } else {
                            $result['successMessages'][] = 'Something went wrong. Please try again.';
                            $result['redirect'] = 'form with error';
                        }

                        break;

                    case 'u': // update

//                    $newAT = new AuditTrailEntity(
//                        'Device',
//                        $em->getClassMetadata(DeviceEntity::class)->getTableName(),
//                        AuditTrailEntity::AXN_UPDATE
//                    );
//                    $newAT->entity = $device;
//                    $newAT->parseOriginalDetails();

                        $form->handleRequest($request);

                        if ($form->isValid()) {

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

                            $em->flush();

                            $result['success'] = true;
                            $result['successMessages'][] = 'Record Successfully Saved.';
                            $result['redirect'] = 'index';

                        } else {
                            $result['successMessages'][] = 'Something went wrong. Please try again.';
                            $result['redirect'] = 'form with error';
                        }

                        break;

                    case 'd': // delete

                        $addInventoryItem = $em->getRepository('RxConnexionBundle:AddInventoryItemEntity')->find($addInventoryItem_form['id']);
                        $em->remove($addInventoryItem);
//
//                        $newAT = new AuditTrailEntity();
//                        $newAT->setUser($em->getReference('RxConnexionBundle:UserEntity', base64_decode($_COOKIE['userId'])));
//                        $newAT->entity = $addInventoryItem;
//                        $newAT->setRefTable('add_inventory_item');
//                        $newAT->parseInformation('Delete');
//                        $em->persist($newAT);

                        $em->flush();

                        $result['successMessages'] = array('Record Successfully Deleted.');

                        break;
                }

                $result['success'] = true;

            } else {

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

        return new JsonResponse($result);
    }

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

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

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) $result['errorMessages'][] = 'You have not logged in. Please reload the page.';
        if(!$authService->isUserHasAccesses(array('Admin Add Inventory Item Send'))) $result['errorMessages'][] = 'You don\'t have the right to make the action. Please contact the administrator.';
        $em = $this->getDoctrine()->getManager();
        $addInventory_id = $request->get('addInventory_id');
        $addInventory = $em->getRepository('RxConnexionBundle:AddInventoryEntity')->find(base64_decode($addInventory_id));

        if($addInventory->getTotalPrice() != $addInventory->getTotalPayment()) {
            $result['errorMessages'][] = 'Total price of all items should match the total amount of payments.';
        }

        if(!count($result['errorMessages'])) {

            $addInventory->setStatus('Completed');

//            $newAT = new AuditTrailEntity();
//            $newAT->setUser($em->getReference('RxConnexionBundle:UserEntity', base64_decode($_COOKIE['userId'])));
//            $newAT->entity = $addInventory;
//            $newAT->setRefTable('add_inventory');
//            $newAT->parseInformation('Send');
//            $em->persist($newAT);
//            $em->flush();

            $inventoryService = $this->get('rx_connexion.inventoryService');
            $inventoryService->recordMovement('Inventory Add Inventory Send', array(
                'addInventory' => $addInventory
            ));

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

            $result['success'] = true;
        }

        return new JsonResponse($result);
    }

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

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

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

        if($this->get('rx_connexion.authService')->isLoggedIn()) {
            $result = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:AddInventoryPaymentEntity')->ajax_list($get, $this->get('session')->get('userData'));
        }

        return new JsonResponse($result);
    }

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

        $result['success'] = false;

        $authService = $this->get('rx_connexion.authService');
        if($authService->isLoggedIn() && $authService->isUserHasAccesses(array('Admin Add Inventory Payment New', 'Admin Add Inventory Payment Update'))) {

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

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

            $formOptions = array(
                'action' => $action,
                'addInventory' => base64_decode($addInventory_id)
            );
            $form = $this->createForm(AddInventoryPaymentForm::class, $addInventoryPayment, $formOptions);

            $addInventory = $em->getRepository('RxConnexionBundle:AddInventoryEntity')->find(base64_decode($addInventory_id));

            $title = ($action === 'n' ? 'Add' : 'Update') . ' Payment';
            $result['html'] = $this->renderView('@RxConnexion/AddInventory/payment_form.html.twig', array(
                'title' => $title,
                'page_title' => $title,
                'form' => $form->createView(),
                'action' => $action,
                'id' => $id,
                'addInventory' => $addInventory
            ));

            $result['success'] = true;
        }

        return new JsonResponse($result);
    }

    /**
     * @Route(
     *      "/payment/form_action",
     *      name = "add_inventory_payment_form_action"
     * )
     */
    public function payment_form_actionAction(Request $request) {

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

        $authService = $this->get('rx_connexion.authService');
        if($authService->isLoggedIn() && $authService->isUserHasAccesses(array('Admin Add Inventory Payment New', 'Admin Add Inventory Payment Update'))) {

            $addInventoryPayment_form = $request->get('addInventoryPayment');
            $em = $this->getDoctrine()->getManager();

            $addInventoryPayment = $em->getRepository('RxConnexionBundle:AddInventoryPaymentEntity')->find($addInventoryPayment_form['id']);

            if (!$addInventoryPayment) {
                $addInventoryPayment = new AddInventoryPaymentEntity();
            }

            $formOptions = array(
                'action' => $addInventoryPayment_form['action'],
                'addInventory' => base64_decode($addInventoryPayment_form['addInventory'])
            );
            $form = $this->createForm(AddInventoryPaymentForm::class, $addInventoryPayment, $formOptions);

            $errors = $em->getRepository('RxConnexionBundle:AddInventoryPaymentEntity')->validate($addInventoryPayment_form);

            if(!count($errors)) {

                switch($addInventoryPayment_form['action']) {

                    case 'n': // new

                        $form->handleRequest($request);

                        if ($form->isValid()) {

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

//                        $newAT = new AuditTrailEntity(
//                            'Device',
//                            $em->getClassMetadata(DeviceEntity::class)->getTableName(),
//                            AuditTrailEntity::AXN_NEW
//                        );
//                        $newAT->entity = $device;
//                        $newAT->parseDetails();
//                        $em->persist($newAT);
//                        $em->flush();

                            $result['success'] = true;
                            $result['successMessages'][] = 'Record Successfully Saved.';
                            $result['redirect'] = 'index';

                        } else {
                            $result['successMessages'][] = 'Something went wrong. Please try again.';
                            $result['redirect'] = 'form with error';
                        }

                        break;

                    case 'u': // update

//                    $newAT = new AuditTrailEntity(
//                        'Device',
//                        $em->getClassMetadata(DeviceEntity::class)->getTableName(),
//                        AuditTrailEntity::AXN_UPDATE
//                    );
//                    $newAT->entity = $device;
//                    $newAT->parseOriginalDetails();

                        $form->handleRequest($request);

                        if ($form->isValid()) {

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

                            $em->flush();

                            $result['success'] = true;
                            $result['successMessages'][] = 'Record Successfully Saved.';
                            $result['redirect'] = 'index';

                        } else {
                            $result['successMessages'][] = 'Something went wrong. Please try again.';
                            $result['redirect'] = 'form with error';
                        }

                        break;

                    case 'd': // delete

                        $addInventoryPayment = $em->getRepository('RxConnexionBundle:AddInventoryPaymentEntity')->find($addInventoryPayment_form['id']);
                        $em->remove($addInventoryPayment);
                        $em->flush();

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

                        break;
                }

            } else {

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

        return new JsonResponse($result);
    }

    /**
     * @Route("/received_record/print/{addInventory_id}", name="add_inventory_received_record_print")
     */
    public function recieved_record_printAction($addInventory_id) {

        $authService = $this->get('rx_connexion.authService');
        ini_set('memory_limit', '2048M');
        if(!$authService->isLoggedIn()){
            return $authService->redirectToLogin();
        }

        set_time_limit(0);
        $em = $this->getDoctrine()->getManager();
        $addInventory = $em->getRepository('RxConnexionBundle:AddInventoryEntity')->find(base64_decode($addInventory_id));

        $content = $this->renderView('@RxConnexion/AddInventory/received_record_print.pdf.twig', array(
            'addInventory' => $addInventory,
            'userData' => $authService->getUser()
        ));

        $xml = $this->get('knp_snappy.pdf')->getOutputFromHtml($content, array(
//            'dpi' => 72,
            // 'disable-smart-shrinking',
//            'zoom' => 'LINUX' == strtoupper(PHP_OS) ? 0.78 : 1
        ));

        $pdfResponse = array(
            'success' => true,
            'msg' => 'PDF was successfully generated.',
            'pdfBase64' => base64_encode($xml)
        );
        if($pdfResponse['success']) {
            $pdfContent = $pdfResponse['pdfBase64'];
            return new Response(base64_decode($pdfContent), 200, array(
                'Content-Type' => 'application/pdf',
                'Content-Disposition'   => 'attachment; filename="Received Record' . date('m/d/Y') . ' Details.pdf"'
            ));
        } else {
            $this->get('session')->getFlashBag()->set('error_messages', $pdfResponse['msg']);
            return $this->redirect($this->generateUrl('add_inventory_item', array(
                'addInventory_id' => $addInventory_id
            ), 302));
        }

    }
}
