<?php

namespace RxConnexionBundle\Controller;

use RxConnexionBundle\Entity\HealthFacilityEntity;
use RxConnexionBundle\Entity\InventorySerialNoEntity;
use RxConnexionBundle\Entity\SystemParameterEntity;
use RxConnexionBundle\Service\ItemService;
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\Entity\InventoryEntity;
use RxConnexionBundle\Form\InventoryForm;

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

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

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

        return $this->render('@RxConnexion/Inventory/index.html.twig', array(
            'title' => 'Inventory',
            'page_title' => 'Inventory',
            'javascripts' => array('rxconnexion/admin/js/inventory/inventory.js?v=1.0.3','rxconnexion/admin/js/report/report.js'),
            'branches' => $userData['type'] == 'Super Admin'
	            ? $em->getRepository(HealthFacilityEntity::class)->findAllNotDeleted()
	            : $em->getRepository(HealthFacilityEntity::class)->findAllByIds($userData['branches'], true),
            'inventoryStatuses' => $this->get('rx_connexion.inventoryService')->getInventoryStatuses()
        ));
    }

    /**
     * @Route("/ajax_list", name="inventory_ajax_list")
     */
    public function ajax_list(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:InventoryEntity')->ajax_list($get, $this->get('session')->get('userData'));
        }

        return new JsonResponse($result);
    }

    /**
     * @Route("/ajax_list_sales_order", name="inventory_ajax_list_sales_order")
     */
    public function ajax_list_sales_order(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:InventoryEntity')->ajax_list_sales_order($get, $this->get('session')->get('userData'));
        }

        return new JsonResponse($result);
    }

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

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

        $inventory = $em->getRepository('RxConnexionBundle:InventoryEntity')->find(base64_decode($id));
        if(!$inventory) {
            $inventory = new InventoryEntity();
        } else {
	        // COMPUTE AVERAGE COST
	        $itemService = new ItemService($em, $this->container);
	        $itemService->computeAverageCostByBranch($inventory->getItem(), $inventory->getHealthFacility());
	        $inventory->getInitialQuantity();
        }

        $userData = $this->get('session')->get('userData');
        $formOptions = array(
            'action' => $action,
            //'user_branchIds' => $this->get('session')->get('userData')['branchIds'],
            'inventoryStatuses' => $this->get('rx_connexion.inventoryService')->getInventoryStatuses(),
	        'is_itemised' => $inventory->getItem() ? $inventory->getItem()->getIsItemised() : false,
	        'userType' => $userData['type']
        );
        $form = $this->createForm(InventoryForm::class, $inventory, $formOptions);

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

            $inventory_form = $request->get($form->getName());
            $result = $this->processForm($inventory_form, $inventory, $form, $request);

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

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

	    $historyStartDate = $em->getRepository(SystemParameterEntity::class)->getValueByDesc('Inventory History Start Date');
        return $this->render('@RxConnexion/Inventory/form.html.twig', array(
	        'title'            => $title,
	        'page_title'       => $title,
	        'javascripts'      => array('rxconnexion/admin/js/inventory/inventory_form.js?v=1.0.4'),
	        'form'             => $form->createView(),
	        'action'           => $action,
	        'id'               => $id,
	        'inventory'        => $inventory,
	        'historyStartDate' => $historyStartDate ? new \DateTime($historyStartDate) : new \DateTime('04/20/2021 00:00:00'),
        ));
    }

    private function processForm($inventory_form, $inventory, $form, Request $request) {

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

        $errors = $em->getRepository('RxConnexionBundle:InventoryEntity')->validate($inventory_form);

        if(!count($errors)) {

            switch($inventory_form['action']) {

                case 'n': // new

                    $form->handleRequest($request);

                    if ($form->isValid()) {

                        $em->persist($inventory);
                        $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

                    $inventory = $em->getRepository('RxConnexionBundle:InventoryEntity')->find($inventory_form['id']);
                    $em->remove($inventory);

//                    $newAT = new AuditTrailEntity();
//                    $newAT->setUser($em->getReference('RxConnexionBundle:UserEntity', base64_decode($_COOKIE['userId'])));
//                    $newAT->entity = $inventory;
//                    $newAT->setRefTable('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("/autocomplete", name="inventory_autocomplete")
     */
    public function autocompleteAction(Request $request) {

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

        $result = array(
            'query' => 'inventories',
            'suggestions' => $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:InventoryEntity')->autoCompleteSuggestions($q, $this->get('session')->get('userData'))
        );

        return new JsonResponse($result);
    }

    /**
     * @Route("/serial-no/autocomplete", name="inventory_serial_no_autocomplete")
     */
    public function inventory_serial_no_autocompleteAction(Request $request) {

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

        $result = array(
            'query' => 'inventories',
            'suggestions' => $this->getDoctrine()->getManager()->getRepository(InventorySerialNoEntity::class)->autoCompleteSuggestions($q, $this->get('session')->get('userData'))
        );

        return new JsonResponse($result);
    }

	/**
	 * @Route("/setup/initial-quantity", name="inventory_setup_initial_quantity")
	 */
	public function setup_initial_quantityAction(Request $request) {

		$userData = $this->get('session')->get('userData');
		$authService = $this->get('rx_connexion.authService');
		if ($userData['type'] !== 'Super Admin') {
			return $authService->redirectToHome();
		}

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

		$now = (new \DateTime())->format('Y-m-d H:i:s');

		$sql = "UPDATE inventory SET initial_quantity = IF(quantity >= 0, quantity, 0) WHERE status = 'Stock On Hand';";
		$sql = $connection->prepare($sql);
		$sql->execute();

		$desc = 'Inventory History Start Date';
		$historyStartDate = $em->getRepository(SystemParameterEntity::class)->findOneBy(['description' => $desc]);
		if($historyStartDate) {
			$historyStartDate->setValue($now);
		} else {
			$historyStartDate = new SystemParameterEntity();
			$historyStartDate->setDescription($desc);
			$historyStartDate->setValue($now);
			$em->persist($historyStartDate);
		}
		$em->flush();

		$this->get('session')->getFlashBag()->set('success_messages', 'Initial Quantity successfully updated.');
		return $this->redirect($this->generateUrl('inventory'), 302);
    }
}
