define("ticketControllers",
    [ "SHARED/jquery", "SHARED/uiCalendar", "SHARED/CalDateTimePicker",
        "SHARED/DateTimeFormatter", "SHARED/juzu-ajax", "/commons-extension/ckeditor/ckeditor.js" ], function($,
        timePicker, otherTimePicker, dateFormatter, jz) {
        return function ($scope, $q, $timeout, $http, $filter, $window) {
          let ticketContainer = $('#ticketAddon'), 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;
              let severity = $scope.getParameterByName('severity'), 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 () {
              let locationHref = window.location.href, relativePath = locationHref.replace(/^(?:\/\/|[^\/]+)*\//, "/");
              let indexOfSemiColon = locationHref.lastIndexOf(":spaces:"), indexOfSlash = locationHref.indexOf("/", indexOfSemiColon + 1);
              if (indexOfSlash < 0) {
                  indexOfSlash = locationHref.length;
              }
              let spacePrettyName = eXo.env.portal.selectedNodeUri, indexSlashPrettyName = spacePrettyName.indexOf('/');
              if (indexSlashPrettyName > 0) {
                  spacePrettyName = spacePrettyName.substring(0, indexSlashPrettyName);
              }
              window.location.href = locationHref.substring(0, indexOfSlash) + "/" + spacePrettyName + "/environments?new=true&initURL="
                  + encodeURIComponent(relativePath) + "&ticketType=" + $scope.newTicket.type + "&severity=" + $scope.newTicket.severity;
          };

          $scope.updateEnvironmentForm = function () {
              let 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 {
                  let 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') {
                  let 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('', '');
                  }
                  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') {
                  let 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') {
                  let 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 (let 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 () {
                  $(".ticketAddon input#fileToImport").click();
              });
          };

          $scope.appendEnvironment = function (environmentId) {
              let environment;
              for (let i in $scope.environments) {
                  if ($scope.environments[i].id === environmentId) {
                      environment = $scope.environments[i];
                  }
              }
              if (environment) {
                  let textArray = [];
                  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>");
                  }
                  //Environment Type
                  if (environment.typeName && environment.typeName.length > 0) {
                      textArray.push("<li><b>" + $scope.i18n.environmentType + ": </b>" + environment.typeName + "</li>");
                  } else if (environment.typeOtherName && environment.typeOtherName.length > 0) {
                      textArray.push("<li><b>" + $scope.i18n.environmentType + ": </b>" + environment.typeOtherName + "</li>");
                  }
                  // eXo Product Version
                  if (environment.productVersion && environment.productVersion.length > 0) {
                      textArray.push("<li><b>" + $scope.i18n.environmentProductInformation + ": </b>" + environment.productVersion + "</li>");
                  }
                  // Operating System
                  if (environment.osName && environment.osName.length > 0) {
                      let osName = [];
                      osName.push("<li><b>" + $scope.i18n.environmentOSInformation + ": </b>" + environment.osName);
                      if (environment.osVersion && environment.osVersion.length > 0) {
                          osName.push(" <b>");
                          osName.push($scope.i18n.version);
                          osName.push(": ");
                          osName.push("</b>");
                          osName.push(environment.osVersion);
                      }
                      osName.push("</li>");
                      textArray.push(osName.join(""));
                  } else if (environment.osOtherName && environment.osOtherName.length > 0) {
                      let osOtherName = [];
                      osOtherName.push("<li>");
                      osOtherName.push("<b>");
                      osOtherName.push($scope.i18n.environmentOSInformation);
                      osOtherName.push(": ");
                      osOtherName.push("</b>");
                      osOtherName.push(environment.osOtherName);
                      if (environment.osVersion && environment.osVersion.length > 0) {
                          osOtherName.push(" ");
                          osOtherName.push("<b>");
                          osOtherName.push($scope.i18n.version);
                          osOtherName.push(": ");
                          osOtherName.push("</b>");
                          osOtherName.push(environment.osVersion);
                      }
                      osOtherName.push("</li>");
                      textArray.push(osOtherName.join(""));
                  }
                  // Java version
                  if (environment.jvmVendorName && environment.jvmVendorName.length > 0) {
                      let jvmVendorName = [];
                      jvmVendorName.push("<li>");
                      jvmVendorName.push("<b>");
                      jvmVendorName.push($scope.i18n.environmentJavaInformation);
                      jvmVendorName.push(": ");
                      jvmVendorName.push("</b>");
                      jvmVendorName.push(environment.jvmVendorName);
                      if (environment.jvmVersion && environment.jvmVersion.length > 0) {
                          jvmVendorName.push(" ");
                          jvmVendorName.push("<b>");
                          jvmVendorName.push($scope.i18n.version);
                          jvmVendorName.push(": ");
                          jvmVendorName.push("</b>");
                          jvmVendorName.push(environment.jvmVersion);
                      }
                      jvmVendorName.push("</li>");
                      textArray.push(jvmVendorName.join(""));
                  } else if (environment.jvmVendorOtherName && environment.jvmVendorOtherName.length > 0) {
                      let jvmVendorOtherName = [];
                      jvmVendorOtherName.push("<li>");
                      jvmVendorOtherName.push("<b>");
                      jvmVendorOtherName.push($scope.i18n.environmentJavaInformation);
                      jvmVendorOtherName.push(": ");
                      jvmVendorOtherName.push("</b>");
                      jvmVendorOtherName.push(environment.jvmVendorOtherName);
                      if (environment.jvmVersion && environment.jvmVersion.length > 0) {
                          jvmVendorOtherName.push(" ");
                          jvmVendorOtherName.push("<b>");
                          jvmVendorOtherName.push($scope.i18n.version);
                          jvmVendorOtherName.push(": ");
                          jvmVendorOtherName.push("</b>");
                          jvmVendorOtherName.push(environment.jvmVersion);
                      }
                      jvmVendorOtherName.push("</li>");
                      textArray.push(jvmVendorOtherName.join(""));
                  }
                  // Application server
                  if (environment.asName && environment.asName.length > 0) {
                      let asName = [];
                      asName.push("<li>");
                      asName.push("<b>");
                      asName.push($scope.i18n.environmentASInformation);
                      asName.push(": ");
                      asName.push("</b>");
                      asName.push(environment.asName);
                      if (environment.asVersion && environment.asVersion.length > 0) {
                          asName.push(" ");
                          asName.push("<b>");
                          asName.push($scope.i18n.version);
                          asName.push(": ");
                          asName.push("</b>");
                          asName.push(environment.asVersion);
                      }
                      asName.push("</li>");
                      textArray.push(asName.join(""));
                  } else if (environment.asOtherName && environment.asOtherName.length > 0) {
                      let asOtherName = [];
                      asOtherName.push("<li>");
                      asOtherName.push("<b>");
                      asOtherName.push($scope.i18n.environmentASInformation);
                      asOtherName.push(": ");
                      asOtherName.push("</b>");
                      asOtherName.push(environment.asOtherName);
                      if (environment.asVersion && environment.asVersion.length > 0) {
                          asOtherName.push(" ");
                          asOtherName.push("<b>");
                          asOtherName.push($scope.i18n.version);
                          asOtherName.push(": ");
                          asOtherName.push("</b>");
                          asOtherName.push(environment.asVersion);
                      }
                      asOtherName.push("</li>");
                      textArray.push(asOtherName.join(""));
                  }

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

                  if (environment.ssoName && environment.ssoName.length > 0) {
                      let ssoName = [];
                      ssoName.push("<li>");
                      ssoName.push("<b>");
                      ssoName.push($scope.i18n.environmentSSOInformation);
                      ssoName.push(": ");
                      ssoName.push("</b>");
                      ssoName.push(environment.ssoName);
                      if (environment.ssoVersion && environment.ssoVersion.length > 0) {
                          ssoName.push(" ");
                          ssoName.push("<b>");
                          ssoName.push($scope.i18n.version);
                          ssoName.push(": ");
                          ssoName.push("</b>");
                          ssoName.push(environment.ssoVersion);
                      }
                      ssoName.push("</li>");
                      textArray.push(ssoName.join(""));
                  } else if (environment.ssoOtherName && environment.ssoOtherName.length > 0) {
                      let ssoOtherName = [];
                      ssoOtherName.push("<li>");
                      ssoOtherName.push("<b>");
                      ssoOtherName.push($scope.i18n.environmentSSOInformation);
                      ssoOtherName.push(": ");
                      ssoOtherName.push("</b>");
                      ssoOtherName.push(environment.ssoOtherName);
                      if (environment.ssoVersion && environment.ssoVersion.length > 0) {
                          ssoOtherName.push(" ");
                          ssoOtherName.push("<b>");
                          ssoOtherName.push($scope.i18n.version);
                          ssoOtherName.push(": ");
                          ssoOtherName.push("</b>");
                          ssoOtherName.push(environment.ssoVersion);
                      }
                      ssoOtherName.push("</li>");
                      textArray.push(ssoOtherName.join(""));
                  }
                  if (environment.moreInformation && environment.moreInformation.length > 0) {
                      let moreInformation = [];
                      moreInformation.push("<li>");
                      moreInformation.push("<b>");
                      moreInformation.push($scope.i18n.environmentMoreInformationTitle);
                      moreInformation.push(": ");
                      moreInformation.push("</b>");
                      moreInformation.push(environment.moreInformation);
                      moreInformation.push("</li>");
                      textArray.push(moreInformation.join(""));
                  }
                  textArray.push("</ul></p>");
                  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) => {
                  let 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, "\\$&");
              let 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();
      };
    });