<?php

class Waindigo_LoginAsUser_ControllerPublic_LoginAsUser extends XenForo_ControllerPublic_Abstract
{

    /**
     * Logs in as user.
     *
     * @return XenForo_ControllerResponse_Abstract
     */
    public function actionIndex()
    {
        $this->_checkCsrfFromToken($this->_input->filterSingle('_xfToken', XenForo_Input::STRING));

        /* @var $userModel XenForo_Model_User */
        $userModel = XenForo_Model::create('XenForo_Model_User');

        $input = $this->_input->filter(
            array(
                'user_id' => XenForo_Input::UINT,
                'username' => XenForo_Input::STRING,
                'logout' => XenForo_Input::STRING,
                'reason' => XenForo_Input::STRING
            ));

        $parentVisitor = Waindigo_LoginAsUser_Extend_XenForo_Visitor::getParentInstance()->toArray();

        if ($input['logout'] || $input['username'] == $parentVisitor['username'] ||
             $input['user_id'] == $parentVisitor['user_id']) {
            $user = $parentVisitor;
        } elseif ($input['username']) {
            $user = $userModel->getUserByName($input['username']);
        } elseif ($input['user_id']) {
            $user = $userModel->getUserById($input['user_id']);
        } else {
            $user = array(
                'user_id' => ''
            );
        }

        if (!$user) {
            return $this->responseError(new XenForo_Phrase('requested_user_not_found'), 404);
        }
        $userId = $user['user_id'];

        if (XenForo_Application::isRegistered('session')) {
            /* @var $session XenForo_Session */
            $session = XenForo_Application::get('session');
            if (!$session->isRegistered('loggedInAs') || $session->get('loggedInAs') != $userId) {
                if ($parentVisitor['user_id'] != $userId) {
                    $errorPhraseKey = '';
                    if (($userModel->canLoginAsUser($user, $errorPhraseKey, $parentVisitor) && $input['reason']) ||
                         $userModel->canLoginAsUserWithoutReason($user, $errorPhraseKey, $parentVisitor)) {
                        if ($input['reason']) {
                            $visitor = XenForo_Visitor::getInstance();
                            $conversation = array(
                                'title' => new XenForo_Phrase('waindigo_your_account_has_been_accessed_loginasuser')
                            );
                            $message = new XenForo_Phrase('waindigo_conversation_message_loginasuser',
                                array(
                                    'to' => $user['username'],
                                    'from' => $visitor['username'],
                                    'reason' => $input['reason']
                                ));
                            $recipients = array($user['username']);
                            $this->_getLoginAsUserModel()->startConversation($conversation, $message,
                                $recipients, $visitor);
                        }
                        $session->regenerate(true);
                        if (XenForo_Application::get('options')->waindigo_loginAsUser_logOutFirst) {
                            $session->changeUserId($userId);
                            if (XenForo_Helper_Cookie::getCookie('user')) {
                                $userModel->setUserRememberCookie($userId);
                            }
                        } else {
                            $session->set('loggedInAs', $userId);
                            $session->set('password_date', '');
                        }
                        $session->save();
                    } elseif ($errorPhraseKey) {
                        return $this->responseError(new XenForo_Phrase($errorPhraseKey));
                    } else {
                        return $this->responseNoPermission();
                    }
                } elseif ($session->isRegistered('loggedInAs')) {
                    $session->regenerate(true);
                    $session->remove('loggedInAs');
                    $session->save();
                }
            }
        }

        if ($parentVisitor['user_id'] == $user['user_id']) {
            return $this->responseRedirect(XenForo_ControllerResponse_Redirect::SUCCESS,
                $this->getDynamicRedirect(XenForo_Link::buildPublicLink('index')),
                new XenForo_Phrase('waindigo_log_out_successful_loginasuser'));
        } else {
            return $this->responseRedirect(XenForo_ControllerResponse_Redirect::SUCCESS,
                $this->getDynamicRedirect(XenForo_Link::buildPublicLink('index')),
                new XenForo_Phrase('waindigo_login_successful_loginasuser'));
        }
    } /* END actionIndex */

    /**
     *
     * @return XenForo_ControllerResponse_View
     */
    public function actionChoice()
    {
        /* @var $userModel XenForo_Model_User */
        $userModel = XenForo_Model::create('XenForo_Model_User');

        $users = array();

        $xenOptions = XenForo_Application::get('options');

        $parentVisitor = Waindigo_LoginAsUser_Extend_XenForo_Visitor::getParentInstance()->toArray();

        $errorPhraseKey = '';
        if ($userModel->canLoginAsUsers($errorPhraseKey, $parentVisitor)) {
            if (!$xenOptions->waindigo_loginAsUser_useComboBox) {
                $users = $userModel->getLoginAsUsers(array(), $parentVisitor);
            }
            if (XenForo_Visitor::getUserId()) {
                $canLoginAsGuest = $userModel->canLoginAsUser(array(), $errorPhraseKey, $parentVisitor);
            } else {
                $canLoginAsGuest = false;
            }
        } elseif ($errorPhraseKey) {
            return $this->responseError(new XenForo_Phrase($errorPhraseKey));
        } else {
            return $this->responseNoPermission();
        }

        $viewParams = array(
            'redirect' => $this->getDynamicRedirect(),
            'useAutoCombo' => Waindigo_Listener_ControllerPreDispatch::isAddOnEnabled('Waindigo_AutoCombo',
                'load_class_controller'),
            'users' => $users,
            'canLoginAsGuest' => $canLoginAsGuest,
            'parentVisitor' => $parentVisitor
        );

        return $this->responseView('Waindigo_LoginAsUser_View_LoginAsUser_Choice', 'waindigo_login_as_user_loginasuser',
            $viewParams);
    } /* END actionChoice */

    public function actionFindAutoCombo()
    {
        $q = $this->_input->filterSingle('q', XenForo_Input::STRING);

        $parentVisitor = Waindigo_LoginAsUser_Extend_XenForo_Visitor::getParentInstance()->toArray();

        $errorPhraseKey = '';

        $users = array();
        if ($this->_getUserModel()->canLoginAsUsers($errorPhraseKey, $parentVisitor)) {
            $conditions = array();
            if ($q) {
                $conditions['username'] = array(
                    $q,
                    'r'
                );
            }
            $users = $this->_getUserModel()->getLoginAsUsers($conditions, $parentVisitor);
        }

        $viewParams = array(
            'users' => $users
        );

        return $this->responseView('XenForo_ViewPublic_Member_Find', 'member_autocomplete', $viewParams);
    } /* END actionFindAutoCombo */

    public function actionFind()
    {
        $q = $this->_input->filterSingle('q', XenForo_Input::STRING);

        $parentVisitor = Waindigo_LoginAsUser_Extend_XenForo_Visitor::getParentInstance()->toArray();

        $errorPhraseKey = '';

        $users = array();
        if ($this->_getUserModel()->canLoginAsUsers($errorPhraseKey, $parentVisitor)) {
            if ($q !== '' && utf8_strlen($q) >= 2) {
                $conditions = array(
                    'username' => array(
                        $q,
                        'r'
                    )
                );
                $users = $this->_getUserModel()->getLoginAsUsers($conditions, $parentVisitor);
            }
        }

        $viewParams = array(
            'users' => $users
        );

        return $this->responseView('XenForo_ViewPublic_Member_Find', 'member_autocomplete', $viewParams);
    } /* END actionFind */

    /**
     * Enforce registered-users only for all actions in this controller
     *
     * @see library/XenForo/XenForo_Controller#_preDispatch($action)
     */
    protected function _preDispatch($action)
    {
        $parentVisitor = Waindigo_LoginAsUser_Extend_XenForo_Visitor::getParentInstance()->toArray();

        if (!$parentVisitor['user_id']) {
            $this->_assertRegistrationRequired();
        }
    } /* END _preDispatch */

    protected function _assertViewingPermissions($action)
    {
        // do nothing
    } /* END _assertViewingPermissions */

    protected function _assertNotBanned()
    {
        // do nothing
    } /* END _assertNotBanned */

    protected function _assertBoardActive($action)
    {
        // do nothing
    } /* END _assertBoardActive */

    /**
     *
     * @return Waindigo_LoginAsUser_Model_LoginAsUser
     */
    protected function _getLoginAsUserModel()
    {
        return $this->getModelFromCache('Waindigo_LoginAsUser_Model_LoginAsUser');
    } /* END _getLoginAsUserModel */

    /**
     *
     * @return XenForo_Model_User
     */
    protected function _getUserModel()
    {
        return $this->getModelFromCache('XenForo_Model_User');
    } /* END _getUserModel */
}