(function ($, Drupal) {
  Drupal.behaviors.pagedesigner_init_base_blocks = {
    attach: function (context, settings) {
      $(document).on('pagedesigner-init-base-blocks', function (e, editor, options) {
        editor.component_classes = [];
        editor.twigIncludes = [];
        const twigInlcudeRegex = /{% include[ *]['"](.*)['"][ *][[width|%}]/g;

        for (var pattern_id in options.patterns) {
          if (options.patterns.hasOwnProperty(pattern_id)) {

            // create component
            var traits = [];
            for (var field_name in options.patterns[pattern_id].fields) {
              // TODO: Add check for editable somewhere else

              if (options.patterns[pattern_id].fields.hasOwnProperty(field_name) && editor.TraitManager.getType(options.patterns[pattern_id].fields[field_name].type)) {
                var trait_tmp = {
                  type: options.patterns[pattern_id].fields[field_name].type,
                  label: Drupal.t(options.patterns[pattern_id].fields[field_name].label),
                  name: field_name,
                  additional: options.patterns[pattern_id].fields[field_name]
                }

                if (options.patterns[pattern_id].additional && options.patterns[pattern_id].additional.relations && options.patterns[pattern_id].additional.relations[field_name]) {
                  trait_tmp.relations = options.patterns[pattern_id].additional.relations[field_name];
                }

                traits.push(trait_tmp);
              }
            }

            editor.DomComponents.addType(pattern_id, {
              extend: options.patterns[pattern_id].type,
              model: {
                defaults: {
                  name: Drupal.t(options.patterns[pattern_id].label),
                  traits: traits,
                  stylable: (options.patterns[pattern_id].styles === 1),
                  styles: options.patterns[pattern_id].styles,
                  toggable_classes: options.patterns[pattern_id].additional.classes,
                  styling_options: options.patterns[pattern_id].additional.styling_options
                },
              }
            });

            if (options.patterns[pattern_id].additional.classes) {
              editor.component_classes = editor.component_classes.concat(Object.keys(options.patterns[pattern_id].additional.classes));
              editor.getConfig().deviceManager.devices.forEach(function (device) {
                editor.component_classes = editor.component_classes.concat(Object.keys(options.patterns[pattern_id].additional.classes).map(i => i + '-' + device.key));
              });
            }

            if (options.patterns[pattern_id].additional.styling_options) {
              Object.keys(options.patterns[pattern_id].additional.styling_options).forEach(option => {
                editor.component_classes = editor.component_classes.concat(Object.keys(options.patterns[pattern_id].additional.styling_options[option].options));
              });
            }

            if (options.patterns[pattern_id].additional.type == 'component' || options.patterns[pattern_id].additional.type == 'row') {
              if ($(options.patterns[pattern_id].markup.replace(/{.*}/g, '')).attr('class')) {
                editor.component_classes = editor.component_classes.concat($(options.patterns[pattern_id].markup.replace(/{.*}/g, '')).attr('class').split(' '));
              }
            }


            // create block
            var preview = {};
            for (var field_name in options.patterns[pattern_id].fields) {
              if (options.patterns[pattern_id].fields.hasOwnProperty(field_name)) {
                preview[field_name] = options.patterns[pattern_id].fields[field_name].preview;
              }
            }

            // make this a bit less hacky :)
            if (options.patterns[pattern_id].markup) {
              var tmpl = options.patterns[pattern_id].markup
            } else {
              var tmpl = '';
            }

            let m;
            while ((m = twigInlcudeRegex.exec(tmpl)) !== null) {
              if (m.index === twigInlcudeRegex.lastIndex) {
                twigInlcudeRegex.lastIndex++;
              }

              // The result can be accessed through the `m`-variable.
              m.forEach((match, groupIndex) => {
                if (groupIndex) {
                  let matchUrlReplaced = match;
                  Object.keys(drupalSettings.pagedesigner.theme_namespaces).forEach(function (theme) {
                    matchUrlReplaced = matchUrlReplaced.replace(theme, drupalSettings.pagedesigner.theme_namespaces[theme]);
                  });
                  if (!Twig.twig({ ref: match })) {
                    editor.twigIncludes.push(Twig.twig({
                      id: match,
                      href: matchUrlReplaced,
                      async: false
                    }));
                  }
                }
              });
            }

            var twig = Twig.twig({
              data: '{% spaceless %}' + tmpl + '{% endspaceless %}'
            });
            var markup = twig.render(preview);

            var elem = $(markup).attr('data-gjs-type', pattern_id);
            elem.find('[class*=column]').attr('data-gjs-type', 'cell');

            editor.BlockManager.add(pattern_id, {
              additional: options.patterns[pattern_id].additional,
              label: Drupal.t(options.patterns[pattern_id].label),
              pattern: {
                type: pattern_id,
                template: options.patterns[pattern_id].markup
              },

              content: elem[0].outerHTML,

              preview: preview,
              category: options.patterns[pattern_id].category,
              attributes: {
                class: options.patterns[pattern_id].icon
              },
              render: ({ model, el }) => {
                $(document).trigger('pagedesigner-render-block-element', [model, el]);
              }
            });
          }
        }

        // lock classes
        editor.component_classes = Array.from(new Set(editor.component_classes));
        editor.SelectorManager.addClass(editor.component_classes).forEach(selector => selector.set('active', false).set('private', true).set('protected', true));
      });
    }
  };
})(jQuery, Drupal);
