<?php

/**
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is protected 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
 * @version    $Id:$
 * @link       http://www.life-style.de
 */

namespace LifeStyle\Tools\BackendSecurityBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
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 Symfony\Component\Form\Extension\Core\Type as FormType;

/**
 * Class UserController
 * @package LifeStyle\Tools\BackendSecurityBundle\Controller
 */
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("/", name="_lifestyle_backend_security_user_edit")
     * @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 array(
            'entity' => $entity,
            'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        );
    }

    /**
     * @return Response
     */
    public function newAction()
    {
        $entity = $this->userManager()->createUser();
        $form = $this->createCreateForm($entity);

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

    /**
     * @param 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(),
        ));
    }

    /**
     * @param Request $request
     * @param int $userId
     * @return Response
     */
    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 The form
     */
    private function createEditForm(UserEntity $entity)
    {
        $form = $this->createForm(UserForm::class, $entity, array(
            'action' => $this->generateUrl('_lifestyle_backend_security_user_update',
                array('userId' => $entity->getId())),
            'roles' => $this->getUserRoleHierarchy(),
            'method' => 'PUT',
        ));
        if ($form->has('Password')) {
            $form->get('Password')->setData('');
        }

        $form->add('submit', FormType\SubmitType::class, array('label' => 'Update'));

        return $form;
    }

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

        $form->add('submit', FormType\SubmitType::class, array('label' => 'Create'));

        return $form;
    }

    /**
     * @param integer $userId The entity id
     * @return \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', FormType\SubmitType::class, array('label' => 'Delete'))
            ->getForm();
    }

    /**
     * @param Request $request
     * @param int $userId
     * @return 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'));
    }

    /**
     * @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');
    }
}
