'use strict';
/**
 * @ngdoc directive
 * @name annotationAppApp.directive:tagSelection
 * @description
 * # tagSelection
 */
angular.module('app')
.directive('tagSelection', function($q, $rootScope, Tag, TextReview, notify, HtmlKeywordsUnderliner, Annotations) {
    return {
	    template: require('./tag-selection.html'),
        restrict: 'E',
        scope: {
            tagsDomain: '=',
            language: '=',
            selectedText: '=?',
            review: '='
        },
        link: function postLink(scope) {
            var resetStatus = function() {
                angular.forEach(Object.keys(scope.categories), function(cKey) {
                    angular.forEach(Object.keys(scope.categories[cKey].uid), function(uKey) {
                        scope.categories[cKey].uid[uKey]._status.isOpen = false;
                        scope.categories[cKey].uid[uKey]._status.sentiment = null;
                        scope.categories[cKey].uid[uKey]._status.newSynonym = '';

                    });
                });
                angular.forEach(Object.keys(scope.uids), function(uKey) {
                    scope.uids[uKey]._status.isOpen = false;
                    scope.uids[uKey]._status.sentiment = null;
                    scope.uids[uKey]._status.newSynonym = '';

                });
            };
            var addNewSynonym = function(category, uid, synonym) {
                scope.categories[category].uid[uid][synonym] = {};
                var newSyns = [];
                Object.keys(scope.categories[category].uid[uid]).forEach(function(key) {
                    if (key !== '_status' && key !== 'syns' && key !== 'definition') {
                        newSyns.push(key);
                    }
                });
                scope.categories[category].uid[uid].syns = newSyns.join(', ');
                scope.uids[uid][synonym] = {};
                scope.uids[uid].syns = newSyns.join(', ');
            };
            scope.removeSentiment = function(status, $event) {
                $event.stopPropagation();
                $event.preventDefault();
                status.sentiment = null;
                status.isOpen = false;
                status.newSynonym = '';
            };
            scope.selectSentiment = function(status, sentiment) {
                var prevSentiment = status.sentiment;
                resetStatus();
                if (prevSentiment === sentiment) {
                    status.isOpen = false;
                    status.sentiment = null;
                } else {
                    status.sentiment = sentiment;
                    status.isOpen = true;
                }
            };
            scope.addFeature2Sentiment = function(categoryKey, uidKey, sentiment, synonym, origin) {
                var _categoryKey = categoryKey;
                if (!categoryKey) {
                    angular.forEach(scope.categoriesKeys, function(cKey) {
                        angular.forEach(Object.keys(scope.categories[cKey].uid), function(uKey) {
                            if (!_categoryKey && uKey === uidKey) {
                                _categoryKey = cKey;
                            }
                        });
                    });
                }
                var reviewLanguage = scope.review.review.language;
                var _syn = null;
                if (reviewLanguage === 'en' || reviewLanguage === 'gb' || reviewLanguage === 'us') {
                    _syn = synonym;
                }
                var feature2Sentiment = {
                    category: _categoryKey,
                    name: synonym,
                    text: scope.selectedText.text,
                    syn: _syn,
                    sentiment: sentiment,
                    start: scope.selectedText.start,
                    offset: scope.selectedText.offset,
                    uid: uidKey,
                    version: 'v2',
                    origin: origin
                        // here i should set the field origin
                        // origin should be added to this method parameters
                };
                feature2Sentiment.id = Annotations.getIdByAnnotation(feature2Sentiment);
                
                var tag = {
                    name: synonym,
                    domain: scope.tagsDomain,
                    language: scope.language,
                    syn: _syn,
                    uid: uidKey,
                    category: _categoryKey,
                    origin: origin,
                    type: 'company-generated'
                };
                
                $q.all([
                    TextReview.addFeature2Sentiment(scope.review._id, feature2Sentiment),
                    Tag.updateOrCreate(tag)
                ]).then(function() {
                    if (!scope.review.feature2sentiment) {
                        scope.review.feature2sentiment = [];
                    }
                    scope.review.feature2sentiment.push(feature2Sentiment);
                    addNewSynonym(_categoryKey, uidKey, synonym);
                    resetStatus();
                    $rootScope.$emit('ANNOTATION_SAVED');
                    notify.show('Annotation saved!');
                }).catch(function() {
                    resetStatus();
                    notify.show("Error while saving annotation");
                });
            };
            scope.dictionaryVisible = false;
            scope.visualizationType = 'tree';
            scope.categories = {};
            scope.uids = {};
            scope.uidsKeys = [];
            scope.categoriesKeys = [];

            scope.changeView = function(visualizationType) {
                scope.visualizationType = visualizationType;
            };

            scope.toggleTagDictionary = function() {
                scope.dictionaryVisible = !scope.dictionaryVisible;
            };

            scope.$on('toggleTagDictionary', function() {
                scope.toggleTagDictionary();
            });

            scope.closeSelection = function() {
                scope.$emit('tagSelectionClosed');
            };

            var elaborateTags = function(tags) {
                var categories = {};
                var uids = {};
                for (var i = 0; i < tags.length; i++) {
                    var cat = tags[i].category;
                    var uid = tags[i].uid;
                    var name = tags[i].name;
                    if (cat && uid) {
                        if (!categories[cat]) {
                            categories[cat] = {
                                uid: {}
                            };
                        }
                        if (!categories[cat].uid[uid]) {
                            categories[cat].uid[uid] = {};
                        }
                        if (!categories[cat].uid[uid][name]) {
                            categories[cat].uid[uid][name] = {};
                        }
                    }
                }
                angular.forEach(Object.keys(categories), function(key) {
                    categories[key].uidKeys = Object.keys(categories[key].uid);
                    angular.forEach(Object.keys(categories[key].uid), function(uidKey) {
                        categories[key].uid[uidKey].syns = Object.keys(categories[key].uid[uidKey]).join(', ');
                        categories[key].uid[uidKey].definition = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ac lacus erat. Praesent aliquet pulvinar velit, vitae tempus mi molestie mattis. Ut eget tellus nisi.';
                        if (!categories[key].uid[uidKey]) {
                            uids[uidKey] = {};
                        }
                        uids[uidKey] = categories[key].uid[uidKey];
                    });
                });
                scope.uids = uids;
                scope.uidsKeys = Object.keys(uids);
                scope.categories = categories;
                scope.categoriesKeys = Object.keys(categories);
                angular.forEach(Object.keys(scope.uids), function(key) {
                    scope.uids[key]._status = {
                        isOpen: false,
                        sentiment: null,

                        mouseOver: false,
                        newSynonym: ''
                    };
                });
                angular.forEach(Object.keys(scope.categories), function(cKey) {
                    angular.forEach(Object.keys(scope.categories[cKey].uid), function(uKey) {
                        scope.categories[cKey].uid[uKey]._status = {
                            isOpen: false,
                            sentiment: null,
                            mouseOver: false,
                            newSynonym: ''
                        };
                    });
                });
            };
            var getDictionaryTags = function() {
                scope.categories = {};
                scope.uids = {};
                scope.categoriesKeys = [];
                scope.uidsKeys = [];
                Tag.getAllTags({
                    languages: {
                        $in: ['en', 'gb', 'us']
                    },
                    domain: scope.tagsDomain,
                    $or: [{
                        type: 'company-generated'
                    }, {
                        type: 'ana-generated'
                    }]
                }).then(function(tags) {
                    elaborateTags(tags);
                }, function(err) {
                    console.log(err);
                    alert(JSON.stringify(err, null, 4));
                });
            };
            scope.$watch('tagsDomain', function() {
                getDictionaryTags();
            });
            scope.$watch('language', function() {
                getDictionaryTags();
            });
            getDictionaryTags();
        }
    };
});
