(function ($, document, PP_Checklists) {
  'use strict';

  $(function () {
    var $prohibitedWordsElements = $('[id^="pp-checklists-req-prohibited_words"]');

    if ($prohibitedWordsElements.length === 0) {
      return;
    }

    function getRequirementConfig(requirementId) {
      if (typeof objectL10n_checklist_requirements === 'undefined') {
        return null;
      }

      return objectL10n_checklist_requirements.requirements[requirementId]
        || objectL10n_checklist_requirements.requirements.prohibited_words
        || null;
    }

    function getTextContent(content) {
      return $('<div>').html(content || '').text();
    }

    function escapeRegExp(text) {
      return String(text).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    }

    function buildPattern(word) {
      var prefix = /^[A-Za-z0-9_]/.test(word) ? '(^|[^A-Za-z0-9_])' : '';
      var suffix = /[A-Za-z0-9_]$/.test(word) ? '(?=$|[^A-Za-z0-9_])' : '';

      return new RegExp(prefix + '(' + escapeRegExp(word) + ')' + suffix, 'i');
    }

    function containsProhibitedWord(text, words) {
      for (var i = 0; i < words.length; i++) {
        if (buildPattern(words[i]).test(text)) {
          return true;
        }
      }

      return false;
    }

    function updateRequirementStatus(text) {
      var normalizedText = getTextContent(text);

      $prohibitedWordsElements.each(function () {
        var $element = $(this);
        var requirementId = $element.attr('id').replace('pp-checklists-req-', '');
        var config = getRequirementConfig(requirementId);
        var words = config && $.isArray(config.value) ? config.value : [];
        var status = true;

        if (words.length > 0) {
          status = !containsProhibitedWord(normalizedText, words);
        }

        $element.trigger(PP_Checklists.EVENT_UPDATE_REQUIREMENT_STATE, status);
      });
    }

    if (PP_Checklists.is_gutenberg_active()) {
      var debouncedUpdate = _.debounce(function () {
        var content = PP_Checklists.getEditor().getEditedPostAttribute('content');

        if (typeof content !== 'undefined') {
          updateRequirementStatus(content);
        }
      }, 250);

      wp.data.subscribe(debouncedUpdate);
      debouncedUpdate();

      return;
    }

    var $content = $('#content');
    var editor;

    function updateClassicEditor() {
      var text;

      if (typeof editor === 'undefined' || !editor || editor.isHidden()) {
        text = $content.val();
      } else {
        text = editor.getContent({ format: 'raw' });
      }

      updateRequirementStatus(text);
    }

    $(document).on(PP_Checklists.EVENT_TINYMCE_LOADED, function (event, tinymce) {
      editor = tinymce.editors.content;

      if (typeof editor !== 'undefined') {
        editor.onInit.add(function () {
          if (editor.id !== 'content') {
            return;
          }

          editor.on('nodechange keyup', _.debounce(updateClassicEditor, 200));
        });
      }
    });

    $content.on('input keyup', _.debounce(updateClassicEditor, 200));
    updateClassicEditor();
  });
})(jQuery, document, PP_Checklists);
