<?php

/**
 * Lifestyle Webconsulting GmbH
 *
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is private by copyright law - it is NOT Freeware.
 *
 * Any unauthorized use of this software without a valid license
 * is a violation of the license agreement and will be prosecuted by
 * civil and criminal law.
 *
 * @copyright  2020 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 */

namespace Sso\BackendBundle\Controller;

use Sso\WebserviceBundle\Database\Webservice\UserApplicationRole;
use Sso\WebserviceBundle\Entity\Webservice\Type\Role;
use Symfony\Component\Form\Form as SfForm;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Sso\BackendBundle\Form;

/**
 * Class WsApplicationRoleController
 * @package Sso\BackendBundle\Controller
 */
class WsApplicationRoleController extends WsAbstractController
{
    const SUBMIT = 'submit';
    const LABEL = 'label';
    const SESSION = 'session';
    const ENTITY = 'entity';
    const FORM = 'form';
    const DELETE_FORM = 'delete_form';

    /**
     * @return Response
     */
    public function indexAction()
    {
        $controller = $this;
        $routeGenerator = function ($page) use ($controller) {
            return $controller->generateUrl('_admin_backend_webservice_application_role', array('page' => $page));
        };
        list($filterForm, $queryBuilder) = $this->filter(
            new Form\WsApplicationRoleFilterType(),
            $this->roleHandler()->getRepository()
        );
        list($entities, $pagerHtml) = $this->paginator($queryBuilder, $routeGenerator);

        return $this->render('SsoBackendBundle:ws_application_role:index.html.twig', [
            'entities' => $entities,
            'pagerHtml' => $pagerHtml,
            'filterForm' => $filterForm->createView(),
        ]);
    }

    /**
     *
     * @param string $roleId
     * @return Response
     */
    public function showAction($roleId)
    {
        $entity = $this->roleHandler()->getRepository()->find($roleId);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find ApplicationRole entity.');
        }

        $deleteForm = $this->createDeleteForm($roleId);

        return $this->render('SsoBackendBundle:ws_application_role:show.html.twig', [
            self::ENTITY => $entity,
            self::DELETE_FORM => $deleteForm->createView(),
        ]);
    }

    /**
     * @param string $roleId
     * @return Response
     */
    public function editAction($roleId)
    {
        $entity = $this->roleHandler()->getRoleById($roleId);
        if (!$entity) {
            throw $this->createNotFoundException('Attribute not found!');
        }

        $editForm = $this->createEditForm($entity);
        $deleteForm = $this->createDeleteForm($roleId);

        return $this->render('SsoBackendBundle:ws_application_role:edit.html.twig', [
            self::ENTITY => $entity,
            self::FORM => $editForm->createView(),
            self::DELETE_FORM => $deleteForm->createView(),
        ]);
    }

    /**
     * @param Request $request
     * @param string $roleId
     * @return RedirectResponse|Response
     */
    public function updateAction(Request $request, $roleId)
    {
        $entity = $this->roleHandler()->getRoleById($roleId);
        if (!$entity) {
            throw $this->createNotFoundException('Role not found!');
        }
        $deleteForm = $this->createDeleteForm($roleId);
        $editForm = $this->createEditForm($entity);
        $editForm->handleRequest($request);

        if ($editForm->isValid()) {
            $this->roleHandler()->saveRole($entity);
            $this->userAppHandler()->updateRole($entity);
            $this->get(self::SESSION)->getFlashBag()->add('info', 'Role Saved Sucess');

            return $this->redirect(
                $this->generateUrl(
                    '_admin_backend_webservice_application_role_edit',
                    ['roleId' => $roleId]
                )
            );
        }

        return $this->render('SsoBackendBundle:ws_application_role:edit.html.twig', array(
            self::ENTITY => $entity,
            self::FORM => $editForm->createView(),
            self::DELETE_FORM => $deleteForm->createView(),
        ));
    }

    /**
     * @param Request $request
     * @return RedirectResponse|Response
     */
    public function newAction(Request $request)
    {
        $entity = new Role($this->container->get('validator'));
        if (null === $entity->getId()) {
            $entity->generateId();
        }
        $form = $this->createCreateForm($entity);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $this->roleHandler()->saveRole($entity);

            $this->get(self::SESSION)->getFlashBag()->add('success', 'Role created success');
            return $this->redirect(
                $this->generateUrl('_admin_backend_webservice_application_role')
            );
        }

        return $this->render('SsoBackendBundle:ws_application_role:new.html.twig', [
            self::ENTITY => $entity,
            self::FORM => $form->createView(),
        ]);
    }

    /**
     * @param Request $request
     * @param string $roleId
     * @return RedirectResponse
     */
    public function deleteAction(Request $request, $roleId)
    {
        $form = $this->createDeleteForm($roleId);
        $form->handleRequest($request);

        if ($form->isValid()) {
            $entity = $this->roleHandler()->getRoleById($roleId);

            if (!$entity) {
                throw $this->createNotFoundException('Unable to find role entity.');
            }

            $status = $this->roleHandler()->deleteRole($entity);
            if ($status) {
                $this->get(self::SESSION)->getFlashBag()->add('success', 'Role deleted.');
            } else {
                $this->get(self::SESSION)->getFlashBag()->add(
                    'error',
                    'There are users linked to role. Delete links first.'
                );

            }
        } else {
            $this->get(self::SESSION)->getFlashBag()->add('error', 'Error while deleting role.');
        }

        return $this->redirect($this->generateUrl('_admin_backend_webservice_application_role'));
    }

    /**
     * Ajax search for applications roles
     * @param \Symfony\Component\HttpFoundation\Request $request
     * @param string $applicationId
     * @return JsonResponse|Response
     */
    public function searchAction(Request $request, $applicationId)
    {
        if (!$request->isXmlHttpRequest()) {
            return new Response('This is no ajax request!', 400);
        }

        $query = $request->get('query', '');
        $limit = $request->get('limit', 10);
        $offset = ($request->get('page', 1) - 1) * $limit;
        $items = array();
        foreach ($this->roleHandler()->getRolesByName($applicationId, $query, $limit, $offset) as $role) {
            array_push($items, array(
                'id' => $role->getId(),
                'text' => $role->getName(),
            ));
        }

        $response = new JsonResponse(array(
            'total' => count($items),
            'items' => $items,
        ));
        if (null !== ($callback = $request->get('callback'))) {
            $response->setCallback($callback);
        }

        return $response;
    }

    /**
     * @return \Sso\WebserviceBundle\Database\Webservice\Role Database handler for application role model
     */
    private function roleHandler()
    {
        return $this->databaseManager()->webservice()->role();
    }

    /**
     * @param Role $entity
     * @return SfForm
     */
    private function createCreateForm(Role $entity)
    {
        $form = $this->createForm(
            new Form\WsApplicationRoleType(),
            $entity,
            [
                'action' => $this->generateUrl('_admin_backend_webservice_application_role_new'),
                'method' => 'POST',
            ]
        );

        $form->add(self::SUBMIT, self::SUBMIT, [self::LABEL => 'Create Role']);

        return $form;
    }

    /**
     * @param Role $entity
     * @return SfForm
     */
    private function createEditForm(Role $entity)
    {
        $form = $this->createForm(
            new Form\WsApplicationRoleType(),
            $entity,
            [
                'action' => $this->generateUrl(
                    '_admin_backend_webservice_application_role_update',
                    ['roleId' => $entity->getId()]
                ),
                'method' => 'PUT',
            ]
        );
        $form->add(self::SUBMIT, self::SUBMIT, [self::LABEL => 'Update']);
        return $form;
    }

    /**
     * @param string $roleId
     * @return SfForm|FormInterface
     */
    private function createDeleteForm($roleId)
    {
        return $this->createFormBuilder()
            ->setAction(
                $this->generateUrl(
                    '_admin_backend_webservice_application_role_delete',
                    ['roleId' => $roleId]
                )
            )
            ->setMethod('DELETE')
            ->add(self::SUBMIT, self::SUBMIT, [self::LABEL => 'Delete Role'])
            ->getForm();
    }

    /**
     * @return UserApplicationRole
     */
    private function userAppHandler()
    {
        return $this->databaseManager()->webservice()->userApplicationRole();
    }
}
