(function(angular){
    'use strict';

    var app = angular.module('activities.controllers', ['ngSanitize']);

    app.controller('RelationshipCtrl', ['$scope',
        function ($scope) {

            function compareNumbers(a, b) {
              return a - b;
            }

            $scope.$watch('currentActivity', function(currentActivity) {
                $scope.possibleAnswers = currentActivity.expected.slice(0);
                $scope.possibleAnswers.sort(compareNumbers);
            });

            $scope.possibleAnswers = $scope.currentActivity.expected.slice(0);
            $scope.possibleAnswers.sort(compareNumbers);
        }
    ]);

    app.controller('DiscussionActivityCtrl', [
      '$scope',
      '$sce',
      '$routeParams',
      '$anchorScroll',
      '$document',
      'uiTinymceConfig',
      'Forum',
      'Topic',
      'Comment',
      'TopicLike',
      'TopicFile',
      'CommentLike',
      'CommentFile',
      'Progress',
      'ClassActivity',
      'CurrentUser',
      'AnswerNotification',
      'ContentFile',
      function ($scope, $sce, $routeParams, $anchorScroll, $document, uiTinymceConfig, Forum, Topic, Comment, TopicLike, TopicFile, CommentLike, CommentFile, Progress, ClassActivity, CurrentUser, AnswerNotification, ContentFile) {
        $scope.activity_open = true;
        $scope.activity_expired = false;
        var now = Date.now();
        var start_date = Date.parse($scope.currentActivity.data.start_date);
        var end_date = Date.parse($scope.currentActivity.data.end_date);

        $scope.user = CurrentUser;

        $scope.question = $scope.currentActivity.data.content;

        // Decide the current state of the activity
        if(now < start_date){
          // The Activity is not open yet
          $scope.activity_open = false;
        } else if(now > end_date){
          // The Activity has been open and now is already expired
          $scope.activity_expired = true;
        }

        uiTinymceConfig.automatic_uploads = true;
        uiTinymceConfig.images_upload_handler = ContentFile.upload;

        // If there is not an answer yet, create topic instance
        $scope.topic = new Topic();
        $scope.topic.title = 'Resposta de atividade';
        $scope.topic.forum = $scope.currentActivity.data.forum;

        // Check if there is an answer to this activity
        if ($scope.answer.$promise) {
            $scope.answer.$promise.then(function(answer) {
                // if there is, show the corresponding topic that holds this answer and its comments
                $scope.show_answer = true;
                if(answer.given !== undefined && answer.given.topic)
                    $scope.topic = Topic.get({id: answer.given.topic, activity: true});
            });
        }

        // if there is no answer, show the text editor and prepare to save it
        $scope.show_answer = false;
        $scope.edit_topic = false;

        $scope.show_edit = function () {
          $scope.edit_topic = true;
          $scope.show_answer = false;
        }

        $scope.save_answer = function() {
            // if there is no content, the edit form must not disappear from screen
            if($scope.topic.content === undefined || $scope.topic.content === ""){
                throw "Content field is empty"
                return;
            }
            $scope.sending = true;
            var topic_files = $scope.topic.files;
            if ($scope.topic.id)
                $scope.topic.$update({activity: true}, function(topic) {
                    $scope.edit_topic = true;
                    $scope.show_answer = true;
                    angular.forEach(topic_files, function(topic_file) {
                        if (!topic_file.hasOwnProperty('topic') || !topic_file.topic) {
                            topic_file.topic = topic.id;
                            delete topic_file.file;
                            topic_file.$patch().then(function(comment_file_complete) {
                                topic.files.push(comment_file_complete);
                            });
                        }
                    });
                }, function(error) {
                    console.error(error)
                  alert("Não foi possível salvar a sua resposta. Por favor, verifique sua conexão com a internet e tente novamente! Caso o problema persista, salve o seu texto em um arquivo no seu computador para não perder sua atividade.");
                });
            else
                $scope.topic.$save(function(topic) {
                    $scope.answer.given = {topic: topic.id};
                    $scope.answer.activity = $scope.currentActivity.id;
                    $scope.answer.$save().then(function(answer) {
                        $scope.currentUnit.progress = Progress.complete($scope.currentUnit.id);
                        $scope.edit_topic = true;
                        $scope.show_answer = true;
                    }, function(error) {
                      alert("Não foi possível salvar a sua resposta. Por favor, verifique sua conexão com a internet e tente novamente! Caso o problema persista, salve o seu texto em um arquivo no seu computador para não perder sua atividade.");
                    });
                    angular.forEach(topic_files, function(topic_file) {
                        if (!topic_file.hasOwnProperty('topic') || !topic_file.topic) {
                            topic_file.topic = topic.id;
                            delete topic_file.file;
                            topic_file.$patch().then(function(comment_file_complete) {
                                topic.files.push(comment_file_complete);
                            });
                        }
                    });
                }, function(error) {
                    console.error(error)
                    alert("Não foi possível salvar a sua resposta. Por favor, verifique sua conexão com a internet e tente novamente! Caso o problema persista, salve o seu texto em um arquivo no seu computador para não perder sua atividade.");
                });
        };

        // Bootstrap functions for new comments and replies
        $scope.new_comment = function(){
            var comment = new Comment();
            comment.topic = $scope.topic;
            return comment;
        };

        $scope.uploadTopicFiles = function (file, topic) {
            if (file) {
                TopicFile.upload(file).then(function (response) {
                    var comment_file = new TopicFile(response.data);
                    if (topic.files === undefined)
                        topic.files = [];
                    topic.files.push(comment_file);
                    return {location: comment_file.file};
                }, function(error){

                }, function(evt){
                    topic.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
                });
            }
        };

        $scope.uploadCommentFiles = function (file, comment) {

            if (file) {
                CommentFile.upload(file).then(function (response) {
                    var comment_file = new CommentFile(response.data);

                    if (comment.files === undefined)
                        comment.files = [];
                    comment.files.push(comment_file);
                    return {location: comment_file.file};
                }, function (response) {
                    if (response.status > 0) {
                        $scope.errorMsg = response.status + ': ' + response.data;
                    }
                }, function (evt) {
                    comment.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
                });
            }
        }

        var my_topic_activity = null;
        $scope.my_answer = true;
        // Load the given answer from other student on screen
        $scope.viewAnswer = function(activity_topic){
            if(my_topic_activity === null)
                my_topic_activity = $scope.topic;
            $scope.my_answer = false;
            $scope.topic = activity_topic;
            $scope.show_answer = true;

            AnswerNotification.update({topic: activity_topic.id, is_read: true});

            setTimeout(function() {
                $('html, body').animate({
                  'scrollTop':   $('#answer').position().top
                }, 500);
            }, 100);
        };

        $scope.viewMyAnswer = function(){
            $scope.topic = my_topic_activity;
            $scope.my_answer = true;
            // If the user still hasn't created an answer, the editor must be reactivated too
            if(!$scope.topic.hasOwnProperty('id')){
              $scope.show_answer = false;
            }
        };

        // Load other students activities
        $scope.classes_activities = ClassActivity.query({
            activity: $scope.currentActivity.id,
            course: $scope.lesson.course,
            ordering: '-last_activity_at',
            exclude_cur_user: true,
          }, function(response){
                // Check if there are any activities to show
                var acticvities = false;
                for (var i = 0; i < response.length; i++) {
                    if(response[i].activity_answers.length > 0){
                      acticvities = true;
                      break;
                    }
                }
                $scope.activities_loaded = acticvities;
            }
        );

        $scope.topic_like = function(topic) {
            if (topic.user_like) {
                TopicLike.delete({id:topic.user_like});
                topic.user_like = 0;
                topic.count_likes -=1;
            } else {
                // Change this before promisse so the user sees the action take effect.
                topic.user_like = -1;

                  TopicLike.save({topic:topic.id}, function(topic_like){
                    topic.user_like = topic_like.id;
                });
                topic.count_likes +=1
            }
        };

        $scope.save_comment = function(comment, parent_comment) {
            var comment_destination;
            var raw_comment = comment;
            if (parent_comment) {
                comment.parent = parent_comment.id;
                comment_destination = parent_comment.comment_replies;
            } else {
                comment_destination = comment.topic.comments;
            }
            // Store files to be saved after the comment
            var files = [];
            angular.copy(comment.files, files);
            delete comment.files;

            // Turn the topic object into an id for JSON parsing
            comment.topic = comment.topic.id;

            // Send the comment data to be saved by the API
            comment.$save().then(function(comment) {
                angular.forEach(files, function(comment_file) {
                    comment_file.comment = comment.id;
                    delete comment_file.file;
                    comment_file.$patch().then(function(comment_file_complete) {
                        comment.files.push(comment_file_complete);
                    });
                });
                comment_destination.push(raw_comment);
                if(!parent_comment) {
                  $scope.topic.show_comment_input = false;
                  var last_comment = angular.element(document.getElementById('last-comment'));
                  $document.scrollToElement(last_comment);
                } else {
                  parent_comment.show_comment_input = false;
                }
            });
        };

        $scope.update_comment = function(changed_comment) {
            var comment_files = changed_comment.files;

            // Get the correct comment instance from the server
            Comment.get({id: changed_comment.id}, function(comment){
              comment.text = changed_comment.text;
              angular.copy(comment, changed_comment);
              comment.$update().then(function(comment) {
                  angular.forEach(comment_files, function(comment_file) {
                        if(comment_file instanceof CommentFile){ // Prepare only new files for store in the topic
                          comment_file.comment = comment.id;
                          delete comment_file.file;
                          comment_file.$patch().then(function(comment_file_complete) {
                              changed_comment.files.push(comment_file_complete);
                          });
                      }
                  });
              });
            });
        };

        $scope.comment_like = function(comment) {
            if (comment.user_like) {
                CommentLike.delete({id:comment.user_like});
                comment.user_like = 0;
                comment.count_likes -=1;
            } else {
                // Change this before promisse so the user sees the action take effect.
                comment.user_like = -1;

                CommentLike.save({comment:comment.id}, function(comment_like){
                    comment.user_like = comment_like.id;
                });
                comment.count_likes +=1;
            }
        };

        $scope.get_as_safe_html = function(html_content) {
            return $sce.trustAsHtml(html_content);
        };

      }
    ]);

    app.controller('PresentationActivityCtrl', [
        '$scope',
        '$sce',
        'uiTinymceConfig',
        function ($scope, $sce, uiTinymceConfig) {
            uiTinymceConfig.automatic_uploads = true;

            $scope.getReadingActivityHtml = function() {
                return $sce.trustAsHtml($scope.currentActivity.comment);
            };

        }
    ]);

    app.controller('MultipleChoiceCtrl', [
        '$scope',
        '$sce',
        'Progress',
        'Answer',
        function($scope, $sce, Progress, Answer) {

            $scope.$watch('currentActivity', function(currentActivity) {
                $scope.answer = Answer.get({activityId: currentActivity.id}, function(answer) {
                    // Prepare the 'given' array to receive answers, if necessary
                    // If the given array from the server is out of sync with the alternatives, it must be recreated now
                    // This ensures that every alternative will have a booleaan answer
                    if(answer.given.length !== currentActivity.data.alternatives.length) {
                        for(var i = 0; i < currentActivity.data.alternatives.length; i++) {
                            answer.given[i] = false;
                        }
                    }
                    return answer;
                }, function(error) {
                    console.log('answer does not exists or other errors');
                    var answer = {};
                    if(angular.isArray(currentActivity.expected)) {
                        answer.given = currentActivity.expected.map(function(){});
                    }
                    $scope.$root.changed = true;
                    $scope.answer = new Answer(answer);
                });
            });

            $scope.sendAnswer = function() {

                // Force given to be an array, if necessary
                if(typeof $scope.answer.given === 'object'){
                    $scope.answer.given = Object.keys($scope.answer.given).map(function(key) { return $scope.answer.given[key]; });
                }
                // Creates a new answer object for each user answer
                $scope.answer.activity = $scope.currentActivity.id;
                $scope.answer.$save().then(function(answer) {
                    if(answer.correct)
                        $scope.currentUnit.progress = Progress.complete($scope.currentUnit.id);
                }, function(error) {
                    alert("Não foi possível salvar a sua resposta. Por favor, verifique sua conexão com a internet e tente novamente! Caso o problema persista, salve o seu texto em um arquivo no seu computador para não perder sua atividade.");
                });
            };
        }
    ]);

})(angular);