<?php

class DefaultController extends Controller
{

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

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

    /**
     * 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', 'configurationTree', 'tooltipText'),
                //'users'=>array('@')
                'expression' => AccessManager::checkSessionPermission($this->module->id),
            ),
            array('deny', // deny all users
                'users' => array('*'),
            ),
        );
    }

    /**
     * Lists all models.
     */
    public function actionIndex()
    {
        $items[] = array(
            'class' => 'bootstrap.widgets.TbMenu',
            'encodeLabel' => false,
            'items' => TreeMapHelper::getItemsForKeyMap(),
            'htmlOptions' => array('class' => 'treeNavbar')
        );
        $this->render('index', array('items' => $items));
    }

    public function actionConfigurationTree()
    {
        $this->getTreeData();
    }

    protected function getTreeData()
    {
        $modelDataArray = $this->processTreeData();
//        dump($modelDataArray);
//        dump($this->getGraphicalTreeData($modelDataArray));
        echo json_encode($this->getGraphicalTreeData($modelDataArray));
    }
    /*
     * static stuff start
     */

    protected function processTreeData()
    {
        $gateways = $this->processGateways();
        $result = array();
        foreach ($gateways as $key => $value) {
            $result[$key]['keyID'] = $value->id;
            $result[$key]['keyColor'] = TreeMapHelper::setColorForTreeDataType($value);
            $result[$key]['name'] = $value->name;
            $result[$key]['children'] = $this->processRoutingInbound($value->id);
        }
        return $result;
    }

    protected function processGateways()
    {
        return ConfigurationOverview::getModelDataFromGateways();
    }

    protected function processRoutingInbound($parentId)
    {
        $models = RoutingInbound::model()->findAllByAttributes(array('gw_id' => $parentId));
        $result = array();
        foreach ($models as $model) {
            if ($model->active == '1') {
                $patternName = $model->pattern;
                $children = $this->processRoutingInboundFirstLevelTargets($model);

                $result[$patternName]['keyID'] = $model->id;
                $result[$patternName]['keyColor'] = TreeMapHelper::setColorForTreeDataType(__('ROUTING_INBOUND_MODEL_PATTERN'));
                $result[$patternName]['name'] = __('ROUTING_INBOUND_MODEL_PATTERN') . ': ' . $patternName;
                $result[$patternName]['children'][] = $children;
            }
        }
        sort($result);
        return $result;
    }

    protected function processRoutingInboundFirstLevelTargets($model)
    {
        $targetType = $model->targetType;
        $type = TargetHelper::getTranslationForTargetType($targetType);
        $children = false;

        if ($targetType == TargetType::Manual) {
            $children = $this->processManualTarget($model);
        } else if ($targetType == TargetType::UserFax || $targetType == TargetType::CallThrough) {
            $name = "<$model->targetExtension> " . TargetHelper::getTranslationForTargetType($targetType);
            $children = $this->processChildren($model->id, $type, $name, false, false);
        } else if ($targetType == TargetType::Conference) {
            $children = $this->processConferenceRoom($model);
        } else {
            $targetModel = TargetHelper::getModelForTargetType($model->targetType);
            $currentTargetModel = $targetModel->findByPk($model->target);
            $children = $this->processRoutingInBoundTargets($targetType, $currentTargetModel);
        }
        return $children;
    }

    protected function processConferenceRoom($model)
    {
        $conferenceModel = TargetHelper::getModelForTargetType(TargetType::Conference);
        $isConferenceModel = get_class($conferenceModel);
        $modelName = get_class($model);

        if ($modelName == $isConferenceModel) {
            $target = $model->id;
            $name = "<$model->extension> " . $model->name;
            $targetType = TargetType::Conference;
        } else {
            $target = $model->target;
            $name = "<$model->pattern> " . $model->targetExtension;
            $targetType = $model->targetType;
        }

        $type = TargetHelper::getTranslationForTargetType($targetType);
        $children = false;
        $moderators = ConferenceModerator::model()->findAllByAttributes(array('conferenceId' => $target));

        foreach ($moderators as $moderator) {
            if ($moderator->moderatorCall == '1') {
                $userModel = User::model()->findByPk($moderator->userId);
                $children[] = $this->processRoutingInBoundTargets(TargetType::User, $userModel);
            }
        }
        return $this->processChildren($model->id, $type, $name, $children, false);
    }

    protected function processManualTarget($model)
    {
        $targetType = $model->targetType;
        $type = TargetHelper::getTranslationForTargetType($targetType);
        $name = $type . ": $model->target";

        $targetModel = TreeMapHelper::getModelFromTarget($model->target);

        if ($targetModel) {
            $targetModelType = TreeMapHelper::getTargetTypeForModel($targetModel);
            $children = $this->processRoutingInBoundTargets($targetModelType, $targetModel);
        } else {
            $children = $this->processChildren($model->id, $type, $name, false, false);
        }
        return $children;
    }
    /*
     * static stuff ends
     */

    protected function processChildren($id, $type, $name, $children = array(), $childNeedArray = true, $key = null)
    {
        $color = TreeMapHelper::setColorForTreeDataType($type);

        $result = array();
        if (isset($key)) {
            $result[$key]['keyID'] = $id;
            $result[$key]['keyColor'] = $color;
            $result[$key]['name'] = $name;
            $result[$key]['children'][] = $children;
        } else {
            $result['keyID'] = $id;
            $result['keyColor'] = $color;
            $result['name'] = $name;
            if (!$childNeedArray) {
                $result['children'] = $children;
            } else {
                $result['children'][] = $children;
            }
        }
        return $result;
    }

    protected function processRoutingInBoundTargets($targetType, $currentTargetModel, $childNeedArray = false)
    {
        $name = TargetHelper::getTitleForModelAndTargetType($currentTargetModel, $targetType);
        $children = false;
        $id = $currentTargetModel->id;

        if ($targetType == TargetType::User) {
            if (!empty($currentTargetModel->callForwardSet)) {
                $children = $this->processCallForwarding($currentTargetModel);
                if ($children) {
                    $childNeedArray = true;
                }
            }
        }
        if ($targetType == TargetType::Group) {
            $children = $this->processGroups($id);
        }
        if ($targetType == TargetType::Queue) {
            $children = $this->processQueues('Tiers', array('queueId' => $id));
        }
        if ($targetType == TargetType::CallGroup) {
            $children = $this->processQueues('UserToCallGroup', array('callGroupId' => $id));
        }
        if ($targetType == TargetType::Conference) {
            return $this->processConferenceRoom($currentTargetModel);
        }
        if ($targetType == TargetType::Ivr) {
            $children = $this->processIVRs($currentTargetModel);
        }
        return $this->processChildren($id, $currentTargetModel, $name, $children, $childNeedArray);
    }

    protected function processCallForwarding($currentTargetModel)
    {
        $result = array();
        if (!empty($currentTargetModel->callForwardSet)) {
            $pk = $currentTargetModel->callForwardSet;
            $model = ForwardPreset::model()->findByPk($pk);
            if ($model) {
                $id = $model->id;
                $hasLoopWith = TreeMapHelper::checkForForwardLoops($model);

                if (!$hasLoopWith) {
                    $result = $this->processChildren($id, $model, $model->name, $this->processForwardPresent($model->configs));
                } else {
                    $targetModel = TreeMapHelper::getModelFromTarget($hasLoopWith);
                    $targetModelType = TreeMapHelper::getTargetTypeForModel($targetModel);
                    $loopTarget = TargetHelper::getTitleForModelAndTargetType($targetModel, $targetModelType);

                    $name = 'Fehler! Schleife mit: ' . $loopTarget;
                    $type = 'ERROR';
                    $result = $this->processChildren($id, $type, $name, false, false);
                }
            } else {
                return false;
            }
        }
        return $result;
    }

    protected function processForwardPresent($configs)
    {
        $forwardRules = TreeMapHelper::getDecodedForwardConfigs($configs);
        $result = array();
        foreach ($forwardRules as $forwardRule) {
            $target = $forwardRule->target;
            $targetType = $target->type;

            if ($targetType == 'number') {
                $targetModel = TreeMapHelper::getModelFromTarget($target->desc);
                $targetModelType = TreeMapHelper::getTargetTypeForModel($targetModel);
                $result = $this->processRoutingInBoundTargets($targetModelType, $targetModel);
            } else if ($targetType == 'voicemail') {
                $name = __('PHONESETTINGSCALLFORWARD_TARGET_VOICE_MAIL');
                $result = $this->processChildren($name, $targetType, $name, false, false);
            } else {
                $name = __('PHONESETTINGSCALLFORWARD_TARGET_ANNONCEMENT');
                $result = $this->processChildren($name, $targetType, $name, false, false);
            }
        }
        return $result;
    }

    protected function processGroups($id)
    {
        $children = array();
        $userModels = User::model()->findAllByAttributes(array('group' => $id));
        foreach ($userModels as $userModel) {
            $children[] = $this->processRoutingInBoundTargets(TargetType::User, $userModel);
        }
        return $children;
    }

    protected function processQueues($modelName, $searchArray)
    {
        $models = PhonalisaRecord::model($modelName)->findAllByAttributes($searchArray);
        $children = array();
        foreach ($models as $model) {
            if ($modelName == 'Tiers' && $model->type == TiersType::external) {
                $children[] = $this->processExternalAgents($model);
            } else {
                $userModel = User::model()->findByPk($model->userId);
                $children[] = $this->processRoutingInBoundTargets(TargetType::User, $userModel);
            }
        }
        return $children;
    }

    protected function processExternalAgents($model)
    {
        $externalAgent = ExternalAgent::model()->findByPk($model->userId);
        $name = "<$externalAgent->number> $externalAgent->name";
        $children = $this->processChildren($model->id, $model, $name, false, false);
        return $children;
    }

    protected function processIVRs($model)
    {
        $nonSelecteds = TreeMapHelper::getIvrSearchArray($model, KeyType::noneSelected);
        $hangUps = TreeMapHelper::getIvrSearchArray($model, KeyType::hangUp);
        $targetNumbers = TreeMapHelper::getIvrSearchArray($model, KeyType::targetNumber);
        $voiceMails = TreeMapHelper::getIvrSearchArray($model, KeyType::voiceMail);
        $retryAnnounces = TreeMapHelper::getIvrSearchArray($model, KeyType::retryAnnounce);
        $id = $model->id;

        if (!empty($nonSelecteds)) {
            foreach ($nonSelecteds as $key => $target) {
                $resultKey = TreeMapHelper::changeIvrNonNumericKeysToNumericString($key);
                $key = strtoupper($key);
                $type = __('ADMIN_CONFIGURATION_OVERVIEW_TREEMAP_TYPE_NONE_SELECTED');
                $name = __("IVR_MODEL_ACTION_KEY_$key");
                $children = $this->processChildren($id, $type, $type, false, false);
                $result[$resultKey] = $this->processChildren($id, $type, $name, $children);
            }
        }

        if (!empty($hangUps)) {
            foreach ($hangUps as $key => $target) {
                $resultKey = TreeMapHelper::changeIvrNonNumericKeysToNumericString($key);
                $key = strtoupper($key);
                $type = __('IVR_MODEL_TYPE_REPLACE');
                $name = __("IVR_MODEL_ACTION_KEY_$key");
                $children = $this->processChildren($id, $type, $type, false, false);
                $result[$resultKey] = $this->processChildren($id, $type, $name, $children);
            }
        }

        if (!empty($targetNumbers)) {
            foreach ($targetNumbers as $key => $targetNumber) {
                $targetModel = TreeMapHelper::getModelFromTarget($targetNumber);
                if (!$targetModel) {
                    $targetModel = TreeMapHelper::getModelFromTarget($targetNumber);
                }
                if ($targetModel) {
                    $targetModelType = TreeMapHelper::getTargetTypeForModel($targetModel);
                    $children = $this->processRoutingInBoundTargets($targetModelType, $targetModel);
                    $parent = $this->processChildren($id, $targetModel, __('IVR_MODEL_KEY_TYPE_TARGET_NUMBER'), $children);
                    $resultKey = TreeMapHelper::changeIvrNonNumericKeysToNumericString($key);
                    $key = strtoupper($key);
                    $result[$resultKey] = $this->processChildren($id, $targetModel, __("IVR_MODEL_ACTION_KEY_$key"), $parent);
                }
                if (!$targetModel) {
                    $resultKey = TreeMapHelper::changeIvrNonNumericKeysToNumericString($key);
                    $key = strtoupper($key);
                    $type = __('MANUAL');
                    $name = __("IVR_MODEL_ACTION_KEY_$key");
                    $children = $this->processChildren($id, $type, $type, false, false);
                    $result[$resultKey] = $this->processChildren($id, $type, $name, $children);
                }
            }
        }

        if (!empty($voiceMails)) {
            foreach ($voiceMails as $key => $voiceMail) {
                $targetModel = TreeMapHelper::getModelFromTarget($voiceMail);
                $translation = __('PHONESETTINGSCALLFORWARD_TARGET_VOICE_MAIL');
                $title = TargetHelper::getTitleForModelAndTargetType($targetModel, TargetType::UserVoiceMail);
                $name = $translation . ': ' . $title;
                $children = $this->processChildren($id, $targetModel, $name, false, false);
                $resultKey = TreeMapHelper::changeIvrNonNumericKeysToNumericString($key);
                $key = strtoupper($key);
                $result[$resultKey] = $this->processChildren($id, $translation, __("IVR_MODEL_ACTION_KEY_$key"), $children);
            }
        }

        if (!empty($retryAnnounces)) {
            foreach ($retryAnnounces as $key => $target) {
                $resultKey = TreeMapHelper::changeIvrNonNumericKeysToNumericString($key);
                $key = strtoupper($key);
                $type = __('PHONESETTINGSCALLFORWARD_TARGET_ANNONCEMENT');
                $name = __("IVR_MODEL_ACTION_KEY_$key");
                $children = $this->processChildren($id, $type, $type, false, false);
                $result[$resultKey] = $this->processChildren($id, $type, $name, $children);
            }
        }

        ksort($result);
        return $result;
    }

    protected function processIvrEndTarget($targets, $type)
    {
        $result = array();
        foreach ($targets as $key => $target) {
            $resultKey = TreeMapHelper::changeIvrNonNumericKeysToNumericString($key);
            $key = strtoupper($key);
            $name = __("IVR_MODEL_ACTION_KEY_$key");
            $children[] = $this->processChildren('', $type, $type, false, false);
            $result[$resultKey] = $this->processChildren('', $type, $name, array($children), false);
        }
        return $result;
    }

    public function actionTooltipText()
    {
        if (isset($_REQUEST['keyID']) && !empty($_REQUEST['keyID'])) {
            return $this->getToolTipText($_REQUEST['keyID']);
        }
        echo __('STATISTIC_NO_DATA');
    }

    protected function getToolTipText($keyID)
    {
        $model = TreeMapHelper::getModelFromTarget($keyID);
        if ($model) {
            $modelName = get_class($model);
            $modelKeyArray = TreeMapHelper::getModelKeyArrayForToolTipText($modelName);

            echo "<table border='1px solid black;'>";
            foreach ($modelKeyArray as $value) {
                if (property_exists($modelName, $value)) {
                    $modelValue = ConfigurationOverview::getRevisedModelValue($modelName, $value, $model->$value);

                    echo "<tr><td><b style='text-align:left;'>" . $model->getAttributeLabel($value) . ":</b></td>";
                    echo "<td style='text-align:right;'>" . $modelValue . "</td></tr>";
                }
            }
            echo "</table>";
        } else {
            echo "Test-Text-Box for THIS MODULE to check how many text can stand in this little shiny tooltip-box!";
        }
    }

    protected function getGraphicalTreeData($dataArray)
    {
        return array(
            'name' => __('ADMIN_CONFIGURATION_OVERVIEW_INCOMMING_CALL'), //'Incomming Call',
            'children' => $dataArray
        );
    }
}
