<?php

/**
  model class name  = MODEL_NAME
  form-id  == my-phones
 */
class DefaultController extends Controller
{

    const LOGIN_LOGOUT_TYPE_QUEUE = 'queue';
    const LOGIN_LOGOUT_TYPE_CALLGROUP = 'callgroup';

    /**
     * @var string the default layout for the views. Defaults to '//layouts/column2', meaning
     * using two-column layout. See 'protected/views/layouts/column2.php'.
     */
    public $layout = '//layouts/column2';

    /**
     * @return array action filters
     */
    public function filters()
    {
        return array(
            'accessControl', // perform access control for CRUD operations
        );
    }

    /**
     * Specifies the access control rules.
     * This method is used by the 'accessControl' filter.
     * @return array access control rules
     */
    public function accessRules()
    {
        return array(
            array('allow', // allow all users to perform 'index' and 'view' actions
                'actions' => array('index', 'authenticate', 'toggleQueueStatus'),
                'expression' => AccessManager::checkSessionPermission($this->module->name),
            ),
            array('allow', // allow authenticated user to perform 'create' and 'update' actions
                'actions' => array('create', 'update', 'requestTempToken', 'viewQRCode'),
                'expression' => AccessManager::checkSessionPermission($this->module->name),
            ),
            array('allow', // allow admin user to perform 'admin' and 'delete' actions
                'actions' => array('delete', 'deleteAuthenticDevice'),
                'expression' => AccessManager::checkSessionPermission($this->module->name),
            ),
            array('deny', // deny all users
                'users' => array('*'),
            ),
        );
    }

    public function actionToggleQueueStatus()
    {
        $id = $_REQUEST['id'];

        if (isset($_REQUEST['type']) && $_REQUEST['type'] == self::LOGIN_LOGOUT_TYPE_CALLGROUP) {
            $tier = UserToCallGroup::model()->findByPk($id);
        } else {
            $tier = Tiers::model()->findByPk($id);
        }

        if ($tier) {
            if (!$tier->static_member) {
                if ($tier->loggedIn == '0' || $tier->loggedIn == null) {
                    $tier->loggedIn = 1;
                } else {
                    $tier->loggedIn = 0;
                }
                $tier->save();
            }
        }
    }

    public function actionAuthenticate()
    {
        header('Content-type: application/json');
        if ($_POST['status'] == 'loggedIn') {
            $this->loggout($_POST['id']);
            echo json_encode(array('loggedOut' => true, 'label' => __('PHONESETTINGS_MY_PHONES_LOGIN_BUTTON')));
        } else {
            $this->loggin($_POST['id']);
            echo json_encode(array('loggedOut' => false, 'label' => __('PHONESETTINGS_MY_PHONES_LOGOUT_BUTTON')));
        }
        Yii::app()->end();
    }

    public function loggout($id)
    {
        $phone = Phones::model()->findByPk($id);
        $phone->loggout();
    }

    public function loggin($id)
    {
        $phone = Phones::model()->findByPk($id);
        $phone->loggin();
    }

    protected function getPhonesDataProvider($user)
    {
        $array = array();
        $sips = $user->getSipAccounts();
        $index = 0;
        $phones = array();
        foreach ($sips as $sip) {
            $phones[$sip->id]['loggedIn'] = $sip->getPhones();
            $phones[$sip->id]['loggedOut'] = $sip->getLastPhones();
        }

        foreach ($phones as $sipId => $phonesOfSipId) {
            if ($phonesOfSipId['loggedIn']) {
                foreach ($phonesOfSipId['loggedIn'] as $phone) {

                    $array[] = array(
                        'id' => $index,
                        'status' => 'loggedIn',
                        'phoneId' => $phone->id,
                        'sipId' => $sipId,
                        'descr' => $phone->descr,
                        'phone' => $phone->getPhoneModelNameHumanReadable(),
                    );
                    $index++;
                }
            }
            if (isset($phonesOfSipId['loggedOut'])) {
                foreach ($phonesOfSipId['loggedOut'] as $phone) {

                    $array[] = array(
                        'id' => $index,
                        'phoneId' => $phone->id,
                        'status' => 'loggedOut',
                        'sipId' => $sipId,
                        'descr' => $phone->descr,
                        'phone' => $phone->getPhoneModelNameHumanReadable(),
                    );
                    $index++;
                }
            }
        }
        return $this->getDataProvider($array);
    }

    public function renderLogButton($data, $row, $column)
    {
        $this->renderPartial('loggInLogoutButton', array('data' => $data, 'row' => $row, 'column' => $column));
    }

    /**
     * Lists all models.
     */
    public function actionIndex()
    {
        $user = app()->user->sudoUserInstance;
        if (!$user) {
            app()->user->logout();
            app()->user->loginRequired();
        }
        $this->checkIfAuthenticDeviceTimeIsOver($user->id);
        $phonesCurrentDataProvider = $this->getPhonesDataProvider($user);
        $authenticateDevice = $this->getDataProviderByPk("AuthenticDevice", $user->id);

        $this->render('index', array(
            'phonesCurrentDataProvider' => $phonesCurrentDataProvider,
            'authenticateDevice' => $authenticateDevice,
            'userID' => $user->id,
        ));
    }

    public function getQueueDataProvider($user)
    {
        $queues = array();
        $tiers = Tiers::model()->findAllByAttributes(array('userId' => $user->id));

        $index = 0;
        foreach ($tiers as $index => $tier) {
            $queues[] = $this->getQueueData($tier, $index);
            $index++;
        }
        return $this->getDataProvider($queues, 'name');
    }

    public function getQueueData($tier, $index)
    {
        $queue = Queue::model()->findByPk($tier->queueId);
        $data = array();
        $data['id'] = $index;
        $data['tierId'] = $tier->id;
        $data['loggedIn'] = $tier->loggedIn;
        $data['static_member'] = $tier->static_member;

        if ($queue == null) {
            return $data;
        }
        $data['queueId'] = $queue->id;
        $data['name'] = $this->changeNameFormatToNameWithExtension($queue->name, $queue->extension);
        return $data;
    }

    protected function changeNameFormatToNameWithExtension($name, $extension = '')
    {
        if (!empty($extension)) {
            $name = "<$extension> $name";
        }
        return $name;
    }

    protected function getUserGroupDataProvider($groupID)
    {
        $group = Groups::model()->findByPk($groupID);
        if ($group) {
            $group->name = $this->changeNameFormatToNameWithExtension($group->name, $group->extension);
        }
        return $this->getDataProvider($group);
    }

    protected function getCallGroupDataProvider($userID)
    {
        $userToCallGroups = UserToCallGroup::model()->findAllByAttributes(array('userId' => $userID));
        $data = array();
        foreach ($userToCallGroups as $userToCallGroup) {
            $model = CallGroup::model()->findByPk($userToCallGroup->callGroupId);
            $model->name = $this->changeNameFormatToNameWithExtension($model->name, $model->extension);
            $data[] = $model;
        }
        return $this->getDataProvider($data, 'name');
    }

    protected function getParallelCallDataProvider($userID)
    {
        $externalNumber = ExternalNumber::model()->findAllByAttributes(array('userId' => $userID, 'useParallelCall' => '1'));
        return $this->getDataProvider($externalNumber, 'pattern');
    }

    protected function getSecretaryDataProvider($userID)
    {
        $models = Secretary::model()->getSecretarys($userID);
        return $this->getSecretaryBossDataProvider($models);
    }

    protected function getBossDataProvider($userID)
    {
        $models = Secretary::model()->findAllByAttributes(array('secretaryId' => $userID));
        $data = array();
        foreach ($models as $model) {
            $data[] = User::model()->findByPk($model->bossId);
        }
        return $this->getSecretaryBossDataProvider($data);
    }

    protected function getSecretaryBossDataProvider($models)
    {
        $data = array();
        foreach ($models as $model) {
            if (isset($model->name)) {
                $model->name = getFormatedUsername($model);
            }
            $data[] = $model;
        }
        return $this->getDataProvider($data, 'name');
    }

    protected function getDNDStatus($user)
    {
        return $this->getDataProvider($user);
    }

    protected function getDataProviderByPk($modelName, $id, $order = "id")
    {
        $model = $modelName::model()->findByPk($id);
        return $this->getDataProvider($model, $order);
    }

    protected function getDataProvider($data, $order = 'id')
    {
        if (!$data) {
            $data = array();
        }
        if (!is_array($data)) {
            $data = array($data);
        }

        $sort = new CSort();
        $sort->defaultOrder = "$order ASC";
        $filter = array(
            'sort' => $sort,
            'pagination' => false
        );
        return new CArrayDataProvider($data, $filter);
    }

    public function actionRequestTempToken()
    {
        if ($_REQUEST['userID']) {
            $model = new AuthenticDevice();
            $this->performAjaxValidation($model);
            $model->tempToken = sha1(PasswordGenerator::generateToken());
            $model->added = PhonalisaDate::newServerDate();
            $model->userid = $_REQUEST['userID'];

            $content = array(
// FIXME API URL not longer exists
//                'eh' => cfg('API_URL_EXTERN'),
//                'ih' => cfg('API_URL_INTERN'),
                't' => $model->tempToken
            );
            if ($model->save()) {
                $this->renderPartial('_viewQRCode', array(
                    'model' => $model,
                    'content' => $content
                        ), false, true);
            }
        }
    }

    public function checkIfAuthenticDeviceTimeIsOver($userID)
    {
        $devices = AuthenticDevice::model()->findAllByAttributes(array('userid' => $userID, 'accessToken' => ''));
        if ($devices) {
            $currentNewServerDate = PhonalisaDate::newServerDate();
            $currentDateTime = strtotime($currentNewServerDate);

            foreach ($devices as $device) {
                $addedTime = strtotime($device->added);
                if ($currentDateTime - $addedTime > 60 * 5) {
                    $this->actionDeleteAuthenticDevice($device->id);
                }
            }
        }
    }

    public function actionViewQRCode($id)
    {
        $model = AuthenticDevice::model()->findByPk($id);
        $content = array(
            // FIXME API URL not longer exists
            // 'eh' => cfg('API_URL_EXTERN'),
            // 'ih' => cfg('API_URL_INTERN'),
            't' => $model->tempToken
        );
        $this->renderPartial('_viewQRCode', array('model' => $model, 'content' => $content), false, true);
    }

    public function actionDeleteAuthenticDevice($id)
    {
        $model = AuthenticDevice::model()->findByPk($id);
        if ($model) {
            $model->delete();
        }
    }

    /**
     * Returns the data model based on the primary key given in the GET variable.
     * If the data model is not found, an HTTP exception will be raised.
     * @param integer the ID of the model to be loaded
     */
    public function loadModel($id)
    {
        $model = MODEL_NAME::model()->findByPk($id);
        if ($model === null) {
            throw new CHttpException(404, 'The requested page does not exist.');
        }
        return $model;
    }

    /**
     * Performs the AJAX validation.
     * @param CModel the model to be validated
     */
    protected function performAjaxValidation($model)
    {
        if (isset($_POST['ajax']) && $_POST['ajax'] === 'my-phones-form') {
            echo CActiveForm::validate($model);
            Yii::app()->end();
        }
    }

    public function renderQueueStatus($data, $row, $column)
    {
        $data['type'] = self::LOGIN_LOGOUT_TYPE_QUEUE;
        $this->renderPartial('queueLoginLogout', array('data' => $data, 'row' => $row, 'column' => $column));
    }

    public function renderCallGroupStatus($data, $row, $column)
    {
        $attributes = array(
            'userId' => app()->user->sudoUserInstance->id,
            'callGroupId' => $data->id
        );
        $userToCallGroupModel = UserToCallGroup::model()->findByAttributes($attributes);

        if ($userToCallGroupModel) {
            $static_member = '1';
            if (isset($userToCallGroupModel->static_member) && $userToCallGroupModel->static_member !== '') {
                $static_member = $userToCallGroupModel->static_member;
            }
            $dataArray = array(
                'id' => $row,
                'tierId' => $userToCallGroupModel->id,
                'loggedIn' => $userToCallGroupModel->loggedIn,
                'static_member' => $static_member,
                'queueId' => $data->id,
                'name' => $data->name,
                'type' => self::LOGIN_LOGOUT_TYPE_CALLGROUP
            );
            $this->renderPartial('queueLoginLogout', array('data' => $dataArray, 'row' => $row, 'column' => $column));
        }
    }

    public function renderMobilePhoneSwitcher($phonesCurrentDataProvider)
    {
        $title = __('PHONESETTINGSMYPHONES_HEADER_TITLE');
        $showTitle = true;
        $disabled = '';

        foreach ($phonesCurrentDataProvider->data as $key => $phone) {
            $logInStatus = '';
            if ($phone['status'] === 'loggedIn') {
                $logInStatus = "checked='checked'";
            }
            $this->renderPartial('mobile_switcher', array(
                'id' => $phone['phoneId'],
                'wsAction' => $phone['status'] === 'loggedIn' ? "logoutPhone" : "loginPhone",
                'title' => $title,
                'label' => $phone['phone'],
                'showTitle' => $showTitle,
                'logInStatus' => $logInStatus,
                'disabled' => $disabled
            ));
            $showTitle = false;
        }
    }

    public function renderMobileQueueSwitcher($queueDataProvider)
    {
        $title = __('MYPHONES_INDEX_QUEUE_NAME');
        $showTitle = true;

        foreach ($queueDataProvider->data as $queue) {
            $logInStatus = '';
            $disabled = '';

            if ($queue['loggedIn'] === '1') {
                $logInStatus = "checked='checked'";
            }
            if ($queue['static_member'] === '1') {
                $logInStatus = "checked='checked'";
                $disabled = "disabled='disabled'";
            }

            $this->renderPartial('mobile_switcher', array(
                'id' => $queue["tierId"],
                'wsAction' => $queue["loggedIn"] == true ? "logoutQueue" : "loginQueue",
                'title' => $title,
                'label' => $queue['name'],
                'showTitle' => $showTitle,
                'logInStatus' => $logInStatus,
                'disabled' => $disabled
            ));
            $showTitle = false;
        }
    }

    public function renderMobileCallForwardList()
    {
        $title = __('PHONESETTINGSCALLFORWARDS_PRESETLIST_HEADER_TITLE');
        $realUserInstance = app()->user->realUserInstance;
        $callForwardSets = $realUserInstance->getForwardingSets();
        $activatedForward = $realUserInstance->callForwardSet;
        $showTitle = true;
        $closeFieldset = false;
        $countCallForwardSets = count($callForwardSets);

        foreach ($callForwardSets as $key => $callForward) {
            $checked = '';
            if ($callForward['id'] === $activatedForward) {
                $checked = "checked='checked'";
            }
            if ($countCallForwardSets === 0 || $countCallForwardSets === $key - 1) {
                $closeFieldset = true;
            }
            $this->renderPartial('mobile_radioList', array(
                'title' => $title,
                'id' => $callForward->id,
                'label' => $callForward['name'],
                'showTitle' => $showTitle,
                'checked' => $checked,
                'closeFieldset' => $closeFieldset
                    )
            );
            $showTitle = false;
        }
    }

    public function renderLanguageSelect()
    {
        $title = __('DEFAULT_LANGUAGE');
        $id = 1;
        $languages = Sysconfig::model()->getLanguageArray();

        $selectedLanguage = Yii::app()->user->getState('language');
        if ($selectedLanguage === '') {
            $selectedLanguage = 'Default Language';
        }
        $showTitle = true;
        $closeFieldset = false;
        $count = 1;

        foreach ($languages as $key => $option) {
            $selected = '';
            if (count($languages) === $count) {
                $closeFieldset = true;
            }
            if ($selectedLanguage === $key) {
                $selected = "selected='selected'";
            }
            $this->renderPartial('mobile_selectList', array(
                'title' => $title,
                'value' => $key,
                'option' => $option,
                'showTitle' => $showTitle,
                'selected' => $selected,
                'closeFieldset' => $closeFieldset
                    )
            );
            $count++;
            $showTitle = false;
        }
    }

    public function renderDNDText()
    {
        return __('PHONESETTINGS_USER_MODEL_DND_SHORT');
    }

    public function renderDNDStatus($data)
    {
        $dndStatus = __('MY_PHONES_HUMAN_READABLE_DND_STATUS_OFF');
        if ($data->dnd == '1') {
            $dndStatus = __('MY_PHONES_HUMAN_READABLE_DND_STATUS_ON');
        }
        return $dndStatus;
    }

    public function renderStatusGrids($userID)
    {
        $user = User::model()->findByPk($userID);
        $group = Groups::model()->findByPk($user->group);

        $dndStatus = $this->getDNDStatus($user);
        $groupDataProvider = $this->getUserGroupDataProvider($user->group);
        $queueDataProvider = $this->getQueueDataProvider($user);
        $callGroupDataProvider = $this->getCallGroupDataProvider($user->id);
        $parallelCallDataProvider = $this->getParallelCallDataProvider($user->id);
        $hasSecretaryDataprovider = $this->getSecretaryDataProvider($user->id);
        $hasBossDataProvider = $this->getBossDataProvider($user->id);

        $callForwardDataProvider = $this->getDataProviderByPk("ForwardPreset", $user->callForwardSet, "id");
        $keyProfileUserDataProvider = $this->getDataProviderByPk("ProvisioningKeyProfile", $user->keyProfile, "id");
        $keyProfileGroupDataProvider = $this->getDataProviderByPk("ProvisioningKeyProfile", $group->keyProfile, "id");
        $parameterProfileUserDataProvider = $this->getDataProviderByPk("ProvisioningProfile", $user->provisioningProfile, "id");
        $parameterProfileGroupDataProvider = $this->getDataProviderByPk("ProvisioningProfile", $group->provisioningProfile, "id");

        $allDataProviders = array();
        $allDataProviders['_dndStatus'] = $this->addToDataProviderArray($dndStatus, 'name', '', 'left', $groupDataProvider->totalItemCount);
        $allDataProviders['group'] = $this->addToDataProviderArray($groupDataProvider, 'name', '', 'right', $dndStatus->totalItemCount);
        $allDataProviders['call_forward'] = $this->addToDataProviderArray($callForwardDataProvider, 'name', 'description');
        $allDataProviders['_queueGrid'] = $this->addToDataProviderArray($queueDataProvider);
        $allDataProviders['_callgroupGrid'] = $this->addToDataProviderArray($callGroupDataProvider, 'name', 'description');
        $allDataProviders['parallelcall'] = $this->addToDataProviderArray($parallelCallDataProvider, 'pattern');
        $allDataProviders['has_secretary'] = $this->addToDataProviderArray($hasSecretaryDataprovider, 'name', '', 'left', $hasBossDataProvider->totalItemCount);
        $allDataProviders['has_boss'] = $this->addToDataProviderArray($hasBossDataProvider, 'name', '', 'right', $hasSecretaryDataprovider->totalItemCount);
        $allDataProviders['key_profile_user'] = $this->addToDataProviderArray($keyProfileUserDataProvider, 'name', 'descr', 'left', $keyProfileGroupDataProvider->totalItemCount);
        $allDataProviders['key_profile_group'] = $this->addToDataProviderArray($keyProfileGroupDataProvider, 'name', 'descr', 'right', $keyProfileUserDataProvider->totalItemCount);
        $allDataProviders['parameter_profile_user'] = $this->addToDataProviderArray($parameterProfileUserDataProvider, 'name', 'descr', 'left', $parameterProfileGroupDataProvider->totalItemCount);
        $allDataProviders['parameter_profile_group'] = $this->addToDataProviderArray($parameterProfileGroupDataProvider, 'name', 'descr', 'right', $parameterProfileUserDataProvider->totalItemCount);

        return $this->renderInfoGrid($allDataProviders);
    }

    protected function addToDataProviderArray($dataProvider, $name = '', $descr = '', $position = '', $dependItemCount = '')
    {
        return array(
            'dataProvider' => $dataProvider,
            'name' => $name,
            'descr' => $descr,
            'position' => $position,
            'dependItemCount' => $dependItemCount,
            'totalItemCount' => $dataProvider->totalItemCount
        );
    }

    protected function renderInfoGrid($allDataProviders)
    {
        foreach ($allDataProviders as $key => $value) {
            $position = $value['position'];
            if ($value['dependItemCount'] === 0) {
                $position = '';
            }
            if ($value['totalItemCount'] > 0) {
                $this->renderInfoGridPartial($value['dataProvider'], $key, $value['name'], $position, $value['descr']);
            }
        }
    }

    protected function renderInfoGridPartial($dataProvider, $gridName, $name, $position, $descr)
    {
        $viewFile = '_nameInfoGrid';
        if ($descr != '') {
            $viewFile = '_nameAndDescrInfoGrid';
        }

        if (substr($gridName, 0, 1) == '_') {
            $viewFile = $gridName;
        }

        $this->renderPartial($viewFile, array(
            'dataProvider' => $dataProvider,
            'gridName' => $gridName,
            'name' => $name,
            'descr' => $descr,
            'position' => strtolower($position) . 'Grid'
                )
        );
    }
}
