<?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 Sso\BackendBundle\Controller;

use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sso\WebserviceBundle\Entity\Webservice\Type;
use Sso\BackendBundle\Form;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Class WsUserApplicationAttributeController
 * @package Sso\BackendBundle\Controller
 */
class WsUserApplicationAttributeController extends WsAbstractController
{
    /**
     * Show user applications attribute values
     * @param string $userApplicationId
     * @param string $userId
     * @return Response
     */
    public function showAction($userApplicationId, $userId)
    {
        if (!($userApplication = $this->databaseManager()->webservice()->userApplication()->getUserApplicationById($userApplicationId))) {
            throw $this->createNotFoundException('Unable to find user application.');
        }

        return $this->render('SsoBackendBundle:WsUserApplicationAttribute:show.html.twig', [
            'userApplication' => $userApplication,
            'userApplicationAttributes' => $userApplication->getAttributes(),
            'attribute_add_form' => $this->createAttributeAddForm($userApplicationId, $userId)->createView(),
            'htmlUid' => uniqid('i'),
            'controller' => $this,
            'userId' => $userId,
        ]);
    }

    /**
     * Creates a form to add new attributes to user
     *
     * @param string $userApplicationId
     * @param string $userId
     * @return \Symfony\Component\Form\Form The form
     */
    private function createAttributeAddForm($userApplicationId, $userId)
    {
        return $this->createForm(new Form\WsUserApplicationAttribute(), [], [
            'action' => $this->generateUrl(
                '_admin_backend_webservice_user_application_attribute_add',
                ['userId' => $userId, 'userApplicationId' => $userApplicationId]
            ),
            'method' => 'POST',
        ]);
    }

    /**
     * Add attribute to user application
     *
     * @param Request $request
     * @param string $userApplicationId
     * @param string $userId
     * @return Response
     */
    public function addAction(Request $request, $userId, $userApplicationId)
    {
        $form = $this->createAttributeAddForm($userApplicationId, $userId);
        $form->handleRequest($request);
        $formData = $form->getData();

        if ($form->isValid() && isset($formData['attributeId'])) {
            $this->addUserApplicationAttribute(
                $userApplicationId,
                $userId,
                $formData['attributeId'],
                $formData['attributeValue']
            );
        }

        return $this->render('SsoBackendBundle:Layout:messages.html.twig', []);
    }

    /**
     * Add attribute to user application
     *
     * @TODO move out from controller and refactor/split method!
     *
     * @param $userApplicationId
     * @param string $userId
     * @param string $attributeId
     * @param string $attributeValue
     * @return bool
     */
    protected function addUserApplicationAttribute($userApplicationId, $userId, $attributeId, $attributeValue)
    {
        if (!($user = $this->databaseManager()->webservice()->user()->getUserById($userId))) {
            $this->addError('User not found');

            return false;
        }
        if (!($userApplication = $this->databaseManager()->webservice()->userApplication()->getUserApplicationById($userApplicationId))) {
            $this->addError('UsersApplication not found');

            return false;
        }
        if (!($attribute = $this->databaseManager()->webservice()->attribute()->getAttributeById($attributeId))) {
            $this->addError('Attribute not found');

            return false;
        }

        $attributeIsLinked = false;
        foreach ($userApplication->getApplication()->getAttributes() as $linkedAttribute) {
            if ($linkedAttribute->getId() == $attribute->getId()) {
                $attributeIsLinked = true;
            }
        }
        if (!$attributeIsLinked) {
            $this->addError('Attribute is not linked to application.');

            return false;
        }

        if (!$attribute->isArray()) {
            $attrAlreadyLinked = false;
            foreach ($userApplication->getAttributes() as $userApplicationAttr) {
                if ($userApplicationAttr->getAttribute()->getId() == $attributeId) {
                    $attrAlreadyLinked = true;
                }
            }

            if ($attrAlreadyLinked) {
                $this->addError('Attribute is already linked to users application.');

                return false;
            }
        }

        $userApplicationAttr = new Type\UserApplicationAttribute($this->validator());
        $userApplicationAttr->setUserApplication($userApplication)->setAttribute($attribute)->setValue($attributeValue)->generateId();
        if (!$this->databaseManager()->webservice()->userApplicationAttribute()->saveUserApplicationAttribute($userApplicationAttr)) {
            $this->addErrors($userApplicationAttr);

            return false;
        }
        $this->addSuccess('Attribute "' . $attribute->getName() . '" successfully added to users application  "' . $userApplication->getName() . '"');

        return true;
    }

    /**
     * @param Request $request
     * @param string $userApplicationAttributeId
     * @return Response
     */
    public function deleteAction(Request $request, $userApplicationAttributeId)
    {
        $this->deleteUserApplicationAttribute($userApplicationAttributeId);

        return $this->render('SsoBackendBundle:Layout:messages.html.twig', array());
    }

    /**
     * Delete user application attribute
     *
     * @param string $userAppAttrId
     * @return bool
     */
    private function deleteUserApplicationAttribute($userAppAttrId)
    {
        if (!($userAppAttr = $this->getUserApplicationAttribute($userAppAttrId))) {
            return false;
        }
        if (!$this->databaseManager()->webservice()->userApplicationAttribute()->deleteUserApplicationAttributes([$userAppAttr])) {
            $this->addErrors($userAppAttr);

            return false;
        }
        $this->addSuccess('Attribute "' . $userAppAttr->getName() . '" successfully deleted from users application "');

        return true;
    }

    /**
     * Get user application attribute
     *
     * @param string $userAppAttrId
     * @return boolean|Type\UserApplicationAttribute
     */
    private function getUserApplicationAttribute($userAppAttrId)
    {
        if (!($userAppAttr = $this->databaseManager()->webservice()->userApplicationAttribute()->getUserApplicationAttributeById($userAppAttrId))) {
            $this->addError('User Application Attribute not found');

            return false;
        }

        return $userAppAttr;
    }

    /**
     *
     * @param string $userApplicationAttributeId
     * @return \Symfony\Component\HttpFoundation\Response
     * @throws NotFoundHttpException
     */
    public function editAction($userApplicationAttributeId)
    {
        $entity = $this->attributeHandler()->getUserApplicationAttributeById($userApplicationAttributeId);
        if (!$entity) {
            throw $this->createNotFoundException('Attribute not found!');
        }

        $editForm = $this->createEditForm($entity);

        return $this->render('SsoBackendBundle:WsUserApplicationAttribute:edit.html.twig', array(
            'entity' => $entity,
            'htmlUid' => uniqid('i'),
            'edit_form' => $editForm->createView(),
        ));
    }

    /**
     * Creates a form to edit a userapplicationattribute entity.
     *
     * @param Type\UserApplicationAttribute $entity The entity
     *
     * @return \Symfony\Component\Form\Form The form
     */
    private function createEditForm(Type\UserApplicationAttribute $entity)
    {
        $form = $this->createForm(new Form\WsUserApplicationAttributeType(), $entity, array(
            'action' => $this->generateUrl('_admin_backend_webservice_user_application_attribute_update',
                array('userApplicationAttributeId' => $entity->getId())),
            'method' => 'PUT',
        ));

        $form->add('button', 'button', array(
            'label' => 'Close',
            'attr' => array('class' => 'btn btn-success modal-close', 'style' => 'margin-left: 5px;'),
        ))->add('submit', 'submit', array('label' => 'Update'));

        return $form;
    }

    /**
     *
     * @param \Symfony\Component\HttpFoundation\Request $request
     * @param string $userApplicationAttributeId
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function updateAction(Request $request, $userApplicationAttributeId)
    {
        $entity = $this->attributeHandler()->getUserApplicationAttributeById($userApplicationAttributeId);
        if (!$entity) {
            throw $this->createNotFoundException('Attribute not found!');
        }

        // Force doctrine to pull the user-application
        $entity->getUserApplication()->getId();

        $editForm = $this->createEditForm($entity);
        $editForm->handleRequest($request);

        if ($editForm->isValid()) {

            // As user-application has been loaded before form handle,
            // user-updated-at can be updated, if value has been changed
            $entity->getUserApplication()->checkObjectUpdate();

            if ($this->attributeHandler()->saveUserApplicationAttribute($entity)) {
                $this->get('session')->getFlashBag()->add(
                    'info',
                    'User application attribute saved successfully.'
                );
            } else {
                $this->get('session')->getFlashBag()->add(
                    'error',
                    'Error while saving user application attribute value.'
                );
            }

            return $this->redirect($this->generateUrl('_admin_backend_webservice_user_application_attribute_edit',
                array('userApplicationAttributeId' => $userApplicationAttributeId)));
        }

        return $this->render('SsoBackendBundle:WsUserApplicationAttribute:edit.html.twig', array(
            'entity' => $entity,
            'htmlUid' => uniqid('i'),
            'edit_form' => $editForm->createView(),
        ));
    }

    /**
     * @return \Sso\WebserviceBundle\Database\Webservice\UserApplicationAttribute Database handler for attribute model
     */
    private function attributeHandler()
    {
        return $this->databaseManager()->webservice()->userApplicationAttribute();
    }
}
