'use strict';

require('@progress/telerik-common-report-viewer');
var stringResources = require('./stringResources.js');
var binder = require('./binder.js');
var command = require('./command.js');

var defaultOptions = {};
function replaceStringResources($sendEmailDialog) {
  if (!$sendEmailDialog) {
    return;
  }
  var labels = $sendEmailDialog.find(".trv-replace-string");
  var ariaLabel = $sendEmailDialog.find("[aria-label]").add($sendEmailDialog);
  var titles = $sendEmailDialog.find("[title]");
  var requiredMsg = $sendEmailDialog.find("[data-required-msg]");
  var emailMsg = $sendEmailDialog.find("[data-email-msg]");
  if (labels.length) {
    Array.from(labels).forEach((element) => {
      replaceText($(element));
    });
  }
  if (ariaLabel.length) {
    Array.from(ariaLabel).forEach((element) => {
      replaceAttribute($(element), "aria-label");
    });
  }
  if (titles.length) {
    Array.from(titles).forEach((element) => {
      replaceAttribute($(element), "title");
    });
  }
  if (requiredMsg.length) {
    Array.from(requiredMsg).forEach((element) => {
      replaceAttribute($(element), "data-required-msg");
    });
  }
  if (emailMsg.length) {
    Array.from(emailMsg).forEach((element) => {
      replaceAttribute($(element), "data-email-msg");
    });
  }
}
function replaceText($el) {
  if ($el) {
    $el.text(stringResources.stringResources[$el.text()]);
  }
}
function replaceAttribute($el, attribute) {
  if ($el) {
    $el.attr(attribute, stringResources.stringResources[$el.attr(attribute)]);
  }
}
class SendEmail {
  // #region fields
  // #endregion
  // #region constructor
  constructor(element, options, viewerOptions) {
    this.options = $.extend({}, defaultOptions, options);
    this.viewerOptions = viewerOptions;
    this.element = element;
    this.$element = $(element);
    this.viewerElement = $(`[data-selector='${this.viewerOptions.viewerSelector}']`);
    this.viewer = this.viewerElement.data("telerik_ReportViewer");
    this.controller = this.options.controller;
    this.notificationService = options.notificationService;
    this.initialized = false;
    this.dialogVisible = false;
    this.kendoSendEmailDialog;
    this.inputFrom;
    this.inputTo;
    this.inputCC;
    this.inputSubject;
    this.docFormat;
    this.docFormatEl;
    this.bodyEditorEl;
    this.bodyEditor;
    this.docFormatList;
    this.optionsCommandSet;
    this.windowLocation;
    if (!this.controller) {
      throw "No controller (telerikReporting.ReportViewerController) has been specified.";
    }
    if (!this.notificationService) {
      throw "No notificationService (telerikReporting.NotificationService) has been specified.";
    }
    if (!this.viewerOptions.sendEmail || !this.viewerOptions.sendEmail.enabled) {
      this.viewerElement.find("[data-command='toggleSendEmailDialog']").addClass("send-email-hidden");
      return;
    }
    this.init();
  }
  // #endregion
  // #region methods
  init() {
    if (this.initialized) {
      return;
    }
    replaceStringResources(this.$element);
    this.controller.getDocumentFormats().then((formats) => {
      this.docFormatList = formats;
      this.docFormat?.setDataSource(this.docFormatList);
      if (this.viewerOptions?.sendEmail && this.viewerOptions?.sendEmail.format) {
        this.docFormat?.value(this.viewerOptions.sendEmail.format);
        this.docFormat?.trigger("change");
      }
    });
    this._initDialog();
    this._initInputFields();
    this._attachCommands();
    this._attachEvents();
    this.initialized = true;
  }
  _attachEvents() {
    this.controller.on("beginLoadReport", this.close.bind(this)).on("viewModeChanged", this.close.bind(this));
    this.notificationService.getSendEmailDialogState((event, args) => {
      args.visible = this.dialogVisible;
    }).setSendEmailDialogVisible((event, args) => {
      if (args.visible === true) {
        this.open();
      } else {
        this.close();
      }
    }).setSearchDialogVisible((event, args) => {
      if (args.visible && this.dialogVisible) {
        this.close();
      }
    });
    $(window).on("resize", () => {
      if (this.kendoSendEmailDialog && this.kendoSendEmailDialog.options.visible) {
        this.storeDialogPosition();
        this.adjustDialogPosition();
      }
    });
  }
  open() {
    this.dialogVisible = true;
    this.kendoSendEmailDialog.open();
  }
  close() {
    this.dialogVisible = false;
    if (this.kendoSendEmailDialog && this.kendoSendEmailDialog.options.visible) {
      this.kendoSendEmailDialog.close();
    }
  }
  getBody() {
    return this.bodyEditor ? this.bodyEditor.value() : "";
  }
  _initDialog() {
    this.kendoSendEmailDialog = new kendo.ui.Window(this.element, {
      title: stringResources.stringResources.sendEmailDialogTitle,
      visible: false,
      width: 800,
      minWidth: 350,
      minHeight: 350,
      modal: true,
      close: () => {
        this.storeDialogPosition();
        this.kendoValidator.reset();
      },
      open: () => {
        this.adjustDialogPosition();
      },
      deactivate: () => {
        this.notificationService.setSendEmailDialogVisible({
          visible: false
        });
      },
      activate: () => {
        this.inputFrom.focus();
        setTimeout(() => {
          this.setValidation();
        }, 250);
      }
    });
    this.kendoSendEmailDialog.element.removeClass("trv-send-email-dialog k-hidden");
    this.kendoSendEmailDialog.wrapper.addClass("trv-send-email-dialog");
  }
  _initInputFields() {
    const prefix = this.viewerOptions.viewerSelector;
    this.setAttrs();
    this.inputFrom = new kendo.ui.TextBox(this.element.querySelector(`[name="${prefix}-from"]`), {});
    this.inputTo = new kendo.ui.TextBox(this.element.querySelector(`[name="${prefix}-to"]`), {});
    this.inputCC = new kendo.ui.TextBox(this.element.querySelector(`[name="${prefix}-cc"]`), {});
    this.inputSubject = new kendo.ui.TextBox(this.element.querySelector(`[name="${prefix}-subject"]`), {});
    this.docFormat = new kendo.ui.ComboBox(this.element.querySelector(`[name="${prefix}-format"]`), {
      dataTextField: "localizedName",
      dataValueField: "name",
      dataSource: this.docFormatList || [],
      filter: "startswith",
      dataBound: (event) => {
        event.sender.select(0);
        event.sender.trigger("change");
      }
    });
    this.bodyEditor = new kendo.ui.Editor(this.element.querySelector(`[name="${prefix}-emailBody"]`), {
      tools: [
        "bold",
        "italic",
        "underline",
        "strikethrough",
        "justifyLeft",
        "justifyCenter",
        "justifyRight",
        "justifyFull",
        "insertUnorderedList",
        "insertOrderedList",
        "indent",
        "outdent",
        "createLink",
        "unlink",
        "cleanFormatting",
        "formatting",
        "fontName",
        "fontSize",
        "foreColor",
        "backColor",
        "subscript",
        "superscript"
      ]
    });
    this.setDefaultValues(this.viewerOptions.sendEmail);
    this.kendoValidator = new kendo.ui.Validator(this.element.querySelector(".trv-send-email-fields"), {});
  }
  setAttrs() {
    const prefix = this.viewerOptions.viewerSelector;
    Array.from(this.element.querySelectorAll(".trv-send-email-field input, .trv-send-email-field textarea")).forEach((element) => {
      var attrName = element.getAttribute("name");
      if (attrName === null) {
        return;
      }
      element.setAttribute("id", `${prefix}-${attrName}`);
      element.setAttribute("name", `${prefix}-${attrName}`);
    });
    Array.from(this.element.querySelectorAll(".trv-send-email-label label")).forEach((element) => {
      var attrFor = element.getAttribute("for");
      if (attrFor === null) {
        return;
      }
      element.setAttribute("for", `${prefix}-${attrFor}`);
    });
  }
  storeDialogPosition() {
    var kendoWindow = this.kendoSendEmailDialog.element.parent(".k-window");
    this.windowLocation = kendoWindow.offset();
  }
  adjustDialogPosition() {
    var windowWidth = $(window).innerWidth();
    var windowHeight = $(window).innerHeight();
    var width = this.kendoSendEmailDialog.wrapper.outerWidth(true);
    var height = this.kendoSendEmailDialog.wrapper.outerHeight(true);
    var padding = 10;
    if (!this.windowLocation) {
      this.kendoSendEmailDialog.center();
    } else {
      var left = this.windowLocation.left;
      var top = this.windowLocation.top;
      var right = left + width;
      var bottom = top + height;
      if (right > windowWidth - padding) {
        left = Math.max(padding, windowWidth - width - padding);
        this.kendoSendEmailDialog.setOptions({
          position: {
            left
          }
        });
      }
      if (bottom > windowHeight - padding) {
        top = Math.max(padding, windowHeight - height - padding);
        this.kendoSendEmailDialog.setOptions({
          position: {
            top
          }
        });
      }
    }
  }
  _attachCommands() {
    this.optionsCommandSet = {
      "sendEmail_Cancel": new command.Command(() => {
        this.close();
      }),
      "sendEmail_Send": new command.Command(() => {
        this.sendingEmail();
      })
    };
    binder.Binder.attachCommands(this.$element.find(".trv-send-email-actions"), this.optionsCommandSet, this.viewerOptions);
  }
  sendingEmail(cmd, args) {
    var sendEmailArgs = {
      from: this.inputFrom.value(),
      to: this.inputTo.value(),
      cc: this.inputCC.value(),
      subject: this.inputSubject.value(),
      format: this.docFormat.value(),
      body: this.getBody(),
      deviceInfo: {}
    };
    if (this.validateFields()) {
      this.controller.sendReport(sendEmailArgs);
      this.close();
    }
  }
  setValidation() {
    this.inputFrom.element.off("blur").on("blur", () => {
      if (!this.isEmpty(this.inputFrom)) {
        this.isValidEmail(this.inputFrom, false);
      }
    });
    this.inputTo.element.off("blur").on("blur", () => {
      if (!this.isEmpty(this.inputTo)) {
        this.isValidEmail(this.inputTo, true);
      }
    });
    this.inputCC.element.off("blur").on("blur", () => {
      if (this.inputCC.value().toString().length) {
        this.isValidEmail(this.inputCC, true);
      } else {
        this.hideError(this.inputCC.element);
      }
    });
  }
  validateFields() {
    var fromIsValid = !this.isEmpty(this.inputFrom) && this.isValidEmail(this.inputFrom, false);
    var toIsValid = !this.isEmpty(this.inputTo) && this.isValidEmail(this.inputTo, true);
    var ccIsValid = this.isEmpty(this.inputCC) || this.isValidEmail(this.inputCC, true);
    var hasFormat = this.docFormat.value().length > 0;
    if (!hasFormat) {
      this.showError(this.docFormat.element, "data-required-msg");
    }
    return fromIsValid && toIsValid && ccIsValid && hasFormat;
  }
  /* Sets all default email values except the format as it depends on a request */
  setDefaultValues(sendEmail) {
    this.inputFrom.value(sendEmail && sendEmail.from || "");
    this.inputTo.value(sendEmail && sendEmail.to || "");
    this.inputCC.value(sendEmail && sendEmail.cc || "");
    this.inputSubject.value(sendEmail && sendEmail.subject || "");
    this.bodyEditor.value(sendEmail && sendEmail.body || "");
  }
  isEmpty(input) {
    var $el = input.element;
    if (!input.value().length) {
      this.showError($el, "data-required-msg");
      return true;
    }
    this.hideError($el);
    return false;
  }
  showError($el, tag) {
    var validationMsg = stringResources.stringResources[$el.attr(tag)];
    $('[data-for="' + $el.attr("name") + '"]').addClass("-visible").text(validationMsg);
  }
  hideError($el) {
    $('[data-for="' + $el.attr("name") + '"]').removeClass("-visible");
  }
  isValidEmail(input, moreThenOneEmail) {
    var inputValue = input.value();
    var $el = input.element;
    if (moreThenOneEmail) {
      var listEmailsAddress = inputValue.split(/[\s,;]+/);
      for (var i = 0; i < listEmailsAddress.length; i++) {
        if (!this._validateEmail(listEmailsAddress[i].trim(), $el)) {
          return false;
        }
      }
      return true;
    }
    return this._validateEmail(inputValue, $el);
  }
  _validateEmail(email, $el) {
    var regexEmail = /\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
    if (email.indexOf(",") > -1 || email.indexOf(";") > -1) {
      this.showError($el, "data-single-email-msg");
      return false;
    }
    if (!regexEmail.test(email)) {
      this.showError($el, "data-email-msg");
      return false;
    }
    return true;
  }
}

exports.SendEmail = SendEmail;
