define("ticketControllers",
    [ "SHARED/jquery", "SHARED/uiCalendar", "SHARED/CalDateTimePicker",
        "SHARED/DateTimeFormatter", "SHARED/juzu-ajax", "/commons-extension/ckeditor/ckeditor.js" ], function($,
        timePicker, otherTimePicker, dateFormatter, jz) {
      var ticketCtrl = function($scope, $q, $timeout, $http, $filter, $window) {
        var ticketContainer = $('#ticketAddon');
        var deferred = $q.defer();

        $scope.environments = [];
		$scope.uploadIds = [];
        $scope.newTicket = {};
        $scope.fileUploading = false;
        $scope.submitInProgress = false;
        $scope.locale = eXo.env.portal.language;
        $scope.dateFormat = dateFormatter.masks["isoDate"].replace("mm", "MM")
            + " HH:mm";
        $scope.dateInputFields = [];

        $scope.initForm = function() {
          $scope.newTicket = {};
          $scope.newTicket.environmentId = "" + ($filter('filter')($scope.environments, {defaultEnvironment:true}).length > 0 ? $filter('filter')($scope.environments, {defaultEnvironment:true})[0].id : null);
          $scope.resultMessage='';
          $scope.ticketLink = null;
          $scope.ticketLabel = null;
          $scope.importFiles = null;
          $scope.newTicketForm = null;
          var severity = $scope.getParameterByName('severity');
          var ticketType = $scope.getParameterByName('ticketType');
          if(severity && severity.length > 0){
            $scope.newTicket.severity = severity;
          }
          if(ticketType && ticketType.length > 0){
            $scope.newTicket.type = ticketType;
          }
          $scope.submitInProgress = false;
        }

        $scope.loadBundles = function() {
          $http({
            method : 'GET',
            url : ticketContainer.jzURL('TicketController.getBundle') + "&locale=" + eXo.env.portal.language
          }).then(function successCallback(data) {
            $scope.i18n = data.data;
            deferred.resolve(data);
          }, function errorCallback(data) {
            $scope.setResultMessage($scope.i18n.errorInitForm, "error");
          });
        }

        $scope.newEnvironmentForm = function() {
          var locationHref = window.location.href;
          var relativePath = locationHref.replace(/^(?:\/\/|[^\/]+)*\//, "/");
          var indexOfSemiColon = locationHref.lastIndexOf(":spaces:");
          var indexOfSlash = locationHref.indexOf("/", indexOfSemiColon+1);
          if(indexOfSlash <0) indexOfSlash =  locationHref.length
          var spacePrettyName = eXo.env.portal.selectedNodeUri;
          var indexSlashPrettyName = spacePrettyName.indexOf('/');
          if(indexSlashPrettyName > 0) {
            spacePrettyName = spacePrettyName.substring(0, indexSlashPrettyName);
          }
          var environmentLink = locationHref.substring(0, indexOfSlash) + "/" + spacePrettyName + "/environments?new=true&initURL="
          +encodeURIComponent(relativePath)+"&ticketType="+$scope.newTicket.type+"&severity="+$scope.newTicket.severity;
          window.location.href = environmentLink;
        };

          $scope.updateEnvironmentForm = function() {
              var relativePath = encodeURIComponent(window.location.href.replace(/^(?:\/\/|[^\/]+)*\//, "/"));
              window.location.href = "/portal/g/:spaces:"+ eXo.env.portal.spaceGroup +"/"+ eXo.env.portal.spaceName + "/environments?editEnv="+$scope.newTicket.environmentId+"&initURL="
                  +relativePath+"&ticketType="+$scope.newTicket.type+"&severity="+$scope.newTicket.severity;
          };


          $scope.loadEnvironments = function() {
          $http({
            method : 'GET',
            url : ticketContainer.jzURL('TicketController.getEnvironments')
          }).then(function successCallback(data) {
            $scope.environments = data.data;
            $scope.initForm();
          }, function errorCallback(data) {
            $scope.setResultMessage($scope.i18n.errorInitForm, "error");
          });
        };

        $scope.isOldEnv = function (environmentId) {
            try {
                selectedEnvironment = $scope.environments.filter(function (environment) {
                    return environment.id === environmentId
                })[0];
                return Math.floor((new Date() - selectedEnvironment.updateDate) / (1000 * 3600 * 24)) > 90
            } catch (e) {
                return false;
            }
        };

        $scope.saveTicket = function() {
          $scope.submitInProgress = true;
          $scope.newTicket.description = CKEDITOR.instances.requestDescription.getData();
          if ($scope.newTicket.description.replace('/<[^>]*>/gi', '').length == 0){
             $scope.setCKEditorError($scope.i18n.validateAddDescription,'error');
             return;
          } else {
             $scope.setCKEditorError('','');
          }
          if($scope.newTicket.type == 'PRODUCT'){
            var validateDateMsg = '', startAfterEndDateMsg= '';
             validateDateMsg = $scope.validateDate($scope.newTicket.startDate);
            if (validateDateMsg && validateDateMsg.length > 0){
               $scope.setStartDateError(validateDateMsg,'error');
               return;
            } else {
               $scope.setStartDateError('','');
            }
            validateDateMsg = $scope.validateDate($scope.newTicket.endDate);
            if (validateDateMsg && validateDateMsg.length > 0){
               $scope.setEndDateError(validateDateMsg,'error');
               return;
            }else {
               $scope.setEndDateError('','');
            }
            var startAfterEndDateMsg = $scope.validateEndDate($scope.newTicket.startDate,$scope.newTicket.endDate);
             if (startAfterEndDateMsg && startAfterEndDateMsg.length > 0){
               $scope.setStartAfterEndDateError(startAfterEndDateMsg,'error');
               return;
            } else {
               $scope.setStartAfterEndDateError('','');
            }
            $scope.newTicket.dateFormat = $scope.dateFormat;
          }
          //Append the description field with the Information type
          if($scope.newTicket.type == 'INFORMATION'){
            var descriptionTitle = "<blockquote><b>" + $scope.i18n['request'+$scope.newTicket.infoType+'Prefix'] + ": </b>" + $scope.i18n['request'+$scope.newTicket.infoType] + "</blockquote>";
            $scope.newTicket.description = descriptionTitle + $scope.newTicket.description;
          }

          //Append the environment details
          if($scope.newTicket.type == 'INCIDENT'){
            var environmentBanner = $scope.appendEnvironment($scope.newTicket.environmentId);
            $scope.newTicket.description = $scope.newTicket.description + environmentBanner;
          }

          $scope.newTicket.uploads = $scope.uploadIds;
          $scope.setResultMessage($scope.i18n.savingTicket, "info");
          $http({
            data : $scope.newTicket,
            method : 'POST',
            headers : {
              'Content-Type' : 'application/json'
            },
            url : ticketContainer.jzURL('TicketController.saveTicket')
          }).then(function successCallback(data) {
            if (data && data.data && data.data.link && data.data.label) {
              $scope.ticketLink = data.data.link[0];
              $scope.ticketLabel = data.data.label[0]
            } else {
              $scope.ticketLink = null;
              $scope.ticketLabel = null;
            }
            if($scope.newTicket.type == 'PRODUCT'){
               $scope.setResultMessage($scope.i18n.productQuestionSubmitted, "success");
               $scope.ticketLink = null;
               $scope.ticketLabel = null;
            } else {
               $scope.setResultMessage($scope.i18n.ticketSubmitted, "success");
            }
            $scope.newTicket = null;
            $scope.newTicketForm = null;
            $scope.uploadIds = [];
            for(instance in CKEDITOR.instances ){
              CKEDITOR.instances[instance].updateElement();
              CKEDITOR.instances[instance].setData('');
            }
          }, function errorCallback(data) {
            $scope.setResultMessage($scope.i18n.ticketSubmitionError, "error");
          });
          $window.scrollTo(0, 0);
        }

        // function which set the result message with the given style
        $scope.setResultMessage = function(text, type) {
          $scope.resultMessageClass = "alert-" + type;
          $scope.resultMessageClassExt = "uiIcon"
              + type.charAt(0).toUpperCase() + type.slice(1);
          $scope.resultMessage = text;
        }

        $scope.setCKEditorError = function(text, type) {
          $scope.ckeditorErrorClass = "error";
          $scope.ckeditorErrorMessage = text;
        }
        $scope.setStartDateError = function(text, type) {
          $scope.startDateErrorClass = "error";
          $scope.startDateErrorMessage = text;
        }
        $scope.setEndDateError = function(text, type) {
          $scope.endDateErrorClass = "error";
          $scope.endDateErrorMessage = text;
        }
        $scope.setStartAfterEndDateError = function(text, type) {
          $scope.StartAfterEndDateErrorClass = "error";
          $scope.StartAfterEndDateErrorMessage = text;
        }

        $scope.fileUploadClick = function(element) {
          $scope.$apply(function($scope) {
            $(".ticketAddon input#fileToImport").click();
          });
        };

        $scope.appendEnvironment  = function(environmentId) {
            var environment;
            var elementsCount = 0;
            for ( var i=0, L=$scope.environments.length; i<L; i++ ) {
               if ( $scope.environments[i].id === environmentId ) {
                 environment = $scope.environments[i];
               }
             }
            if(environment){
             var textArray = [];
             //textArray.push("<div class=\"row\" style=\"border-top: dotted 1px #ccc;margin-left : 0px;\"><h5>"+ $scope.i18n.serverEnvironmentDetails + "</h5><div class=\"span4\"><ul>");
             textArray.push("<p class=\"environmenttopbanner\" style=\"border-top: 1px solid #ccc;\"><b>"+ $scope.i18n.serverEnvironmentDetails + "</b><ul>");
             //Environment name
             if(environment.name && environment.name.length > 0){
               textArray.push("<li><b>" + $scope.i18n.name + ": </b>" + environment.name + "</li>");
               elementsCount++;
             }
             //Environment Type
             if(environment.typeName && environment.typeName.length > 0){
               textArray.push("<li><b>" + $scope.i18n.environmentType + ": </b>" + environment.typeName + "</li>");
               elementsCount++;
             }else if(environment.typeOtherName && environment.typeOtherName.length > 0){
                textArray.push("<li><b>" + $scope.i18n.environmentType + ": </b>" + environment.typeOtherName + "</li>");
                elementsCount++;
             }
             // eXo Product Version
             if(environment.productVersion && environment.productVersion.length > 0){
               textArray.push("<li><b>" + $scope.i18n.environmentProductInformation + ": </b>" + environment.productVersion + "</li>");
               elementsCount++;
             }
             // Operating System
             if(environment.osName && environment.osName.length > 0){
                var text = [];
                text.push("<li><b>" + $scope.i18n.environmentOSInformation + ": </b>" + environment.osName);
                if(environment.osVersion && environment.osVersion.length > 0){
                  text.push(" <b>");
                  text.push($scope.i18n.version);
                  text.push(": ");
                  text.push("</b>");
                  text.push(environment.osVersion);
                }
              text.push("</li>");
              textArray.push(text.join(""));
              elementsCount++;
              }else if(environment.osOtherName && environment.osOtherName.length > 0){
              var text = [];
               text.push("<li>");
               text.push("<b>");
               text.push($scope.i18n.environmentOSInformation);
               text.push(": ");
               text.push("</b>");
               text.push(environment.osOtherName);
               if(environment.osVersion && environment.osVersion.length > 0){
                 text.push(" ");
                 text.push("<b>");
                 text.push($scope.i18n.version);
                 text.push(": ");
                 text.push("</b>");
                 text.push(environment.osVersion);
               }
               text.push("</li>");
               textArray.push(text.join(""));
               elementsCount++;
              }
              // Java version
              if(environment.jvmVendorName && environment.jvmVendorName.length > 0){
              var text = [];
              text.push("<li>");
              text.push("<b>");
              text.push($scope.i18n.environmentJavaInformation);
              text.push(": ");
              text.push("</b>");
              text.push(environment.jvmVendorName);
              if(environment.jvmVersion && environment.jvmVersion.length > 0){
                text.push(" ");
                text.push("<b>");
                text.push($scope.i18n.version);
                text.push(": ");
                text.push("</b>");
                text.push(environment.jvmVersion);
              }
              text.push("</li>");
              textArray.push(text.join(""));
              elementsCount++;
              }else if(environment.jvmVendorOtherName && environment.jvmVendorOtherName.length > 0){
               var text = [];
               text.push("<li>");
               text.push("<b>");
               text.push($scope.i18n.environmentJavaInformation);
               text.push(": ");
               text.push("</b>");
               text.push(environment.jvmVendorOtherName);
               if(environment.jvmVersion && environment.jvmVersion.length > 0){
                 text.push(" ");
                 text.push("<b>");
                 text.push($scope.i18n.version);
                 text.push(": ");
                 text.push("</b>");
                 text.push(environment.jvmVersion);
               }
               text.push("</li>");
               textArray.push(text.join(""));
               elementsCount++;
              }
              // Application server
              if(environment.asName && environment.asName.length > 0){
              var text = [];
              text.push("<li>");
              text.push("<b>");
              text.push($scope.i18n.environmentASInformation);
              text.push(": ");
              text.push("</b>");
              text.push(environment.asName);
              if(environment.asVersion && environment.asVersion.length > 0){
                text.push(" ");
                text.push("<b>");
                text.push($scope.i18n.version);
                text.push(": ");
                text.push("</b>");
                text.push(environment.asVersion);
              }
              text.push("</li>");
              textArray.push(text.join(""));
              elementsCount++;
              }else if(environment.asOtherName && environment.asOtherName.length > 0){
              var text = [];
               text.push("<li>");
               text.push("<b>");
               text.push($scope.i18n.environmentASInformation);
               text.push(": ");
               text.push("</b>");
               text.push(environment.asOtherName);
               if(environment.asVersion && environment.asVersion.length > 0){
                 text.push(" ");
                 text.push("<b>");
                 text.push($scope.i18n.version);
                 text.push(": ");
                 text.push("</b>");
                 text.push(environment.asVersion);
               }
               text.push("</li>");
               textArray.push(text.join(""));
               elementsCount++;
              }

              if(environment.dbName && environment.dbName.length > 0){
              var text = [];
              text.push("<li>");
              text.push("<b>");
              text.push($scope.i18n.environmentDBInformation);
              text.push(": ");
              text.push("</b>");
              text.push(environment.dbName);
              if(environment.dbVersion && environment.dbVersion.length > 0){
                text.push(" ");
                text.push("<b>");
                text.push($scope.i18n.version);
                text.push(": ");
                text.push("</b>");
                text.push(environment.dbVersion);
              }
              text.push("</li>");
              textArray.push(text.join(""));
              elementsCount++;
              }else if(environment.dbOtherName && environment.dbOtherName.length > 0){
              var text = [];
               text.push("<li>");
               text.push("<b>");
               text.push($scope.i18n.environmentDBInformation);
               text.push(": ");
               text.push("</b>");
               text.push(environment.dbOtherName);
               if(environment.dbVersion && environment.dbVersion.length > 0){
                 text.push(" ");
                 text.push("<b>");
                 text.push($scope.i18n.version);
                 text.push(": ");
                 text.push("</b>");
                 text.push(environment.dbVersion);
               }
               if(environment.dbEncoding && environment.dbEncoding.length > 0){
                  text.push(" ");
                  text.push("<b>");
                  text.push($scope.i18n.encoding);
                  text.push(": ");
                  text.push("</b>");
                  text.push(environment.dbEncoding);
                }
               text.push("</li>");
               textArray.push(text.join(""));
               elementsCount++;
              }

              if(environment.ssoName && environment.ssoName.length > 0){
              var text = [];
                text.push("<li>");
                text.push("<b>");
                text.push($scope.i18n.environmentSSOInformation);
                text.push(": ");
                text.push("</b>");
                text.push(environment.ssoName);
                if(environment.ssoVersion && environment.ssoVersion.length > 0){
                  text.push(" ");
                  text.push("<b>");
                  text.push($scope.i18n.version);
                  text.push(": ");
                  text.push("</b>");
                  text.push(environment.ssoVersion);
                }
                text.push("</li>");
                textArray.push(text.join(""));
                elementsCount++;
                }else if(environment.ssoOtherName && environment.ssoOtherName.length > 0){
                 var text = [];
                 text.push("<li>");
                 text.push("<b>");
                 text.push($scope.i18n.environmentSSOInformation);
                 text.push(": ");
                 text.push("</b>");
                 text.push(environment.ssoOtherName);
                 if(environment.ssoVersion && environment.ssoVersion.length > 0){
                   text.push(" ");
                   text.push("<b>");
                   text.push($scope.i18n.version);
                   text.push(": ");
                   text.push("</b>");
                   text.push(environment.ssoVersion);
                 }
                 text.push("</li>");
                 textArray.push(text.join(""));
                 elementsCount++;
                }
              if(environment.moreInformation && environment.moreInformation.length > 0){
              var text = [];
              text.push("<li>");
              text.push("<b>");
              text.push($scope.i18n.environmentMoreInformationTitle);
              text.push(": ");
              text.push("</b>");
              text.push(environment.moreInformation);
              text.push("</li>");
              textArray.push(text.join(""));
              elementsCount++;
              }
              //textArray.push("</ul></div></div>");
              textArray.push("</ul></p>");
              //if(textArray && textArray.length > 6){
              //textArray.splice(6, 0, "</ul></div><div class=\"span4\"><ul>");
              //}
              return textArray.join("");
            }
         };

        $scope.uploadFile = function(data) {

          const MAX_RANDOM_NUMBER = 100000;
          const uploadId = Math.round(Math.random() * MAX_RANDOM_NUMBER);

            fetch(`/portal/upload?uploadId=${uploadId}&action=upload`, {
              method: 'POST',
              credentials: 'include',
              body: data
            }).then(response => {
                    $scope.uploadIds.push(uploadId);
                    $scope.fileUploading = false;
             })
        };

        $scope.prepareImportFile = function(element) {
          $scope.importFiles = element.files;
          if (!$scope.importFiles || !$scope.importFiles.length) {
            $scope.importFiles = null;
            $scope.setResultMessage($scope.i18n.noSelectedFile, "error");
            return;
          }

          $(".ticketAddon .uiAction").addClass("resources-loader");
          if($scope.importFiles.length > 3) {
            $scope.importFiles = null;
            $scope.setResultMessage($scope.i18n.validateMaxSelectedFile, "warning");
            return;
          }
		  $scope.fileUploading = true;
          $scope.setResultMessage($scope.i18n.analyzingFile, "info");

          [...$scope.importFiles].forEach((file) => {
              var formData = new FormData();
            formData.append('data', file, file.name);
            $scope.uploadFile(formData)

          });
		  $scope.setResultMessage("", "info");
          $(".ticketAddon .uiAction").removeClass("resources-loader");
        }

        $scope.validateDate = function(txtDate) {
          if (!txtDate) {
            return $scope.i18n.validateAddStartDate;
          }
          if (isNaN(Date.parse(txtDate))) {
            return $scope.i18n.validateStartDateFormat;
          }
        };
        $scope.validateEndDate = function(start,end){
        if (Date.parse(end) <= Date.parse(start)) {
            return $scope.i18n.validateEndAfterStartDates;
          }
        }

        $scope.setDateTimeField = function(inputFieldId) {
          $scope.dateInputFields[$scope.dateInputFields.length] = inputFieldId;
          timePicker.isDisplayTime = true;
          $("#" + inputFieldId).on("change", function(evt) {
            $scope.newTicket[evt.target.id] = evt.target.value;
          });
          timePicker.hideCalendarHandler = function(evt) {
            $scope.refreshController();
            console.log(evt.srcElement.value);
            if (evt.type == "click"
                && $scope.dateInputFields.indexOf(evt.srcElement.id) >= 0) {
              return;
            }
            timePicker.hide();
          }
          $("#" + inputFieldId).focus(
              function() {
                otherTimePicker.isDisplayTime = true;
                timePicker.init(document.getElementById(inputFieldId), true,
                    $scope.dateFormat, "", otherTimePicker.months.toString());
              });
          $("#" + inputFieldId).keyup(function() {
            eXo.webui.UICalendar.show();
          });
          $("#" + inputFieldId).focus(function(event) {
            event.cancelBubble = true;
          });
        }

        $scope.getParameterByName = function (name, url) {
           if (!url) {
             url = window.location.href;
           }
           name = name.replace(/[\[\]]/g, "\\$&");
           var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
               results = regex.exec(url);
           if (!results) return null;
           if (!results[2]) return '';
           return decodeURIComponent(results[2].replace(/\+/g, " "));
        }



        $scope.loadEnvironments();
        $scope.loadBundles();
        $scope.setDateTimeField("startDate");
        $scope.setDateTimeField("endDate");

        CKEDITOR
            .replace(
                'requestDescription',
                {
                  toolbar:'Basic',
                  height : '200px',
                  contentsCss : ['/commons-extension/ckeditor/contents.css'],
                  enterMode : CKEDITOR.ENTER_P,
                  forceEnterMode : false,
                  shiftEnterMode : CKEDITOR.ENTER_BR
                });

        $scope.refreshController = function() {
          try {
            $scope.$apply();
            $scope.$digest();
          } catch (excep) {
            // Nothing here
          }
        };

        $('#ticketAddon').css('visibility', 'visible');
        $(".ticketLoadingBar").remove();
      };
      return ticketCtrl;
    });