/**
 * Controls the taking of a survey
 */
(function (window) {
    'use strict';
    angular.module('cla.survey').controller('startController', startController);

    startController.$inject = ['$rootScope','$scope', '$window', 'surveyActions', 'surveyTracker'];

    /**
     * @param $rootScope
     * @param $scope
     * @param $window
     * @param surveyTracker
     * @param surveyActions
     * @constructor
     */
    function startController($rootScope, $scope, $window, surveyActions, surveyTracker) {
        let questionContainer;
        let questionTimeouts = [];

        $scope.beingSubmitted = false;
        $scope.currentSection = null; // current question object
        $scope.optionIndexes = null; // map of option indexes to option IDs
        $scope.outstandingRequests = 0;
        $rootScope.isLastSection = false;
        $scope.isIE = /msie\s|trident\/|edge\//i.test(window.navigator.userAgent);

        // user is continue his attempt and it is last section - set button to finish
        if (surveyTracker.trackpos === surveyTracker.count - 1) {
            $rootScope.isLastSection = true;
        }

        $scope.toggleOption = toggleOption;
        $scope.toggleCheckboxes = toggleCheckboxes;
        $scope.saveInputText = saveInputText;
        $scope.isPrevDisabled = isPrevDisabled;

        /** broadcast to nav, so skip the question*/
        $scope.skip = function() {
            $scope.$broadcast('survey.skip');
        };

        /** broadcast to nav - go to next section and save */
        $scope.next = function() {
            // set flag when it's last section
            if (surveyTracker.trackpos === surveyTracker.count - 2) {
                $rootScope.isLastSection = true;
            }

            $scope.$broadcast('survey.next');
        };

        /** go to previous section */
        $scope.previous = function() {
            // set flag int the rootScope when it's last section
            $rootScope.isLastSection = false;

            $scope.$broadcast('survey.previous');
        };

        $scope.finish = function() {
            $scope.beingSubmitted = true;
            $scope.$broadcast('survey.finish', function(result) {
                if (result === false)
                {
                    $scope.beingSubmitted = false;
                    $scope.tracker.showFormErrors = true;
                }
            });
        }

        $scope.cancelFinish = function() {
            $scope.beingSubmitted = false;
        }

        $scope.showValidationError = function(question_id) {
            return $scope.tracker.showFormErrors && $scope.tracker.isQuestionMandatory(question_id) && !$scope.tracker.isQuestionAnswered(question_id);
        }

        $scope.hasValidationErrors = function() {
            return $scope.tracker.showFormErrors;
        }

        // $scope.isSkipHidden = isSkipHidden;
        $scope.isNextDisabled = isNextDisabled;

        $scope.tracker = surveyTracker;
        $scope.survey_id = $window.survey_preload.survey.id;
        $scope.preview = $window.survey_preload.preview;
        $scope.survey = $window.survey_preload.survey;

        $scope.isSelectedOption = function(questionId, option) {
            return ($scope.tracker.isQuestionAnswered(questionId) && option.isSelected === true)
        };

        window.onbeforeunload = function() {
            return "";
        };

        init();

        /**
         * initialise controller, with routing
         */
        function init() {
            $scope.$on('survey.finish', $scope.cancelFinish);

            angular.element("#survey-wrap").hide();
            questionContainer = angular.element('#questions');

            start();
        }

        /**
         * load survey start
         */
        function start() {
            surveyActions.setPreview($scope.preview);

            // set survey anonymous status
            surveyTracker.setAnonymous($scope.survey.anonymous)

            // attempt to the survey
            surveyActions.start($scope.survey_id, surveyTracker.anonymous, function() {
                $scope.currentSection = surveyTracker.currentSection;
                $scope.optionIndexes = surveyTracker.optionIndexes;

                angular.element('#survey-wrap').show();
            });
        }

        /**
         * Set a selected option.
         *
         * Time taken is not tracked until we move to the next question, so this is set to null.
         *
         * @param {int} option_id
         */
        function toggleOption(question_id, option_id) {
            if ($scope.beingSubmitted)
                return;

            const question = $scope.currentSection.questions.filter(question => question.id === question_id)
            if (question[0].type === 0)    // Radio buttons
            {
                // Make sure all other sibling options are reset as well as setting the new one
                for (var optionIndex in question[0].options) {
                    var option = question[0].options[optionIndex];
                    option.isSelected = option.id === option_id;
                }
            }
            const optionKey = Object.keys(question[0].options).filter(key => question[0].options[key].id === option_id)

            $scope.outstandingRequests++;
            surveyActions.answer($scope.survey_id, question_id, option_id, question[0].options[optionKey]).finally(function() {
                $scope.outstandingRequests--;
            })
        }

        /**
         * Method prepared requests data for multiple options
         *
         * @param questionId
         * @param optionId
         */
        function toggleCheckboxes(questionId, optionId) {
            if ($scope.beingSubmitted)
                return;

            const question = $scope.currentSection.questions.filter(question => question.id === questionId)
            let checkedOptions = Object.keys(question[0].options).filter(option => question[0].options[option].isSelected === true);

            // add/remove actual option_id to array
            if (!checkedOptions.includes(optionId.toString())) {
                checkedOptions.push(optionId.toString())
            } else {
                checkedOptions = checkedOptions.filter(option => option !== optionId.toString())
            }

            $scope.outstandingRequests++;
            surveyActions.answer($scope.survey_id, questionId, optionId, checkedOptions).finally(function() {
                $scope.outstandingRequests--;
            });
        }

        function saveInputText(question, option) {
            if ($scope.beingSubmitted)
                return;

            if (questionTimeouts[question.id] != null)
                clearTimeout(questionTimeouts[question.id]);

            questionTimeouts[question.id] = setTimeout(function(){
                $scope.outstandingRequests++;
                surveyActions.
                answer($scope.survey_id, question.id, option.id, question.answer.properties.response_text).
                finally(function(){$scope.outstandingRequests--;});
                if ($scope.tracker.unansweredMandatoryQuestionsCount() === 0) {
                    $scope.tracker.showFormErrors = false;
                    $scope.$digest();
                }
            }, 200);
        }

        /**
         * Checks if the next button should be disabled or not.
         *
         * @returns {boolean}
         */
        function isNextDisabled() {
            return !!surveyTracker.tracker[surveyTracker.section];
        }

        /**
         * disable previous button when it in first section
         *
         * @returns {boolean}
         */
        function isPrevDisabled() {
            return surveyTracker.trackpos === 0;
        }
    }
}(window));
