(function ($) {

  window.initPDGrapes = function (patterns, tabIdentifier) {

    Twig.extendFilter('render', function (value) {
      if (value && typeof value == 'object') {
        return value[0];
      }
      return value;
    });

    Twig.extendFilter('t', function (value) {
      return Drupal.t(value);
    });

    Twig.extendFunction('custom_function', function (functionName, args) {
      return window.TwigFunctions[functionName](args)
    });

    $('[data-gjs-type="container"] *').each(function () {
      $(this).html($(this).html().trim());
    });

    $(drupalSettings.pagedesigner.editor_dom_element).attr('id', 'gjs');

    $('[data-entity-id]').each(function () {
      $(this).attr('id', 'pd-cp-' + $(this).attr('data-entity-id'));
    });

    if (!window.grapes_plugins) {
      window.grapes_plugins = [];
    }

    if (!window.grapes_plugin_options) {
      window.grapes_plugin_options = {};
    }

    grapes_plugins.push('grapesjs-pd-base');

    grapes_plugin_options['grapesjs-pd-base'] = {
      patterns: patterns
    };

    window.classes = {};

    var stylesheets = [];
    // load stylesheets into canvas iframe and attach body classes
    document.querySelectorAll("link[rel=stylesheet]:not([media=print])").forEach(function (css_file) {
      stylesheets.push(css_file.href);
    });



    var cssRules = [];
    $('[data-gjs-type="container"]').each(function () {
      $styleTag = $('style[data-pagedesigner-container="' + $(this).data('entity-id') + '"]');
      let stylsheet = Array.from(document.styleSheets).filter(sheet => sheet.ownerNode == $styleTag[0]);

      if (stylsheet.length) {
        Array.from(stylsheet[0].cssRules).forEach(function (rule) {

          if (rule.media && rule.cssRules) {
            Array.from(rule.cssRules).forEach(function (mediaRule) {
              if (mediaRule.styleMap && mediaRule.styleMap.size) {
                let ruleStyle = {};
                for (let i = 0; i < mediaRule.styleMap.size; i++) {
                  ruleStyle[mediaRule.style.item(i)] = mediaRule.style.getPropertyValue(mediaRule.style.item(i));
                }
                cssRules.push({
                  'selectors': [mediaRule.selectorText],
                  'style': ruleStyle,
                  'mediaText': rule.media.mediaText
                });
              }
            });
          }

          if (rule.styleMap && rule.styleMap.size) {
            let ruleStyle = {};
            for (let i = 0; i < rule.styleMap.size; i++) {
              ruleStyle[rule.style.item(i)] = rule.style.getPropertyValue(rule.style.item(i));
            }

            cssRules.push({
              'selectors': [rule.selectorText],
              'style': ruleStyle
            });
          }
        });
        $styleTag.remove();
      }
    });

    // user this event to add further grapesJS plugins
    $(document).trigger('pagedesigner-before-setup');

    // launch grapes with necessary options
    var editor = grapesjs.init({

      height: '100vh',
      showOffsets: 1,
      noticeOnUnload: 0,
      multipleSelection: false,
      avoidInlineStyle: true,
      storageManager: {
        autoload: 0,
      },
      container: '#gjs',
      fromElement: true,

      style: cssRules,

      canvas: {
        styles: stylesheets,
      },

      domComponents: {
        wrapper: {
          components: [],
          badgable: false,
          copyable: false,
          droppable: false,
          highlightable: false,
          hoverable: false,
          selectable: false,
          editable: false,
          propagate: ['editable', 'dropable'],
        }
      },

      deviceManager: {
        devices: [
          {
            name: 'Desktop',
            key: 'large',
            width: ''
          },
          {
            name: 'Tablet',
            width: '769px',
            key: 'medium',
            widthMedia: '992px'
          },
          {
            name: 'Mobile portrait',
            key: 'small',
            width: '320px',
            widthMedia: '768px'
          }
        ]
      },

      traitManager: {
        labelContainer: Drupal.t('Edit component content'),
        textNoElement: Drupal.t('Select an element before editing.')
      },

      blockManager: {
        labelContainer: Drupal.t('Components'),
      },

      assetManager: {
        upload: 'https://localhost/assets/upload',
        uploadFile: (e) => {
          var files = e.dataTransfer ? e.dataTransfer.files : e.target.files;
          var items = e.dataTransfer ? e.dataTransfer.items : e.target.items;
          var types = editor.AssetManager.getTypes();
          var promises = [];
          var num_of_files = 0;
          for (var x = 0; x < types.length; x++) {
            for (var y = 0; y < files.length; y++) {
              var detection = types[x].isType(files[y]);
              if (typeof detection == 'object' && detection.type == types[x].id) {
                var promise = types[x].upload(files[y]);
                promises.push(promise);
                num_of_files++;

                promise.done(function () {
                  window.asset_upload.files_uploaded++;
                  $('[data-upload-progress]').html('<p>Uploaded <strong>' + window.asset_upload.files_uploaded + '</strong> files of ' + window.asset_upload.files_total + '. <i class="fas fa-spinner fa-spin"></i></p><progress value="' + window.asset_upload.files_uploaded + '" max="' + window.asset_upload.files_total + '"></progress>');
                  $('.gjs-am-assets-header form .form-actions .form-submit').click();
                });

              }
            }
          }

          window.asset_upload = {
            files_total: num_of_files,
            files_uploaded: 0
          };

          $('.gjs-asset-manager').append('<div class="upload-progress-wrapper" data-upload-wrapper><div class="upload-progress" data-upload-progress><p>' + Drupal.t('Preparing the upload of <strong>%num</strong> files.').replace('%num', window.asset_upload.files_total) + ' <i class="fas fa-spinner fa-spin"></i></p><progress value="0" max="' + window.asset_upload.files_total + '"></progress></div></div>');

          $.when(...promises)
            .done(function () {
              $('[data-upload-progress]').html('<p>' + Drupal.t('Upload complete, uploaded <strong>%num</strong> files').replace('%num', window.asset_upload.files_total) + '</p>');
              setTimeout(function () { $('[data-upload-wrapper]').remove() }, 2000);
            })
            .fail(function () {
              alert(Drupal.t('Upload error'));
              setTimeout(function () { $('[data-upload-wrapper]').remove() }, 2000);
            });

        }
      },

      plugins: grapes_plugins,
      pluginsOpts: grapes_plugin_options
    });
    window.editor = editor;
    editor.tabIdentifier = tabIdentifier;
    editor.UndoManager.removeAll();
    editor.UndoManager.stop();
    $(document).trigger('pagedesigner-after-init', [editor]);

    $(".gjs-toolbar").watch({
      // specify CSS styles or attribute names to monitor
      properties: "top,left,display",

      // callback function when a change is detected
      callback: function (data, i) {
        if (editor.getSelected()) {
          $(this).css('margin-left', ($(this).width() - editor.getSelected().view.el.clientWidth) + 'px')
        }
      }
    });
  };
}(jQuery));
