/**
 * Created by dragan.simonovski on 2/17/2016.
 */
'use strict';

/**
 * @ngdoc directive
 * @name global.directive:coreNotes
 * @restrict E
 *
 * @description
 *
 * {@link /acm-standard-applications/arkcase/src/main/webapp/resources/directives/core-notes/core-notes.client.directive.js directives/core-notes/core-notes.client.directive.js}
 *
 * The "Core-Notes" directive add notes grid functionality
 *
 * @param {Object} config object containing configuration items for current component
 * @param {Object} notesInit object containing object type and current object id
 * @param {string} notesInit.objectType string for the type of the object
 * @param {string} notesInit.noteType string for the type of the note object, can be optional
 * @param {string} notesInit.noteTitle string for the title of notes directive, can be optional
 * @param {boolean} notesInit.showAllNotes boolean to show all note types not just one (GENERAL), can be optional
 *
 * @example
 <example>
 <file name="index.html">
 <core-notes config="config" notes-init="notesInit"/>
 </file>
 <file name="app.js">
 angular.module('cases').controller('Cases.NotesController', ['$scope', '$stateParams', 'ConfigService', 'ObjectService'
 , function ($scope, $stateParams, ConfigService, ObjectService) {

 ConfigService.getComponentConfig("cases", "notes").then(function (config) {
 $scope.notesInit = {
 objectType: ObjectService.ObjectTypes.CASE_FILE,
 currentObjectId: $stateParams.id
 };
 $scope.config = config;
 return config;
 });
 }
 ]);
 </file>
 </example>
 */
angular.module('directives').directive(
        'coreNotes',
        [
                '$q',
                '$modal',
                '$translate',
                'Authentication',
                'Helper.UiGridService',
                'Helper.NoteService',
                'Object.NoteService',
                'UtilService',
                'Mentions.Service',
                function($q, $modal, $translate, Authentication, HelperUiGridService, HelperNoteService, ObjectNoteService, Util, MentionsService) {
                    return {
                        restrict: 'E',
                        scope: {
                            notesInit: '=',
                            config: '=',
                            mentionInfo: '='
                        },
                        link: function(scope, element, attrs) {

                            Authentication.queryUserInfo().then(function(userInfo) {
                                scope.userId = userInfo.userId;
                                return userInfo;
                            });

                            // set scope.isReadOnly for addButton in gridHelper
                            scope.isReadOnly = function(objectInfo) {
                                return scope.notesInit.isReadOnly;
                            };

                            var noteHelper = new HelperNoteService.Note();
                            var gridHelper = new HelperUiGridService.Grid({
                                scope: scope
                            });
                            var promiseUsers = gridHelper.getUsers();

                            scope.$watchCollection('config', function(config, oldValue) {
                                if (scope.notesInit) {
                                    if (!scope.notesInit.noteTitle) {
                                        scope.notesInit.noteTitle = $translate.instant("common.directive.coreNotes.title");
                                    }
                                }

                                if (config) {

                                    // if buttons were defined in config, try to use the getConfigurableButton method
                                    if (Util.goodArray(config.buttons)) {
                                        _.each(config.buttons, function(button) {
                                            gridHelper.addConfigurableButton(config, button);
                                        });
                                        // check if the config had an entry for 'edit'. If not, add in default edit button
                                        if (!hasButton(config, "edit")) {
                                            gridHelper.addButton(config, "edit");
                                        }
                                        // check if the config had an entry for 'delete'. If not, add in default delete button
                                        if (!hasButton(config, "delete")) {
                                            gridHelper.addButton(config, "delete");
                                        }
                                    } else {
                                        // no buttons were found in the config, use the default settings
                                        gridHelper.addButton(config, "edit");
                                        gridHelper.addButton(config, "delete");
                                    }
                                    gridHelper.setColumnDefs(config);
                                    gridHelper.setBasicOptions(config);
                                    gridHelper.disableGridScrolling(config);
                                    gridHelper.setExternalPaging(config, scope.retrieveGridData);

                                    gridHelper.setUserNameFilterToConfig(promiseUsers);
                                    scope.retrieveGridData();
                                }

                            });

                            // check if config file has an entry for any named button
                            var hasButton = function(config, name) {
                                var buttonPresent = false;
                                _.each(config.buttons, function(button) {
                                    if (button.name == name) {
                                        buttonPresent = true;
                                        //return false to break out of the loop
                                        return false;
                                    }
                                });
                                return buttonPresent;
                            };

                            scope.retrieveGridData = function() {
                                var info = scope.notesInit;
                                if (info) {
                                    var promiseQueryNotes = ObjectNoteService.queryNotesPage(info.objectType, info.currentObjectId, info.showAllNotes ? 'ALL' : info.noteType, Util.goodValue(scope.start, 0), Util.goodValue(scope.pageSize, 10), Util.goodMapValue(scope.sort, "by"), Util.goodMapValue(
                                            scope.sort, "dir"));

                                    promiseQueryNotes.then(function(data) {
                                        scope.gridOptions = scope.gridOptions || {};
                                        scope.gridOptions.data = data.resultPage;
                                        scope.gridOptions.totalItems = data.totalCount;
                                    });
                                }
                            };

                            scope.addNew = function() {
                                var info = scope.notesInit;
                                var note = noteHelper.createNote(info.currentObjectId, info.objectType, info.parentTitle, info.tag, scope.userId, info.noteType);
                                showModal(note, false);
                            };
                            scope.editRow = function(rowEntity) {
                                var note = angular.copy(rowEntity);
                                showModal(note, true);
                            };
                            scope.deleteRow = function(rowEntity) {
                                gridHelper.deleteRow(rowEntity);
                                //because we are using external paging we should set totalItems too
                                scope.gridOptions.totalItems--;
                                var id = Util.goodMapValue(rowEntity, "id", 0);
                                if (0 < id) { //do not need to call service when deleting a new row with id==0
                                    var info = scope.notesInit;
                                    ObjectNoteService.deleteNote(id, info.currentObjectId, info.objectType).then(function() {
                                        scope.retrieveGridData();
                                    });
                                }
                            };
                            function showModal(note, isEdit) {

                                var modalScope = scope.$new();
                                modalScope.note = note || {};
                                modalScope.isEdit = isEdit || false;

                                // --------------  mention --------------
                                scope.params = {
                                    emailAddresses: [],
                                    usersMentioned: []
                                };

                                var modalInstance = $modal.open({
                                    scope: modalScope,
                                    animation: true,
                                    templateUrl: 'directives/core-notes/core-notes.modal.client.view.html',
                                    controller: function($scope, $modalInstance) {
                                        $scope.onClickOk = function() {
                                            $modalInstance.close({
                                                note: $scope.note,
                                                isEdit: $scope.isEdit
                                            });
                                        };
                                        $scope.onClickCancel = function() {
                                            $modalInstance.dismiss('cancel');
                                        }
                                    },
                                    size: 'md',
                                    backdrop: 'static'
                                });

                                modalInstance.result.then(function(data) {
                                    ObjectNoteService.saveNote(data.note).then(function(note) {
                                        if (scope.mentionInfo) {
                                            var url = "/home.html#!/viewer/" + scope.mentionInfo.fileId + "/" + scope.mentionInfo.containerObjectId + "/" + scope.mentionInfo.containerObjectType + "/" + encodeURIComponent(scope.mentionInfo.fileName) + "/" + scope.mentionInfo.fileId;
                                            MentionsService.sendEmailToMentionedUsersWithUrl(scope.params.emailAddresses, scope.params.usersMentioned, scope.mentionInfo.containerObjectType, scope.mentionInfo.containerObjectId, url, note.note);
                                        } else {
                                            var noteParentType = "";
                                            if (note.type == "REJECT_COMMENT") {
                                                noteParentType = "TASK_REJECT_COMMENT"
                                            } else if (note.type == "REJECT_COMMENT") {
                                                noteParentType = "TASK_REJECT_COMMENT"
                                            } else {
                                                noteParentType = note.parentType;
                                            }
                                            MentionsService.sendEmailToMentionedUsers(scope.params.emailAddresses, scope.params.usersMentioned, "NOTE", noteParentType, note.parentId, note.note);
                                        }
                                        scope.retrieveGridData();
                                    }, function() {
                                    });
                                });
                            }
                        },
                        templateUrl: 'directives/core-notes/core-notes.client.view.html'
                    };
                } ]);
