/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/* global wysihtml, wysihtmlParserRules */

rava.bind('.file', {
  callbacks: {
    created() {
      const field = this;
      const close = field.closest('form').querySelector('a.close');

      function setProgress(m, progress) {
        const meter = m;
        meter.innerText = `${Math.round(progress)}%`;
        meter.value = Math.round(progress);
      }
      function uploadFile(meter, action, file) {
        const formData = new FormData();

        formData.append("*", file);
        formData.append("*@TypeHint", "sling:File");
        formData.append("_charset_", "utf-8");

        const xhr = new XMLHttpRequest();
        xhr.upload.addEventListener('loadstart', () => {
          setProgress(meter, 0);
        }, false);
        xhr.upload.addEventListener('progress', (event) => {
          const percent = (event.loaded / event.total) * 100;
          setProgress(meter, percent);
        }, false);
        xhr.upload.addEventListener('load', () => {
          meter.classList.add('is-info');
        }, false);
        xhr.addEventListener('readystatechange', (event) => {
          let status; let text; let
            readyState;
          try {
            readyState = event.target.readyState;
            text = event.target.responseText;
            status = event.target.status;
          } catch (e) {
            meter.classList.add('is-danger');
          }
          if (readyState === 4) {
            meter.classList.remove('is-info');
            if (status === 200 && text) {
              meter.classList.add('is-success');
            } else {
              meter.classList.add('is-danger');
              console.warn('Failed to upload %s, recieved message %s', file.name, text); // eslint-disable-line no-console
            }
          }
        }, false);
        xhr.open('POST', action, true);
        xhr.send(formData);
      }
      function handleFile(scope, file) {
        const it = document.createElement('div');
        const ctr = scope.closest('.control').querySelector('.file-item-container');
        let meter = null;
        it.innerHTML = document.querySelector('.file-item-template').innerHTML;
        meter = it.querySelector('.progress');
        it.querySelector('.file-item-name').innerText = file.name;
        ctr.classList.remove('is-hidden');
        ctr.appendChild(it);
        uploadFile(meter, scope.closest('form').action, file);
      }

      field.addEventListener('dragover', (event) => {
        event.preventDefault();
      }, false);
      field.addEventListener('dragenter', (event) => {
        event.preventDefault();
        field.classList.add('is-primary');
      }, false);
      field.addEventListener('dragleave', (event) => {
        event.preventDefault();
        if(!field.contains(event.fromElement)){
          field.classList.remove('is-primary');
        }
      }, false);
      field.addEventListener('drop', (event) => {
        event.preventDefault();
        field.classList.remove('is-primary');
        if (event.dataTransfer.items) {
          const { items } = event.dataTransfer;
          for (let i = 0; i < items.length; i++) { // eslint-disable-line no-plusplus
            if (items[i].kind === 'file') {
              handleFile(field, items[i].getAsFile());
            }
          }
        } else {
          const { files } = event.dataTransfer;
          for (let i = 0; i < files.length; i++) { // eslint-disable-line no-plusplus
            handleFile(field, files[i]);
          }
        }
      }, false);
      field.closest('form').querySelector('button[type=submit]').remove();
      close.innerText = 'Done';
      close.addEventListener('click', () => {
        window.Sling.CMS.ui.reloadContext();
      });
      field.querySelector('input').addEventListener('change', (event) => {
        const { files } = event.target;
        for (let i = 0; i < files.length; i++) { // eslint-disable-line no-plusplus
          handleFile(field, files[i]);
        }
      });
    },
  },
});

/* Support for updating the namehint when creating a component */
rava.bind('.namehint', {
  callbacks: {
    created() {
      const field = this;
      this.closest('.Form-Ajax').querySelector('select[name="sling:resourceType"]').addEventListener('change', (evt) => {
        const resourceType = evt.target.value.split('/');
        field.value = resourceType[resourceType.length - 1];
      });
    },
  },
});

/* Support for repeating form fields */
rava.bind('.repeating', {
  callbacks: {
    created() {
      const ctr = this;
      this.querySelectorAll('.repeating__add').forEach((el) => {
        el.addEventListener('click', (event) => {
          event.stopPropagation();
          event.preventDefault();
          const node = ctr.querySelector('.repeating__template > .repeating__item').cloneNode(true);
          ctr.querySelector('.repeating__container').appendChild(node);
        });
      });
    },
  },
});
rava.bind('.repeating__item', {
  events: {
    ':scope .repeating__remove': {
      click(event) {
        event.stopPropagation();
        event.preventDefault();
        this.remove();
      },
    },
  },
});

rava.bind('.rte', {
  callbacks: {
    created() {
      new wysihtml.Editor(this.querySelector('.rte-editor'), { // eslint-disable-line no-new, new-cap
        toolbar: this.querySelector('.rte-toolbar'),
        parserRules: wysihtmlParserRules,
      });
    },
  },
});
