(function ($, Drupal) {

  Drupal.behaviors.pagedesigner_init_events = {
    attach: function (context, settings) {
      once('pagedesigner_init_events', 'body', context).forEach(() => {
        $(document).on('pagedesigner-init-events', function (e, editor, options) {
          editor.on('selector:add', (selector) => {
            if (selector.get('type') == 1) {
              selector.set('active', false)
            }
          });

          editor.on('load', () => {

            // hacks - grapes bugs??
            editor.Panels.getPanel('component-controls').set('visible', true).set('visible', false);
            editor.Panels.getPanel('views-container').set('visible', true).set('visible', false);
            editor.spinner.enable().disable();
            editor.Panels.getButton('sidebar', 'sidebar-open-styles').set('active', true).set('active', false);

            // enable none as value for max widht & height
            editor.StyleManager.getProperty('dimension', 'max-width').set('fixedValues', ["initial", "inherit", "auto", "none"]);


            //prevent margin and padding from being grouped into shorthand definition
            editor.StyleManager.removeProperty('dimension', 'margin');
            editor.StyleManager.addProperty('dimension', {
              name: 'Margin top',
              property: 'margin-top',
              type: 'integer',
              fixedValues: ["initial", "inherit", "auto"],
              units: ['px', '%', 'em', 'rem'],
              unit: 'px',
            });

            editor.StyleManager.addProperty('dimension', {
              name: 'Margin right',
              property: 'margin-right',
              type: 'integer',
              fixedValues: ["initial", "inherit", "auto"],
              units: ['px', '%', 'em', 'rem'],
              unit: 'px',
            });

            editor.StyleManager.addProperty('dimension', {
              name: 'Margin bottom',
              property: 'margin-bottom',
              type: 'integer',
              fixedValues: ["initial", "inherit", "auto"],
              units: ['px', '%', 'em', 'rem'],
              unit: 'px',
            });

            editor.StyleManager.addProperty('dimension', {
              name: 'Margin left',
              property: 'margin-left',
              type: 'integer',
              fixedValues: ["initial", "inherit", "auto"],
              units: ['px', '%', 'em', 'rem'],
              unit: 'px',
            });


            editor.StyleManager.removeProperty('dimension', 'padding');
            editor.StyleManager.addProperty('dimension', {
              name: 'Padding top',
              property: 'padding-top',
              type: 'integer',
              units: ['px', '%', 'em'],
              unit: 'px',
            });

            editor.StyleManager.addProperty('dimension', {
              name: 'Padding right',
              property: 'padding-right',
              type: 'integer',
              units: ['px', '%', 'em'],
              unit: 'px',
            });

            editor.StyleManager.addProperty('dimension', {
              name: 'Padding bottom',
              property: 'padding-bottom',
              type: 'integer',
              units: ['px', '%', 'em'],
              unit: 'px',
            });

            editor.StyleManager.addProperty('dimension', {
              name: 'Padding left',
              property: 'padding-left',
              type: 'integer',
              units: ['px', '%', 'em'],
              unit: 'px',
            });


            var display_property = Object.assign({}, editor.StyleManager.getProperty('general', 'display').attributes);
            display_property.type = 'radio';
            display_property.full = 1;
            editor.StyleManager.removeProperty('general', 'display');
            editor.StyleManager.addProperty('general', display_property);



            var top_property = Object.assign({}, editor.StyleManager.getProperty('general', 'top').attributes);
            editor.StyleManager.removeProperty('general', 'top');
            editor.StyleManager.addProperty('general', top_property);

            var bottom_property = Object.assign({}, editor.StyleManager.getProperty('general', 'bottom').attributes);
            editor.StyleManager.removeProperty('general', 'bottom');
            editor.StyleManager.addProperty('general', bottom_property);

            var left_property = Object.assign({}, editor.StyleManager.getProperty('general', 'left').attributes);
            editor.StyleManager.removeProperty('general', 'left');
            editor.StyleManager.addProperty('general', left_property);

            var right_property = Object.assign({}, editor.StyleManager.getProperty('general', 'right').attributes);
            editor.StyleManager.removeProperty('general', 'right');
            editor.StyleManager.addProperty('general', right_property);

            editor.StyleManager.addProperty('general', {
              name: 'Z-Index',
              property: 'z-index',
              type: 'integer',
              defaults: '',
              min: -1
            });

            editor.StyleManager.addProperty('general', {
              name: 'Overflow',
              property: 'overflow',
              type: 'select',
              defaults: null,
              list: [{
                value: 'visible',
                name: 'visible',
              }, {
                value: 'hidden',
                name: 'hidden',
              }, {
                value: 'scroll',
                name: 'scroll',
              }, {
                value: 'auto',
                name: 'auto',
              }],
            });

            editor.StyleManager.addProperty('general', {
              type: 'integer',
              step: 0.01,
              name: 'Opacity',
              property: 'opacity',
              defaults: null,
              min: 0,
              max: 1
            });


            editor.StyleManager.removeProperty('typography', 'font-family');

            // set defaults to null
            var specialPropertyDefaults = {
              'border-radius': 0,
              'transform': 0,
              'transform-scale-x': 1,
              'transform-scale-y': 1,
              'transform-scale-z': 1,
            };
            editor.StyleManager.getSectors().forEach(function (sector) {
              editor.StyleManager.getProperties(sector.get('id')).forEach(function (prop) {
                let defaultVal = specialPropertyDefaults.hasOwnProperty(prop.get('id')) ? specialPropertyDefaults[prop.get('id')] : null;
                if (prop.get('type') == 'composite') {
                  prop.get('properties').forEach(function (prop) {
                    defaultVal = specialPropertyDefaults.hasOwnProperty(prop.get('id')) ? specialPropertyDefaults[prop.get('id')] : defaultVal;
                    prop.set('defaults', defaultVal)
                  });
                } else {
                  prop.set('defaults', defaultVal)
                }
              });
            })

            const panels = editor.Panels.getPanel('spinner-loading');
            var spinner_content = document.createElement('div');
            spinner_content.appendChild(jQuery('<i class="fas fa-spinner fa-spin"></i>').get(0));
            panels.set('appendContent', spinner_content).trigger('change:appendContent');

            Array.from(document.querySelectorAll('style')).forEach(function (style) {
              editor.Canvas.getDocument().head.appendChild(style.cloneNode(true));
            });

            editor.Canvas.getDocument().body.className += document.body.className;
            editor.Canvas.getDocument().body.className += " gjs-body";
            document.querySelector("iframe.gjs-frame").contentWindow.drupalSettings = window.drupalSettings;

            $(editor.Canvas.getDocument().querySelectorAll("body")).on('click', 'a[data-gjs-type]', function (e) {
              e.preventDefault();
            });

            // Let all links target parent window instead of iframe
            jQuery(editor.Canvas.getDocument().querySelectorAll("body")).find('a:not([data-gjs-type])').attr('target', '_blank');

            editor.Keymaps.keymaster.filter = function (e) {
              // ignore keypressed in ckeditor instances
              if (event.target.ckeditorInstance  || event.target.classList.contains('ck-editor__editable') || event.target.attributes['contenteditable'] === 'true') {
                return false;
              }
              var tagName = (event.target || event.srcElement).tagName;
              // ignore keypressed in any elements that support keyboard data input
              return !(tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA' || event.keyCode == 46 || event.keyCode == 8);
            };

            setTimeout(function () {
              editor.LayerManager.setRoot('[data-grapes-block="content"]');
            });
          });



          editor.on('component:selected', (component, sender) => {

            if (!component.get('stylable')) {
              component.setStylableProperties();
            }

            if (component.load && Drupal.restconsumer) {
              component.load();
            }

            // Begin Class toggle
            if ($('.gjs-clm-class-toggle').length == 0) {
              $('<div class="gjs-clm-class-toggle gjs-one-bg gjs-two-color"><div data-class-toggle-container></div></div>').insertBefore('.gjs-clm-tags')
            }

            $('[data-class-toggle-container]').html('');

            var $classes_global = $('<div class="options-holder"><p class="sidebar-subtitle">' + Drupal.t('Global options') + '</p>');
            var $classes_responsive = $('<div class="options-holder"><p class="sidebar-subtitle">' + Drupal.t('Responsive options') + '</p>');

            for (var class_name in editor.getSelected().get('toggable_classes')) {
              var class_tmp = editor.getSelected().get('toggable_classes')[class_name];
              if (class_tmp.responsive) {
                var $styling_option = $('<div class="responsive-class"><p>' + Drupal.t(class_tmp.label) + '<a class="info" title="' + Drupal.t(class_tmp.description) + '"><i class="fas fa-info-circle"></i></a></p>');
                editor.getConfig().deviceManager.devices.forEach(function (device) {
                  var $checkbox = $('<input type="checkbox"/>').attr('value', class_name + '-' + device.key);

                  if (editor.getSelected().getClasses().includes(class_name + '-' + device.key)) {
                    $checkbox.attr('checked', 'checked');
                  }

                  $checkbox.change(function () {
                    var class_name = $(this).val();
                    if (component.getClasses().includes(class_name)) {
                      component.removeClass(class_name);
                    } else {
                      component.addClass(class_name);
                    }
                  });

                  $label = $('<label class="inline-label">').data('device', device.name);
                  if (editor.getDevice() == device.name) {
                    $label.addClass('active');
                  }

                  $icon = $('<span class="gjs-pn-btn fas"></span>').attr('title', Drupal.t(device.name));

                  if (device.name == 'Desktop') {
                    $icon.addClass('fa-' + device.name.toLowerCase());
                  } else if (device.name == 'Tablet') {
                    $icon.addClass('fa-' + device.name.toLowerCase() + '-alt');
                  } else {
                    $icon.addClass('fa-mobile-alt');
                  }

                  $label.append($checkbox);
                  $label.append($icon);
                  $styling_option.append($label);
                });

                $classes_responsive.append($styling_option);

              } else {
                var $styling_option = $('<label title="' + class_tmp.description + '">');
                var $checkbox = $('<input type="checkbox"/>').attr('value', class_name);

                if (component.getClasses().includes(class_name)) {
                  $checkbox.attr('checked', 'checked');
                }

                $checkbox.change(function () {
                  var class_name = $(this).val();
                  if (component.getClasses().includes(class_name)) {
                    component.removeClass(class_name);
                  } else {
                    component.addClass(class_name);
                  }
                });

                $styling_option.append($checkbox).append('<span>' + Drupal.t(class_tmp.label) + '</span><a class="info" title="' + Drupal.t(class_tmp.description) + '"><i class="fas fa-info-circle"></i></a>');
                $classes_global.append($styling_option);
              }
            }

            if ($classes_global.find('label').length > 0) {
              $('[data-class-toggle-container]').append($classes_global);
            }

            if ($classes_responsive.find('.responsive-class').length > 0) {
              $('[data-class-toggle-container]').append($classes_responsive);
            }

            // End Class toggle

            // Begin easy styling options

            if ($('.gjs-clm-easy-styling').length == 0) {
              $('<div class="gjs-clm-easy-styling gjs-one-bg gjs-two-color" data-easy-styling-container></div>').insertBefore('.gjs-clm-tags')
            }

            $('[data-easy-styling-container]').html('');

            var styling_options = component.get('styling_options');
            var selected_classes = component.getClasses();

            if (styling_options && Object.keys(styling_options).length > 0) {

              $('[data-easy-styling-container]').append('<p class="sidebar-subtitle">' + Drupal.t('Easy styling options') + '</p><div></div>');

              for (var styling_option in styling_options) {
                var $container_class = $('<div class="options-holder" >').append('<p >' + Drupal.t(styling_options[styling_option].label) + '</p>');
                var $select_class = $('<select>').data('styling-option', styling_option).append('<option value="">' + Drupal.t('None') + '</option>');

                for (var class_name in styling_options[styling_option].options) {
                  var $select_class_option = $('<option>').attr('value', class_name).text(Drupal.t(styling_options[styling_option].options[class_name]));
                  if (selected_classes.includes(class_name)) {
                    $select_class_option.attr('selected', 'selected');
                  }
                  $select_class.append($select_class_option);
                }

                $select_class.change(function () {
                  for (remove_class_name in component.get('styling_options')[$(this).data('styling-option')].options) {
                    component.removeClass(remove_class_name);
                  }
                  if ($(this).val()) {
                    component.addClass($(this).val());
                  }

                });

                $container_class.append($select_class);
                $('[data-easy-styling-container] > div').append($container_class);
              }
            }

            // end easy styling options

          });

          editor.on('component:deselected', (component, sender) => {
            editor.stopCommand('edit-component');
            if (component.get('changed')) {
              if (confirm(Drupal.t("Do you want to save your changes?"))) {
                component.save();
              } else {
                component.restore();
              }
            }
          });

          editor.on('component:styleUpdate', component => {
            component.set('changed', true);
          });

          editor.on('component:update:classes', component => {
            component.set('changed', true);
            component.getClasses().forEach(function (className) {
              editor.SelectorManager.get('.' + className).set('active', false);
            });
          });

          editor.on('run:open-blocks', component => {
            if ($('#filter-blocks').length < 1) {

              var $filterInput = $('<input id="filter-blocks" placeholder="' + Drupal.t('Filter components') + '" />');
              $filterInput.keyup(function () {
                var filterValue = $(this).val().toLowerCase();
                if (filterValue) {
                  $('.gjs-block-categories').find('.gjs-blocks-c').children('[title]').hide();
                  $('.gjs-block-categories').find('.gjs-blocks-c').children('[title]').each(function () {
                    if ($(this).attr('title').toLowerCase().indexOf(filterValue) !== -1) {
                      $(this).show()
                    }
                  });
                } else {
                  $('.gjs-block-categories').find('.gjs-blocks-c').children('[title]').show()
                }
              });

              var $filterContainer = $('<label class="filter-blocks-holder"></label>');
              $filterContainer.append($filterInput);
              $filterContainer.insertBefore('.gjs-blocks-cs');

            }
          });

          editor.on('run:open-tm', component => {
            editor.Panels.getPanel('views-container').set('visible', true);
            editor.Panels.getPanel('component-controls').set('visible', true);

            var traitsHolder = $('.gjs-blocks-cs').parent();
            if (traitsHolder.find('.sidebar-title').length == 0) {
              traitsHolder.prepend('<p class="sidebar-title">' + Drupal.t('Edit component content') + '</p>')
            }
          });

          editor.on('stop:open-tm', component => {
            editor.Panels.getPanel('views-container').set('visible', false);
            editor.Panels.getPanel('component-controls').set('visible', false);
            var traitsHolder = $('.gjs-trt-traits').parent();
            if (traitsHolder.find('.sidebar-title').length == 0) {
              $('.gjs-traits-label').remove();
              traitsHolder.prepend('<p class="sidebar-title">' + Drupal.t(editor.TraitManager.getConfig().labelContainer) + '</p>')
            }
          });

          editor.on('run:open-sm', component => {
            editor.Panels.getPanel('views-container').set('visible', true);
            editor.Panels.getPanel('component-controls').set('visible', true);

            var stylesHolder = $('.gjs-clm-tags').parent();
            if (stylesHolder.find('.sidebar-title').length == 0) {
              $('.gjs-traits-label').remove();
              stylesHolder.prepend('<p class="sidebar-title">' + Drupal.t('Edit component styling') + '<a class="info" title="' + Drupal.t('The styling options allow you to customize components.\nSome combination of settings may generate conflicts between parent and child elements and not yield the expected result.') + '"><i class="fas fa-info-circle"></i></a></p>');
              $('#gjs-clm-label').addClass('sidebar-subtitle').text(Drupal.t('Custom CSS classes'));

              if ($('.gjs-sm-sectors').find('.sidebar-subtitle').length == 0) {
                var $styling_warning = $('<div class="sectors-title-holder"><p class="sidebar-subtitle">' + Drupal.t('Advanced styling options') + '</p></div>');

                var $btn_clear_styles = $('<button class="clear-styling">' + Drupal.t('Remove all styles') + '</button>').click(function () {
                  window.editor.getSelected().setStyle({});
                });
                $('.gjs-sm-sectors').prepend($btn_clear_styles);
                $('.gjs-sm-sectors').prepend($styling_warning);
              }
            }
          });

          editor.on('stop:open-sm', component => {
            editor.Panels.getPanel('views-container').set('visible', false);
            editor.Panels.getPanel('component-controls').set('visible', false);
          });

          editor.on('run:open-blocks', component => {
            editor.Panels.getPanel('views-container').set('visible', true);
            editor.select();
            var blocksHolder = $('.gjs-blocks-cs').parent();
            if (blocksHolder.find('.sidebar-title').length == 0) {
              blocksHolder.prepend('<p class="sidebar-title">' + Drupal.t(editor.BlockManager.getConfig().labelContainer) + '</p>')
            }
          });

          editor.on('stop:open-blocks', component => {
            editor.Panels.getPanel('views-container').set('visible', false);
          });

          editor.on('block:drag:start', block => {
            let component = editor.getSelected();
            if (component) {
              component.save();
              editor.select();
            }
          });

          // prevent layer manager from selecting components when toggling children
          editor.on('run:open-layers', component => {

            var layers_holder = $('.gjs-layer:first').parent();
            if (layers_holder.find('.sidebar-title').length == 0) {
              editor.spinner.enable()
              layers_holder.prepend('<p class="sidebar-title">' + Drupal.t('Layers') + '</p>');
              editor.LayerManager.setRoot('[data-grapes-block="content"]');
            }

            $('.gjs-layer [data-toggle-select]').removeAttr('data-toggle-select');
            $('.gjs-layer [data-name]').attr('data-toggle-select', 1);
            $('.fa.fa-arrows').addClass('fa-arrows-alt');
            editor.Panels.getPanel('views-container').set('visible', true);
            editor.spinner.disable()
          });

          editor.on('stop:open-layers', component => {
            editor.Panels.getPanel('views-container').set('visible', false);
          });

          editor.on('component:add', component => {
            if (component.create) {
              component.create();
            }
            editor.UndoManager.removeAll();
          });

          editor.on('component:update:components', (component, movedComponent) => {
            if (component.get('entityId') && component.attributes.droppable && Object.keys(movedComponent.components()._byId).length > 0 && component.save) {
              if (!isNaN(movedComponent.get('entityId')) && component.components().map(item => item.get('entityId')).includes(movedComponent.get('entityId'))) {
                component.save();
              }
            }
            editor.UndoManager.removeAll();
          });

          editor.on('run:open-assets', component => {
            $('.pd-asset-form').remove();
          });

        });
      });
    }
  };
})(jQuery, Drupal);
