import template from './ws-modal.tmpl.html';

ModalService.$inject = [
  '$sce',
  '$q',
  '$log',
  '$timeout',
  '$rootScope',
  '$compile',
  '$document',
  '$animate',
  '$controller',
];

export default function ModalService(
  $sce,
  $q,
  $log,
  $timeout,
  $rootScope,
  $compile,
  $document,
  $animate,
  $controller,
) {
  let element = null;
  let scope = null;
  let actionCallback = null;
  let dismissCallback = null;

  function open(properties) {
    if (isOpen()) {
      $log.warn('Called wsModalService.open but modal is already open.');
      return $q.when();
    }
    element = angular.element(template);
    scope = $rootScope.$new();
    scope.bodyString = $sce.trustAsHtml(properties.bodyString);
    scope.checkboxString = $sce.trustAsHtml(properties.checkboxString);
    scope.actionString = $sce.trustAsHtml(properties.actionString);
    scope.actionInProgressString = $sce.trustAsHtml(properties.actionInProgressString);
    scope.dismissString = $sce.trustAsHtml(properties.dismissString);
    scope.actionInProgress = false;
    scope.checkboxModel = {
      isChecked: false,
    };
    scope.modalCtrl = $controller('wsModalController', { $scope: scope });
    actionCallback = properties.action;
    dismissCallback = properties.dismiss;

    $compile(element)(scope);
    $document.on('keydown', handleKeydownEvent);
    element.on('click', handleClickEvent);
    return $animate.enter(element, $document[0].body);
  }

  function action() {
    scope.actionInProgress = true;
    if (actionCallback) {
      return actionCallback(close, rejectClose);
    }

    return close();
  }

  function close() {
    if (!isOpen()) {
      $log.warn('Called wsModalService.close but modal is already closed.');
      return $q.when();
    }
    $document.off('keydown', handleKeydownEvent);
    element.off('click', handleClickEvent);
    scope.actionInProgress = false;
    scope.$destroy();
    scope = null;
    element.remove();
    element = null;
    actionCallback = null;
    dismissCallback = null;
    return $q.when();
  }

  function rejectClose() {
    $timeout(() => {
      scope.actionInProgress = false;
    }, 0);
  }

  function dismiss() {
    if (dismissCallback) {
      dismissCallback();
    }
    return close();
  }

  function isOpen() {
    return !!element;
  }

  function handleKeydownEvent(event) {
    // Dismiss if "Esc" key is clicked.
    if (event.keyCode === 27) {
      dismiss();
    }
  }

  function handleClickEvent(event) {
    // Dismiss if anywhere on the modal backdrop is clicked, but not if
    // the modal itself is clicked.
    if (event.target.classList.contains('ws-modal-container')) {
      dismiss();
    }
  }

  return { open, action, dismiss, isOpen };
}
