import LiteEditor from 'lite-editor';

export const DispatchLiteEditorField = () => {
  const liteEditor = document.querySelectorAll(ACMS.Config.LiteEditorMark);
  [].forEach.call(liteEditor, (item) => {
    if ($(item).hasClass('editing')) {
      return;
    }
    $(item).addClass('editing');
    new LiteEditor(item, ACMS.Config.LiteEditorFieldConf); // eslint-disable-line no-new
  });
};

const moveCursorToEnd = (el) => {
  let range;
  let selection;
  if (document.createRange) {
    range = document.createRange();
    range.selectNodeContents(el);
    range.collapse(false);
    selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);
  } else if (document.selection) {
    range = document.body.createTextRange();
    range.moveToElementText(el);
    range.collapse(false);
    range.select();
  }
};

export default () => {
  const liteEditorLoadPromise = new Promise((resolve) => {
    const loader = new ACMS.SyncLoader();
    if (ACMS.Admin.liteEditorEmojiPicker) {
      resolve();
      return;
    }
    loader.next(`${ACMS.Config.jsRoot}dest/lite-editor-emoji-picker-plugin.js`).load(() => {
      resolve();
    });
  });

  DispatchLiteEditorField();

  ACMS.addListener('acmsAddUnit', (event) => {
    DispatchLiteEditorField();
    if (ACMS.Config.LiteEditorFeature === true) {
      const item = event.obj.item;
      const selectOptions = [];
      const $select = $('.js-extendTagSelect select', item);
      const selectedOption = $select.val();
      const selectName = $select.attr('name');
      const extendValue = $('[name^="text_extend_tag"]', item).val();
      const sourceModeTags = ACMS.Config.LiteEditorSourceModeTags;

      $('.js-extendTagSelect option', item).each(function () {
        const tag = $(this).val();
        const opt = {
          value: tag,
          label: $(this).text(),
          extendLabel: $(this).data('tag_extend')
        };
        if (tag === 'wysiwyg') {
          opt.onSelect = (self) => {
            self.data.mode = 'html';
            self.data.hideBtns = true;
            self.data.showSource = true;
            self.data.disableEditorMode = true;
            self.update();
            ACMS.Dispatch.emoditor(self._getElementByQuery('[data-selector="lite-editor-source"]'));
          };
        } else if (tag === 'markdown') {
          opt.onSelect = (self) => {
            const editor = $(self._getElementByQuery('[data-selector="lite-editor-source"]')).data('emoditor');
            self.data.mode = 'markdown';
            self.data.disableEditorMode = true;
            self.data.hideBtns = false;
            if (editor) {
              self.data.value = editor.getData();
              editor.destroy();
              $(self._getElementByQuery('[data-selector="lite-editor-source"]')).data('emoditor', null);
              self.data.showSource = true;
              self.update();
            } else if (!self.data.showSource) {
              self.data.showSource = true;
              self.update();
              $(self._getElementByQuery('[data-selector="lite-editor-source"]')).show();
            }
          };
        } else if (tag.match(sourceModeTags)) {
          opt.onSelect = (self) => {
            const editor = $(self._getElementByQuery('[data-selector="lite-editor-source"]')).data('emoditor');
            self.data.mode = 'html';
            self.data.disableEditorMode = true;
            self.data.hideBtns = false;
            if (editor) {
              self.data.value = editor.getData();
              editor.destroy();
              $(self._getElementByQuery('[data-selector="lite-editor-source"]')).data('emoditor', null);
              self.data.showSource = true;
              self.update();
            } else if (!self.data.showSource) {
              self.data.showSource = true;
              self.update();
              $(self._getElementByQuery('[data-selector="lite-editor-source"]')).show();
            }
          };
        } else {
          opt.onSelect = (self) => {
            const emoditor = $(self._getElementByQuery('[data-selector="lite-editor-source"]')).data('emoditor');
            if (emoditor) {
              self.data.value = emoditor.getData();
              emoditor.destroy();
              $(self._getElementByQuery('[data-selector="lite-editor-source"]')).data('emoditor', null);
            }
            self.data.showSource = false;
            self.data.mode = 'html';
            self.data.disableEditorMode = false;
            self.data.hideBtns = false;
            self.update();
            self._getElementByQuery('[data-selector="lite-editor"]').innerHTML = self.data.value;
            $('.entryFormLiteEditor', item).show();
          };
        }
        selectOptions.push(opt);
      });
      liteEditorLoadPromise.then(() => {
        $('.entryFormColumnBody', item).not('editing').each(function () {
          const $textarea = $('.entryFormTextarea', this);
          if ($textarea.length === 0) {
            return;
          }
          $(this).addClass('editing');
          const $selector = $("[name^='text_tag']", this);
          const tag = $selector.val();
          let sourceFirst = false;
          $textarea.attr('rows', '1');
          ACMS.Dispatch.Edit._media(item);
          if (tag && tag.match(sourceModeTags)) {
            sourceFirst = true;
          }
          const isMobile = (navigator.userAgent.indexOf('iPhone') > 0 &&
            navigator.userAgent.indexOf('iPad') === -1) ||
            navigator.userAgent.indexOf('iPod') > 0 ||
            navigator.userAgent.indexOf('Android') > 0;

          const liteEditorAry = [];
          $textarea.each((i, textarea) => {
            requestAnimationFrame(() => {
              const btnOptions = [...ACMS.Config.LiteEditorConf.btnOptions];
              if (ACMS.Config.mediaLibrary === 'on') {
                btnOptions.push({
                  label: 'メディア挿入',
                  selfClassName: 'js-media_insert',
                  action: 'extra',
                  onClick(self) {
                    self.saveSelection();
                  }
                });
              }
              if (ACMS.Config.LiteEditorUseEmojiPicker && ACMS.Config.dbCharset === 'utf8mb4') {
                if (!isMobile) {
                  btnOptions.push(new ACMS.Admin.liteEditorEmojiPicker({ // eslint-disable-line new-cap
                    label: ACMS.Config.LiteEditorEmojiPickerLabel
                  }));
                }
              }
              const editorOption = Object.assign({}, ACMS.Config.LiteEditorConf, {
                selectOptions,
                selectedOption,
                selectName,
                extendValue,
                sourceFirst,
                mode: selectedOption === 'markdown' ? 'markdown' : 'html',
              });
              editorOption.btnOptions = btnOptions;
              const editor = new LiteEditor(textarea, editorOption);
              const $editInplace = $(item).parents('#js-edit_inplace-box');
              if ($editInplace.length) {
                const editable = editor._getElementByQuery('[data-selector="lite-editor"]');
                editable.focus();
                moveCursorToEnd(editable);
                editable.addEventListener('keydown', (e) => {
                  if (e.keyCode === 13 && (e.metaKey === true || e.ctrlKey === true)) {
                    $editInplace.find('#js-edit_inplace-submit').click();
                    return false;
                  }
                });
              }

              liteEditorAry.push(editor);
              if (sourceFirst) {
                editor.deactivateEditorMode();
              }
              ACMS.Dispatch.Edit._media(item);
              $(item).data('lite-editor', editor);
              $('.entryFormColumnBody', item).focus();
              $('.js-extendTagSelect', item).remove();
              $('.editTextInsert', item).remove();
            });
          });
          setTimeout(() => {
            $('.lite-editor-select', item).change(function () {
              liteEditorAry.forEach((editor) => {
                // 自身は除外
                if (editor._getElementByQuery('.lite-editor-select') === $(this).get(0)) {
                  return;
                }
                editor.e = {
                  target: {
                    value: $(this).val()
                  }
                };
                editor.changeOption();
              });
            });
            $(item).on('input', '.lite-editor-extend-input', function () {
              liteEditorAry.forEach((editor) => {
                // 自身は除外
                if (editor._getElementByQuery('.lite-editor-select') === $(this).get(0)) {
                  return;
                }
                editor.data.extendValue = $(this).val();
                editor.update();
              });
            });
          }, 100);
        });
      });
    }
  });
};
