(function ($, Drupal) {

  Drupal.behaviors.pagedesigner_image_init_traits = {
    attach: function (context, settings) {
      once('pagedesigner_image_init_traits', 'body', context).forEach(() => {
        $(document).on('pagedesigner-init-traits', function (e, editor) {
          init(editor);
        });
      })
    }
  };

  /**
   * Target for background images.
   */
  var assetTarget = null;

  /**
   * Intitialize trait and asset "document"
   *
   * @param {Object} editor The grapes editor
   */
  function init(editor) {
    /**
     * Initialise "image" trait using the media trait defaults
     */
    editor.PDMediaManager.addTrait('image', 'file', {
      getMetaData: function getMetaData() {
        if (!this.$metaHolder.hasClass('btn-remove')) {
          var trait = this;
          this.$metaHolder.attr('title', Drupal.t('Remove image'));
          this.$metaHolder.click(function () {
            if (confirm(Drupal.t('Remove image from component?'))) {
              trait.model.set('value', { id: null });
              trait.getMetaData()
            }
          });
          this.$metaHolder.addClass('btn-remove');
        }

        if (this.model.get('value') && this.model.get('value').src) {
          return '<img src="' + this.model.get('value').src + '"/>';
        }
        return '';
      }
    });

    var styleManager = editor.StyleManager;
    styleManager.addType(
      'file',
      {
        isType: function (value) {
          if (typeof value == 'object') {
            if (typeof value.type == 'string' && value.type.startsWith('image/')) {
              return {
                type: 'image',
                src: ''
              };
            }
            if (typeof value.bundle == 'string' && value.bundle == 'image') {
              value.type = value.bundle;
              return value;
            }
          }
        },
      },
    );

    var am = editor.AssetManager;
    am.add([]);
    am.render();
    $('.gjs-am-file-uploader').before('<div id="pd-asset-edit"></div>');
    // Overwrite image asset type to provide value to trait
    var imageAsset = am.getType('image');
    var selection = [];
    am.addType(
      'image',
      {
        view:
          imageAsset.view.extend
            (
              {
                init(o) {
                  const pfx = this.pfx;
                  this.className += ` ${pfx}asset-image`;

                  // highlight selected item
                  if (this.collection.target && this.collection.target.model && this.collection.target.model.getTargetValue() && this.collection.target.model.getTargetValue().id == this.model.attributes.id) {
                    this.className += ` ${pfx}highlight`;
                    this.onClick();
                  } else {
                    if (this.collection.target && this.collection.target.attributes && this.collection.target.attributes.style && this.collection.target.attributes.style['background-image'] == 'url(' + this.model.attributes.src + ')') {
                      this.className += ` ${pfx}highlight`;
                      this.onClick();
                    }
                  }

                  selection = [];

                  $('#pd_add_images').remove();
                },
                getPreview() {
                  const pfx = this.pfx;
                  const preview = this.model.get('preview');
                  return `
                  <div class="${pfx}preview" style="background-image: url('${preview}');"></div>
                  <div class="${pfx}preview-bg ${this.ppfx}checker-bg"></div>
                `;
                },
                getInfo() {
                  const pfx = this.pfx;
                  const model = this.model;
                  let name = model.get('name');
                  if (model.get('height') == '') {
                    return `<div class="${pfx}name">${name}</div>`;
                  }
                  let dimensions = model.get('width') + 'x' + model.get('height') + ' px';
                  return `
                      <div class="${pfx}name">${name}</div>
                      <div class="${pfx}dimensions">${dimensions}</div>
                    `;
                },
                updateTarget(trait) {
                  if (trait.setValueFromAssetManager) {
                    trait.setValueFromAssetManager({
                      id: this.model.get('id'),
                      src: this.model.get('src'),
                      alt: this.model.get('alt'),
                      preview: this.model.get('preview'),
                      title: this.model.get('name')
                    });
                  } else if (assetTarget && assetTarget.onSelect) {
                    this.target = assetTarget.target;
                    assetTarget.onSelect(this.model.get('src'));
                  }
                },
                onClick() {
                  if (this.collection.target && this.collection.target.isMultiSelect) {
                    const { em, model } = this;
                    const target = this.collection.target;
                    this.$el.toggleClass(this.pfx + 'highlight');
                    var id = this.model.get('id');
                    if (this.$el.hasClass(this.pfx + 'highlight')) {
                      selection.push({
                        id: id,
                        src: this.model.get('src'),
                        alt: this.model.get('alt'),
                        preview: this.model.get('preview'),
                      });
                    } else {
                      selection = _.reject(selection, function (el) { return el.id === id; });
                      if (Object.keys(selection).length == 0) {
                        $('#pd_add_images').remove();
                      }
                    }
                    if ($('.pd-asset-form').length == 0 && Object.keys(selection).length > 0) {
                      var button = $('#pd_add_images');
                      if (button.length == 0) {
                        $('.gjs-am-assets').before('<button id="pd_add_images">' + Drupal.t('Add images') + '</button>');
                        button = $('#pd_add_images');
                        button.on('click',
                          // (function (em) {
                          function (e) {
                            $('.pd-asset-form').remove();
                            em && em.get('Modal').close();
                            target.setValueFromAssetManager(selection);
                            selection = {};
                          }
                          // })(em, target)
                        );
                      }
                    }
                  } else {
                    if (!this.$el.hasClass(this.pfx + 'highlight')) {
                      this.collection.trigger('deselectAll');
                      this.$el.addClass(this.pfx + 'highlight');
                      var id = this.model.attributes.id;
                      if ($('.pd-asset-form').length == 0) {
                        $('.gjs-am-file-uploader').prepend('<div class="pd-asset-form"></div>');
                      }
                      $('.pd-asset-form').empty();
                      if ($('#pd-asset-edit').length == 0) {
                        $('.pd-asset-form').append('<div id="pd-asset-edit"></div>');
                      }
                      Drupal.ajax({ url: '/media/' + id + '/edit', wrapper: 'pd-asset-edit' }).execute().then(function () {
                        if ($('.pd-asset-form .form-actions').find('input[type="reset"]').length == 0) {
                          var cancelButton = $('<input type="reset" value="' + Drupal.t('Cancel edit') + '" class="button button--primary js-form-submit form-submit">');
                          cancelButton.on('click', function () {
                            $('.pd-asset-form').remove();
                          });
                          $('.pd-asset-form .form-actions').append(cancelButton);
                        }
                        $('.pd-asset-form input[name=field_media_image_0_remove_button], .pd-asset-form .form-type-vertical-tabs, .pd-asset-form .button--danger').hide();
                      });
                    }
                  }
                },
                onDblClick() {
                  const { em, model } = this;
                  if (this.collection.target.isMultiSelect) {
                    this.onClick();
                  } else {
                    $('.pd-asset-form').remove();
                    this.updateTarget(this.collection.target);
                    em && em.get('Modal').close();
                  }
                },
                onRemove(e) {
                  const model = this.model
                  e.stopImmediatePropagation();
                  if (confirm(Drupal.t('Do you really want to delete "%file"?\nIt might be used on other pages.').replace('%file', model.get('name')))) {
                    editor.PDMediaManager.delete(model.get('id'));
                    this.model.collection.remove(this.model);
                  }
                }
              }
            ),
        isType: function (value) {
          if (typeof value == 'object') {
            if (typeof value.type == 'string' && value.type.startsWith('image/') && !value.type.startsWith('image/svg')) {
              return {
                type: 'image',
                src: ''
              };
            }
            if (typeof value.bundle == 'string' && value.bundle == 'image') {
              value.type = value.bundle;
              return value;
            }
          }
        },
      },
    );
    am.getType('image').upload = function (file) {
      var reader = new FileReader();
      var promise = jQuery.Deferred();
      reader.onload = function () {
        Drupal.restconsumer.upload(
          '/file/upload/media/image/field_media_image',
          file.name,
          reader.result
        )
          .done(function (result) {
            result = JSON.parse(result);
            var mediaData =
            {
              "_links": { "type": { "href": window.location.protocol + '//' + window.location.hostname + '/rest/type/media/image' } },
              "field_media_image": [{ "target_id": result.fid[0].value, 'alt': result.filename[0].value }],
              "name": [{ "value": file.name }],
              "uid": [{ "target_id": drupalSettings.user.uid }],
            };
            if (drupalSettings.pagedesigner.media.image.translatable) {
              mediaData.langcode = [{ "value": drupalSettings.path.currentLanguage }];
            }
            Drupal.restconsumer.post('/entity/media', mediaData).done(function () {
              promise.resolve();
            }).fail(function () {
              promise.reject();
            });
          }).fail(function () {
            promise.reject();
          });
      }
      reader.readAsArrayBuffer(file);
      return promise;
    }
    editor.on('run:open-assets',
      (something, target) => {
        if (target.accept == 'image/*') {
          assetTarget = target;
          editor.PDMediaManager.loadForm(assetTarget.target, 'image');
        }
      }
    );
  }

})(jQuery, Drupal);
