text: export default ['$filter', '$state', '$stateParams', 'Wait', '$scope', 'moment',
  '$rootScope', '$http', 'CreateSelect2', 'ParseTypeChange', 'ParentObject', 'ProcessErrors', 'Rest',
  'GetBasePath', 'SchedulerInit', 'SchedulePost', 'JobTemplateModel', '$q', 'Empty', 'PromptService', 'RRuleToAPI',
  'WorkflowJobTemplateModel', 'TemplatesStrings', 'scheduleResolve', 'timezonesResolve',
  function($filter, $state, $stateParams, Wait, $scope, moment,
      $rootScope, $http, CreateSelect2, ParseTypeChange, ParentObject, ProcessErrors, Rest,
      GetBasePath, SchedulerInit, SchedulePost, JobTemplate, $q, Empty, PromptService, RRuleToAPI,
      WorkflowJobTemplate, TemplatesStrings, scheduleResolve, timezonesResolve
  ) {
  
      let schedule, scheduler, scheduleCredentials = [];
  
      $scope.preventCredsWithPasswords = true;
  
      // initial end @ midnight values
      $scope.schedulerEndHour = "00";
      $scope.schedulerEndMinute = "00";
      $scope.schedulerEndSecond = "00";
      $scope.parentObject = ParentObject;
      $scope.isEdit = true;
      $scope.hideForm = true;
      $scope.parseType = 'yaml';
  
      $scope.strings = TemplatesStrings;
  
      $scope.processSchedulerEndDt = function(){
          // set the schedulerEndDt to be equal to schedulerStartDt + 1 day @ midnight
          var dt = new Date($scope.schedulerUTCTime);
          // increment date by 1 day
          dt.setDate(dt.getDate() + 1);
          var month = $filter('schZeroPad')(dt.getMonth() + 1, 2),
              day = $filter('schZeroPad')(dt.getDate(), 2);
          $scope.$parent.schedulerEndDt = month + '/' + day + '/' + dt.getFullYear();
      };
  
      $scope.formCancel = function() {
          $state.go("^");
      };
  
      /*
       * This is a workaround for the angular-scheduler library inserting `ll` into fields after an
       * invalid entry and never unsetting them. Presumably null is being truncated down to 2 chars
       * in that case.
       *
       * Because this same problem exists in the edit mode and because there's no inheritence, this
       * block of code is duplicated in both add/edit controllers pending a much needed broader
       * refactoring effort.
       */
      $scope.timeChange = () => {
          if (!Number($scope.schedulerStartHour)) {
              $scope.schedulerStartHour = '00';
          }
  
          if (!Number($scope.schedulerStartMinute)) {
              $scope.schedulerStartMinute = '00';
          }
  
          if (!Number($scope.schedulerStartSecond)) {
              $scope.schedulerStartSecond = '00';
          }
  
          $scope.scheduleTimeChange();
      };
  
      $scope.saveSchedule = function() {
          schedule.extra_data = $scope.extraVars;
          SchedulePost({
              scope: $scope,
              url: GetBasePath('schedules') + parseInt($stateParams.schedule_id) + '/',
              scheduler: scheduler,
              mode: 'edit',
              schedule: schedule,
              promptData: $scope.promptData,
              priorCredentials: scheduleCredentials
          }).then(() => {
              Wait('stop');
              $state.go("^", null, {reload: true});
          });
      };
  
      $scope.prompt = () => {
          $scope.promptData.triggerModalOpen = true;
      };
  
      var callSelect2 = function() {
          CreateSelect2({
              element: '.MakeSelect2',
              multiple: false
          });
          $("#schedulerTimeZone").select2({
              width:'100%',
              containerCssClass: 'Form-dropDown',
              placeholder: 'SEARCH'
          });
      };
  
      $scope.$on("updateSchedulerSelects", function() {
          callSelect2();
      });
  
      let previewList = _.debounce(function(req) {
          $http.post('/api/v2/schedules/preview/', {'rrule': req})
              .then(({data}) => {
                  $scope.preview_list = data;
                  let parsePreviewList = (tz) => {
                      return data[tz].map(function(date) {
                          date = date.replace(/Z/, '');
                          return moment.parseZone(date).format("MM-DD-YYYY HH:mm:ss");
                      });
                  };
                  for (let tz in data) {
                      $scope.preview_list.isEmpty = data[tz].length === 0;
                      $scope.preview_list[tz] = parsePreviewList(tz);
                  }
              });
      }, 300);
  
      $scope.$on("setPreviewPane", (event) => {
          let rrule = event.currentScope.rrule.toString();
          let req = RRuleToAPI(rrule, $scope);
          previewList(req);
      });
  
      Wait('start');
  
      //sets the timezone dropdown to the timezone specified by the API
      function setTimezone () {
          $scope.schedulerTimeZone = _.find($scope.timeZones, function(x) {
              return x.name === scheduleResolve.timezone;
          });
      }
  
      // sets the UNTIL portion of the schedule form after the angular-scheduler
      // sets it, but this function reads the 'until' key/value pair directly
      // from the schedule GET response.
      function setUntil (scheduler) {
          let { until } = scheduleResolve;
          if(until !== ''){
              const date = moment(until);
              const endDt =  moment.parseZone(date).format("MM/DD/YYYY");
              const endHour = date.format('HH');
              const endMinute = date.format('mm');
              const endSecond = date.format('ss');
              scheduler.scope.schedulerEndDt = endDt;
              scheduler.scope.schedulerEndHour = endHour;
              scheduler.scope.schedulerEndMinute = endMinute;
              scheduler.scope.schedulerEndSecond = endSecond;
          }
      }
  
      function init() {
          schedule = scheduleResolve;
  
          try {
              schedule.extra_data = JSON.parse(schedule.extra_data);
          } catch(e) {
              // do nothing
          }
  
          $scope.extraVars = (scheduleResolve.extra_data === '' || _.isEmpty(scheduleResolve.extra_data)) ? '---' : '---\n' + jsyaml.safeDump(scheduleResolve.extra_data);
  
          if (_.has(schedule, 'summary_fields.unified_job_template.unified_job_type') &&
              schedule.summary_fields.unified_job_template.unified_job_type === 'system_job'){
              $scope.cleanupJob = true;
          }
  
          $scope.schedule_obj = scheduleResolve;
  
          $('#form-container').empty();
          scheduler = SchedulerInit({ scope: $scope, requireFutureStartTime: false });
  
          scheduler.scope.timeZones = timezonesResolve;
          setTimezone();
  
          scheduler.inject('form-container', false);
          scheduler.injectDetail('occurrences', false);
  
          if (!/DTSTART/.test(schedule.rrule)) {
              schedule.rrule += ";DTSTART=" + schedule.dtstart.replace(/\.\d+Z$/,'Z');
          }
          schedule.rrule = schedule.rrule.replace(/ RRULE:/,';');
          schedule.rrule = schedule.rrule.replace(/DTSTART:/,'DTSTART=');
          $scope.$on("htmlDetailReady", function() {
              scheduler.setRRule(schedule.rrule);
              scheduler.setName(schedule.name);
              setTimezone();
              setUntil(scheduler);
              $scope.hideForm = false;
  
              $scope.$watchGroup(["schedulerName",
                  "schedulerStartDt",
                  "schedulerStartHour",
                  "schedulerStartMinute",
                  "schedulerStartSecond",
                  "schedulerTimeZone",
                  "schedulerFrequency",
                  "schedulerInterval",
                  "monthlyRepeatOption",
                  "monthDay",
                  "monthlyOccurrence",
                  "monthlyWeekDay",
                  "yearlyRepeatOption",
                  "yearlyMonth",
                  "yearlyMonthDay",
                  "yearlyOccurrence",
                  "yearlyWeekDay",
                  "yearlyOtherMonth",
                  "schedulerEnd",
                  "schedulerOccurrenceCount",
                  "schedulerEndDt",
                  "schedulerEndHour",
                  "schedulerEndMinute",
                  "schedulerEndSecond"
              ], function() {
                  $rootScope.$broadcast("loadSchedulerDetailPane");
              }, true);
  
              $scope.$watch("weekDays", function() {
                  $rootScope.$broadcast("loadSchedulerDetailPane");
              }, true);
  
              $rootScope.$broadcast("loadSchedulerDetailPane");
              Wait('stop');
          });
  
          $scope.showRRuleDetail = false;
          scheduler.setRRule(schedule.rrule);
          scheduler.setName(schedule.name);
          $rootScope.breadcrumb.schedule_name = $scope.schedulerName;
          $rootScope.breadcrumb[`${$scope.parentObject.type}_name`] = $scope.parentObject.name;
          $scope.noVars = true;
          scheduler.scope.timeZones = timezonesResolve;
          scheduler.scope.schedulerTimeZone = scheduleResolve.timezone;
          if ($scope.cleanupJob){
              $scope.schedulerPurgeDays = Number(schedule.extra_data.days);
          }
  
          if ($state.current.name === 'templates.editJobTemplate.schedules.edit' || $scope.parentObject.type === 'job_template'){
  
              let jobTemplate = new JobTemplate();
  
              Rest.setUrl(scheduleResolve.related.credentials);
  
              $q.all([jobTemplate.optionsLaunch(ParentObject.id), jobTemplate.getLaunch(ParentObject.id), Rest.get()])
                  .then((responses) => {
                      let launchOptions = responses[0].data,
                          launchConf = responses[1].data;
  
                      scheduleCredentials = responses[2].data.results;
  
                      let watchForPromptChanges = () => {
                          let promptValuesToWatch = [
                              'promptData.prompts.inventory.value',
                              'promptData.prompts.jobType.value',
                              'promptData.prompts.verbosity.value',
                              'missingSurveyValue'
                          ];
  
                          $scope.$watchGroup(promptValuesToWatch, function() {
                              let missingPromptValue = false;
                              if ($scope.missingSurveyValue) {
                                  missingPromptValue = true;
                              } else if (!$scope.promptData.prompts.inventory.value || !$scope.promptData.prompts.inventory.value.id) {
                                  missingPromptValue = true;
                              }
                              $scope.promptModalMissingReqFields = missingPromptValue;
                          });
                      };
  
                      let prompts = PromptService.processPromptValues({
                          launchConf: responses[1].data,
                          launchOptions: responses[0].data,
                          currentValues: scheduleResolve
                      });
  
                      let defaultCredsWithoutOverrides = [];
  
                      const credentialHasScheduleOverride = (templateDefaultCred) => {
                          let credentialHasOverride = false;
                          scheduleCredentials.forEach((scheduleCred) => {
                              if (templateDefaultCred.credential_type === scheduleCred.credential_type) {
                                  if (
                                      (!templateDefaultCred.vault_id && !scheduleCred.inputs.vault_id) ||
                                      (templateDefaultCred.vault_id && scheduleCred.inputs.vault_id && templateDefaultCred.vault_id === scheduleCred.inputs.vault_id)
                                  ) {
                                      credentialHasOverride = true;
                                  }
                              }
                          });
  
                          return credentialHasOverride;
                      };
  
                      if (_.has(launchConf, 'defaults.credentials')) {
                          launchConf.defaults.credentials.forEach((defaultCred) => {
                              if (!credentialHasScheduleOverride(defaultCred)) {
                                  defaultCredsWithoutOverrides.push(defaultCred);
                              }
                          });
                      }
  
                      prompts.credentials.value = defaultCredsWithoutOverrides.concat(scheduleCredentials);
  
                      if (launchConf.ask_variables_on_launch) {
                          // the extra vars codemirror is ONLY shown if the
                          // schedule is for a JT and the JT has
                          // ask_variables_on_launch = true.
                          $scope.extraVars = ParentObject.extra_vars === '' ? '---' : ParentObject.extra_vars;
                          $scope.noVars = false;
                          ParseTypeChange({
                              scope: $scope,
                              variable: 'extraVars',
                              parse_variable: 'parseType',
                              field_id: 'SchedulerForm-extraVars'
                          });
                      } else {
                          $scope.noVars = true;
                      }
  
                      if (!launchConf.survey_enabled &&
                          !launchConf.ask_inventory_on_launch &&
                          !launchConf.ask_credential_on_launch &&
                          !launchConf.ask_verbosity_on_launch &&
                          !launchConf.ask_job_type_on_launch &&
                          !launchConf.ask_limit_on_launch &&
                          !launchConf.ask_tags_on_launch &&
                          !launchConf.ask_skip_tags_on_launch &&
                          !launchConf.ask_diff_mode_on_launch &&
                          !launchConf.survey_enabled &&
                          !launchConf.credential_needed_to_start &&
                          !launchConf.inventory_needed_to_start &&
                          launchConf.passwords_needed_to_start.length === 0 &&
                          launchConf.variables_needed_to_start.length === 0) {
                              $scope.showPromptButton = false;
                      } else {
                          $scope.showPromptButton = true;
  
                          // Ignore the fact that variables might be promptable on launch
                          // Promptable variables will happen in the schedule form
                          launchConf.ignore_ask_variables = true;
  
                          if (launchConf.ask_inventory_on_launch && !_.has(launchConf, 'defaults.inventory') && !_.has(scheduleResolve, 'summary_fields.inventory')) {
                              $scope.promptModalMissingReqFields = true;
                          }
  
                          if (responses[1].data.survey_enabled) {
                              // go out and get the survey questions
                              jobTemplate.getSurveyQuestions(ParentObject.id)
                                  .then((surveyQuestionRes) => {
  
                                      let processed = PromptService.processSurveyQuestions({
                                          surveyQuestions: surveyQuestionRes.data.spec,
                                          extra_data: _.cloneDeep(scheduleResolve.extra_data)
                                      });
  
                                      $scope.missingSurveyValue = processed.missingSurveyValue;
  
                                      $scope.extraVars = (processed.extra_data === '' || _.isEmpty(processed.extra_data)) ? '---' : '---\n' + jsyaml.safeDump(processed.extra_data);
  
                                      ParseTypeChange({
                                          scope: $scope,
                                          variable: 'extraVars',
                                          parse_variable: 'parseType',
                                          field_id: 'SchedulerForm-extraVars',
                                          readOnly: !$scope.schedule_obj.summary_fields.user_capabilities.edit
                                      });
  
                                      $scope.promptData = {
                                          launchConf: launchConf,
                                          launchOptions: launchOptions,
                                          prompts: prompts,
                                          surveyQuestions: surveyQuestionRes.data.spec,
                                          template: ParentObject.id
                                      };
  
                                      $scope.$watch('promptData.surveyQuestions', () => {
                                          let missingSurveyValue = false;
                                          _.each($scope.promptData.surveyQuestions, (question) => {
                                              if (question.required && (Empty(question.model) || question.model === [])) {
                                                  missingSurveyValue = true;
                                              }
                                          });
                                          $scope.missingSurveyValue = missingSurveyValue;
                                      }, true);
  
                                      watchForPromptChanges();
                                  });
                          } else {
                              $scope.promptData = {
                                  launchConf: launchConf,
                                  launchOptions: launchOptions,
                                  prompts: prompts,
                                  template: ParentObject.id
                              };
                              watchForPromptChanges();
                          }
                      }
                  });
          } else if ($state.current.name === 'templates.editWorkflowJobTemplate.schedules.edit' || $scope.parentObject.type === 'workflow_job_template') {
              let workflowJobTemplate = new WorkflowJobTemplate();
  
              $q.all([workflowJobTemplate.optionsLaunch(ParentObject.id), workflowJobTemplate.getLaunch(ParentObject.id)])
                  .then((responses) => {
                      let launchOptions = responses[0].data,
                          launchConf = responses[1].data;
  
                      let watchForPromptChanges = () => {
                          $scope.$watch('missingSurveyValue', function() {
                              $scope.promptModalMissingReqFields = $scope.missingSurveyValue ? true : false;
                          });
                      };
  
                      let prompts = PromptService.processPromptValues({
                          launchConf: responses[1].data,
                          launchOptions: responses[0].data,
                          currentValues: scheduleResolve
                      });
  
                      if(!launchConf.survey_enabled) {
                          $scope.showPromptButton = false;
                      } else {
                          $scope.showPromptButton = true;
  
                          if(responses[1].data.survey_enabled) {
                              // go out and get the survey questions
                              workflowJobTemplate.getSurveyQuestions(ParentObject.id)
                                  .then((surveyQuestionRes) => {
  
                                      let processed = PromptService.processSurveyQuestions({
                                          surveyQuestions: surveyQuestionRes.data.spec,
                                          extra_data: _.cloneDeep(scheduleResolve.extra_data)
                                      });
  
                                      $scope.missingSurveyValue = processed.missingSurveyValue;
  
                                      $scope.promptData = {
                                          launchConf: launchConf,
                                          launchOptions: launchOptions,
                                          prompts: prompts,
                                          surveyQuestions: surveyQuestionRes.data.spec,
                                          template: ParentObject.id
                                      };
  
                                      $scope.$watch('promptData.surveyQuestions', () => {
                                          let missingSurveyValue = false;
                                          _.each($scope.promptData.surveyQuestions, (question) => {
                                              if(question.required && (Empty(question.model) || question.model === [])) {
                                                  missingSurveyValue = true;
                                              }
                                          });
                                          $scope.missingSurveyValue = missingSurveyValue;
                                      }, true);
  
                                      watchForPromptChanges();
                                  });
                          }
                          else {
                              $scope.promptData = {
                                  launchConf: launchConf,
                                  launchOptions: launchOptions,
                                  prompts: prompts,
                                  template: ParentObject.id
                              };
                              watchForPromptChanges();
                          }
                      }
                  });
  
          }
      }
  
      init();
  
      callSelect2();
  }];
  