<?php

/**
  model class name  = ProvisioningProfile
  form-id  == provisioning-profile-form

 */
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'.
     */
    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',
                    'create',
                    'update',
                    'delete',
                    'export',
                    'import',
                    'generatePDF'
                ),
                'expression' => AccessManager::checkSessionPermission($this->module->name),
            ),
            array('deny', // deny all users
                'users' => array('*'),
            ),
        );
    }

    public function actionIndex() {
        $model = new SpeedDialList();
        $this->render('index', array(
            'model' => $model,
        ));
    }

    public function actionCreate() {
        $model = new SpeedDialList();
        $this->updateSpeedDialList($model);
    }

    public function actionUpdate($id) {
        $model = SpeedDialList::model()->findByPk($id);
        $this->updateSpeedDialList($model);
    }

    private function updateSpeedDialList($model) {
        $this->performAjaxValidation($model);
        $models = $this->getSpeedDialModelsFromList($model->id);
        $this->getAttributesFromPost($model);

        if (empty($models)) {
            $models[] = $this->addDefaultSpeedDial();
        }

        $dataProvider = $this->getDataProvider($models);
        $this->renderSpeedDialListGrid($model, $dataProvider);
    }

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

    private function getAttributesFromPost($model) {
        if (isset($_POST['SpeedDial']) && isset($_POST['SpeedDialList'])) {
            $model->attributes = $_POST['SpeedDialList'];
            $speedDials = $_POST['SpeedDial'];
            $this->saveModel($model, $speedDials);
        } elseif (isset($_POST['SpeedDialList'])) {
            $oldModels = $this->getSpeedDialModelsFromList($model->id);
            $this->deleteOutdatedModels(array(), $oldModels);
            $this->redirect(url('/adminSpeedDialList/default/index'));
        }
    }

    private function saveModel($model, $speedDials) {
        if ($model->save()) {
            $this->saveSpeedDials($model, $speedDials);
            $this->redirect(url('/adminSpeedDialList/default/index'));
        } else {
            Yii::app()->user->setErrorFlashMessage();
        }
    }

    private function saveSpeedDials($profile, $speedDials) {
        $oldModels = $this->getSpeedDialModelsFromList($profile->id);
        $this->updateOldListentrys($oldModels, $speedDials);

        //remove outdated list entrys
        foreach ($oldModels as $model) {
            $model->delete();
        }

        $errors = array();
        foreach ($speedDials as $id => $attributes) {
            $model = new SpeedDial("create");
            $attributes["profile_id"] = $profile->id;
            $model->attributes = $attributes;

            if (!$model->save()) {
                $errors[] = $model->errors;
            }
        }

        if (!empty($errors)) {
            app()->user->setErrorFlashMessage("CHANGES_NOT_SAVED_CAUSE_OF_AN_ERROR");
            $this->redirect(url('/adminSpeedDialList/default/update', array("id" => $profile->id)));
        }
    }

    private function updateOldListentrys(&$oldModels, &$speedDials) {
        foreach ($oldModels as $key => $model) {
            if (array_key_exists($model->id, $speedDials)) {
                $model->attributes = $speedDials[$model->id];
                $model->save();
                unset($speedDials[$model->id]);
                unset($oldModels[$key]);
            }
        }
    }

    private function getSpeedDialModelsFromList($id) {
        $speedDialList = SpeedDialList::model()->findByPk($id);
        if (isset($speedDialList)) {
            $models = SpeedDial::model()->findAllByAttributes(array('profile_id' => $speedDialList->id));
            return $models;
        }
        return array();
    }

    private function deleteOutdatedModels($newModels, $oldModels) {
        if ($oldModels) {
            foreach ($oldModels as $oldModel) {
                if (!in_array($oldModel->id, $newModels)) {
                    $oldModel->delete();
                }
            }
        }
    }

    private function addDefaultSpeedDial() {
        $newModel = new SpeedDial("SpeedDialList");
        $newModel->id = 0;
        return $newModel;
    }

    private function getDataProvider($models) {
        return new CArrayDataProvider(
                $models, array(
            'pagination' => false,
            'sort' => array(
                'defaultOrder' => 'key ASC',
            ))
        );
    }

    private function renderSpeedDialListGrid($model, $dataProvider) {
        $this->render('speedDialListGrid', array(
            'model' => $model,
            'dataProvider' => $dataProvider,
        ));
    }

    public function actionDelete($id) {
        if (Yii::app()->request->isPostRequest) {
            //we only allow deletion via POST request
            $this->loadModel($id)->delete();
            //if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
            if (!isset($_GET['ajax'])) {
                $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('index'));
            }
        } else {
            throw new CHttpException(400, 'Invalid request. Please do not repeat this request again.');
        }
    }

    public function actionExport() {
        if (isset($_REQUEST['profile_id'])) {
            $models = SpeedDial::model()->findAllByAttributes(array(
                'profile_id' => $_REQUEST['profile_id']
            ));

            $items = array();

            $blacklistedAttributes = $this->getBlacklistedAttributes();

            foreach ($models as $model) {
                $items[] = $this->getExportItem($blacklistedAttributes, $model);
            }

            header('Content-Type: application/json');
            header('Content-Disposition: attachment; filename=speedDial.json');
            header('Pragma: no-cache');
            echo json_encode($items);
        }
    }

    private function getExportItem($blacklistedAttributes, $model) {
        $item = array();
        foreach (SpeedDial::myAttributes() as $attribute) {
            if (!in_array($attribute, $blacklistedAttributes)) {
                $item[$attribute] = $model->$attribute;
            }
        }
        return $item;
    }

    private function getBlacklistedAttributes() {
        return array('id', 'owner', 'profile_id');
    }

    public function actionImport() {
        $model = new SpeedDialList("create");
        $this->performAjaxValidation($model);
        if (isset($_POST['SpeedDialList'])) {

            $file = CUploadedFile::getInstance($model, 'file');
            if (!$file) {
                $model->addError("file", __('LICENCE_MODEL_REQUIRED_ERROR_MESSAGE'));
                echo json_encode(array('errors' => array("SpeedDialList_file" => array(__('CSV_SELECT_FILE_NO_FILE_SELECTED')))));
                Yii::app()->end();
            } else {
                $fileData = file_get_contents($file->tempName);
                if (!$this->validateFileContent($fileData)) {
                    $model->addError("file", __('SPEED_DIAL_IMPORT_INVALID_FILE'));
                    echo json_encode(array('errors' => array("SpeedDialList_file" => array(__('SPEED_DIAL_IMPORT_INVALID_FILE')))));
                    Yii::app()->end();
                }
            }
            
            $model->attributes = $_POST['SpeedDialList'];
            if ($model->save()) {
                $fileEntrys = json_decode($fileData, true);
                usort($fileEntrys, function ($a, $b) {
                    return (int)$a["key"] >=  (int)$b["key"];
                });
                foreach ($fileEntrys as $entry) {
                    $speedDial = $this->getParsedJsonModel($entry);
                    $speedDial->profile_id = $model->id;
                    $speedDial->save();
                }
            }
        }

        $this->renderPartial('import', array("model" => $model), false, true);
    }

    private function validateFileContent($json) {
        $fileEntrys = json_decode($json, true);
        if (!is_array($fileEntrys)) {
            return false;
        }

        foreach ($fileEntrys as $item) {
            if (!$this->validateImportItem($item)) {
                return false;
            }
        }
        return true;
    }

    private function getParsedJsonModel($entry) {
        $model = new SpeedDial("create");
        foreach ($entry as $key => $value) {
            if (property_exists($model, $key)) {
                $model->$key = $value;
            }
        }
        return $model;
    }

    public function renderSpeedDialInput($data, $row, $column) {
        $attribute = $column->name;
        if ($data->id) {
            $fieldName = get_class($data) . "[" . $data->id . "][" . $attribute . "]";
        } else {
            $fieldName = get_class($data) . "[" . $row . "][" . $attribute . "]";
        }

        return $this->renderPartial("speedDialInput", array("data" => $data, "attribute" => $attribute, "fieldName" => $fieldName), true, false);
    }

    private function validateImportItem($item) {
        
        $expectedKeys = array("key", "phoneNumber", "description");
        $speedDial = new SpeedDial("fileValidation");
        
        foreach ($item as $key => $value) {
            if (!in_array($key, $expectedKeys)) {
                continue;
            } else {
                $speedDial->$key = $value;
            }
        }
        
        return $speedDial->validate();
    }

    public function actionGeneratePDF() {
        if (isset($_REQUEST['profile_id']) && !empty($_REQUEST['profile_id'])) {
            $models = SpeedDial::model()->findAllByAttributes(array(
                'profile_id' => $_REQUEST['profile_id']
            ));
            $speedDialList = SpeedDialList::model()->findByPk($_REQUEST['profile_id']);

            $formatedDate = PhonalisaDate::changeRFC2822EnglishToUserLanguage();

            $generator = new SpeedDialPDFGenerator();
            $generator->init(
                    __("PHONALISA_SPEEDIALLIST"), __("PHONALISA_SPEEDIALLIST_FOR_NAME")
                    . " $speedDialList->name - $formatedDate"
            );
            $generator->generate($models); // outputs the PDF
        }
    }

    /**
     * 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 = SpeedDialList::model()->findByPk($id);
        if ($model === null) {
            throw new CHttpException(404, 'The requested page does not exist.');
        }
        return $model;
    }

}
