<?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  2018 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 */

namespace LifeStyle\Tools\BackendSecurityBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use LifeStyle\Tools\BackendSecurityBundle\Form\User as UserForm;
use LifeStyle\Tools\BackendSecurityBundle\Entity\User as UserEntity;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;

/**
 * Admin user controller
 * @Security("has_role('ROLE_SUPER_ADMIN')")
 */
class UserController extends Controller
{
    /**
     * @var \FOS\UserBundle\Doctrine\UserManager
     */
    private $userManager;

    /**
     * @Route("/", name="_lifestyle_backend_security_user")
     * @Template()
     */
    public function indexAction()
    {
        return array(
            'entities' => $this->userManager()->findUsers(),
        );
    }

    /**
     * @Route("/{userId}/edit", name="_lifestyle_backend_security_user_edit", requirements={"userId": "\d+"})
     * @Template()
     * @param int $userId
     * @return Response
     * @throws NotFoundHttpException
     */
    public function editAction($userId)
    {
        $entity = $this->userManager()->findUserBy(array('id' => $userId));
        if (!$entity) {
            throw $this->createNotFoundException('User not found!');
        }

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

        return [
            'entity' => $entity,
            'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        ];
    }

    /**
     * @Route("/new", name="_lifestyle_backend_security_user_new")
     * @Template()
     * @return Response
     */
    public function newAction()
    {
        $entity = $this->userManager()->createUser();
        $form = $this->createCreateForm($entity);

        return ['entity' => $entity, 'form' => $form->createView()];
    }

    /**
     * Create new backend user
     * @Route("/create", name="_lifestyle_backend_security_user_create")
     * @param \Symfony\Component\HttpFoundation\Request $request
     * @return Response
     */
    public function createAction(Request $request)
    {
        $entity = $this->userManager()->createUser();
        $form = $this->createCreateForm($entity);
        $form->handleRequest($request);

        if ($form->isValid()) {

            // Generate random password, if empty
            if ($form->has('PlainPassword') && $form->get('PlainPassword')->isEmpty()) {
                $entity->setPlainPassword(hash('sha256', mt_rand() . '#' . microtime()));
            }

            $this->userManager()->updateUser($entity);
            $this->get('session')->getFlashBag()->add('success', 'User created success');
            return $this->redirect(
                $this->generateUrl('_lifestyle_backend_security_user_show',
                    array('userId' => $entity->getId()))
            );
        }
        return $this->render(
            'LifeStyleToolsBackendSecurityBundle:User:new.html.twig',
            array(
                'entity' => $entity,
                'form' => $form->createView(),
            )
        );
    }

    /**
     * @Route("/{userId}/update", name="_lifestyle_backend_security_user_update", requirements={"userId": "\d+"})
     * @Template()
     * @param \Symfony\Component\HttpFoundation\Request $request
     * @param int $userId
     * @return string
     */
    public function updateAction(Request $request, $userId)
    {
        $entity = $this->userManager()->findUserBy(array('id' => $userId));
        if (!$entity) {
            throw $this->createNotFoundException('User not found!');
        }
        $deleteForm = $this->createDeleteForm($userId);
        $editForm = $this->createEditForm($entity);
        $editForm->handleRequest($request);

        if ($editForm->isValid()) {
            $this->userManager()->updateUser($entity);
            $this->get('session')->getFlashBag()->add('info', 'User Saved Success');
            return $this->redirect($this->generateUrl('_lifestyle_backend_security_user_edit',
                array('userId' => $userId)));
        }
        return $this->render(
            'LifeStyleToolsBackendSecurityBundle:User:edit.html.twig',
            array(
                'entity' => $entity,
                'edit_form' => $editForm->createView(),
                'delete_form' => $deleteForm->createView(),
            )
        );
    }

    /**
     * @param UserEntity $entity
     * @return \Symfony\Component\Form\Form
     */
    private function createEditForm(UserEntity $entity)
    {
        $form = $this->createForm(new UserForm($this->getUserRoleHierarchy()), $entity, array(
            'action' => $this->generateUrl('_lifestyle_backend_security_user_update',
                array('userId' => $entity->getId())),
            'method' => 'PUT',
        ));
        if ($form->has('Password')) {
            $form->get('Password')->setData('');
        }

        $form->add('submit', 'submit', array('label' => 'Update'));

        return $form;
    }

    /**
     * @param UserEntity $entity
     * @return \Symfony\Component\Form\Form
     */
    private function createCreateForm(UserEntity $entity)
    {
        $form = $this->createForm(new UserForm($this->getUserRoleHierarchy()), $entity, array(
            'action' => $this->generateUrl('_lifestyle_backend_security_user_create'),
            'method' => 'POST',
        ));

        $form->add('submit', 'submit', array('label' => 'Create'));

        return $form;
    }

    /**
     * @param $userId
     * @return \Symfony\Component\Form\Form|\Symfony\Component\Form\FormInterface
     */
    private function createDeleteForm($userId)
    {
        return $this->createFormBuilder()
            ->setAction($this->generateUrl('_lifestyle_backend_security_user_delete', array('userId' => $userId)))
            ->setMethod('DELETE')
            ->add('submit', 'submit', array('label' => 'Delete'))
            ->getForm();
    }

    /**
     * @Route("/{userId}/delete", name="_lifestyle_backend_security_user_delete", requirements={"userId": "\d+"})
     * @param \Symfony\Component\HttpFoundation\Request $request
     * @param int $userId
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
     */
    public function deleteAction(Request $request, $userId)
    {
        $form = $this->createDeleteForm($userId);
        $form->handleRequest($request);

        $entity = $this->userManager()->findUserBy(array('id' => $userId));
        if (!$entity) {
            throw $this->createNotFoundException('Unable to find User entity.');
        }

        $this->userManager()->deleteUser($entity);
        $this->get('session')->getFlashBag()->add('success', 'User deleted.');

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

    /**
     * @Route("/{userId}/show", name="_lifestyle_backend_security_user_show", requirements={"userId":"\d+"})
     * @Template()
     * @param int $userId
     * @return Response
     * @throws NotFoundHttpException
     */
    public function showAction($userId)
    {
        $entity = $this->userManager()->findUserBy(array('id' => $userId));
        if (!$entity) {
            throw $this->createNotFoundException('Unable to find user entity.');
        }

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

        return $this->render(
            'LifeStyleToolsBackendSecurityBundle:User:show.html.twig',
            array(
                'entity' => $entity,
                'delete_form' => $deleteForm->createView(),
            )
        );
    }

    /**
     * @return array
     */
    private function getUserRoleHierarchy()
    {
        $roles = $this->container->getParameter('security.role_hierarchy.roles');
        return $roles ? $roles : array();
    }

    /**
     * @return \FOS\UserBundle\Doctrine\UserManager
     */
    private function userManager()
    {
        return null !== $this->userManager ? $this->userManager : $this->get('fos_user.user_manager');
    }
}
