/*
 * 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.
 */


window.Sling = window.Sling || {};
const {
  Sling,
} = window;
window.Sling.CMS = {
  handlers: {
    handledelete(res, msg) {
      if (window.location.pathname.indexOf(res.path) !== -1) {
        window.top.Sling.CMS.ui.confirmMessage(msg, res.title, () => {
          window.location = '/cms';
        });
      } else {
        Sling.CMS.ui.confirmReload(res, msg);
      }
    },
    handlemove(res, msg) {
      const changes = res.changes[0];
      if (changes.type === 'moved' && window.location.pathname.indexOf(changes.argument[0]) !== -1) {
        window.top.Sling.CMS.ui.confirmMessage(msg, res.title, () => {
          window.location = window.location.href.replace(changes.argument[0], changes.argument[1]);
        });
      } else {
        Sling.CMS.ui.confirmReload(res, msg);
      }
    },
    handleugc(res, msg) {
      Sling.CMS.ui.confirmMessage(msg, res.title, () => {
        window.location = `/cms/usergenerated/content.html${res.parentLocation}`;
      });
    },
  },
  ui: {
    confirmMessage(title, message, complete) {
      const modal = document.createElement('div');
      modal.innerHTML = `<div class="modal-background"></div><div class="is-draggable modal-content"><div class="box"><h3 class="modal-title">${title}</h3><p>${message}</p><br/><button type="button" class="close-modal button is-primary">OK</button></div></div><button class="modal-close is-large" aria-label="close"></button>`;
      document.body.appendChild(modal);
      modal.classList.add('modal');
      modal.classList.add('is-active');
      modal.querySelectorAll('.modal-close,.close-modal,.modal-background').forEach((closer) => {
        closer.addEventListener('click', () => {
          modal.remove();
          complete();
        });
      });
      modal.querySelector('.delete,.close-modal').focus();
      return modal;
    },
    confirmReload(res, msg) {
      if (window.self !== window.top) {
        window.top.Sling.CMS.ui.confirmMessage(msg, res.title, () => {
          window.top.location.reload();
        });
      } else {
        Sling.CMS.ui.confirmMessage(msg, res ? res.title : '', () => {
          Sling.CMS.ui.reloadContext();
        });
      }
    },
    confirmReloadComponent(res, msg, path) {
      window.top.Sling.CMS.ui.confirmMessage(msg, res.title, () => {
        const modal = window.top.Sling.CMS.ui.loaderModal();
        window.parent.window.CMSEditor.ui.reloadComponent(path, () => {
          modal.remove();
        });
      });
    },
    loaderModal() {
      const modal = document.createElement('div');
      modal.classList.add('modal');
      modal.innerHTML = `<div class="modal-background"></div><div class="loader is-loading"></div>`;
      document.querySelector('body').appendChild(modal);
      modal.classList.add('is-active');
      return modal;
    },
    reloadContext() {
      // close all existing modals
      document.querySelectorAll('.modal').forEach((modal) => {
        modal.remove();
      });
      // reset the actions
      document.querySelectorAll('.actions-target *').forEach((child) => {
        child.remove();
      });
      const containers = document.querySelectorAll('.reload-container');
      const modal = Sling.CMS.ui.loaderModal();
      let count = containers.length;
      if (count !== 0) {
        containers.forEach(async (container) => {
          let link = container.dataset.path;
          if (link.indexOf('?') === -1) {
            link += `?tstamp=${Date.now()}`;
          } else {
            link += `&tstamp=${Date.now()}`;
          }
          const response = await fetch(link);
          if (Sling.CMS.utils.ok(response)) {
            const responseText = await response.text();
            const tmp = document.createElement('div');
            tmp.innerHTML = responseText;
            container.replaceWith(tmp.querySelector('.reload-container'));
            tmp.remove();
            count -= 1;
            if (count === 0) {
              modal.remove();
            }
          }
        });
      } else {
        window.location.reload();
      }
    },
  },
  utils: {
    form2Obj(form) {
      const data = {};
      form.querySelectorAll('input,textarea,select').forEach((f) => {
        if (!f.disabled && f.name) {
          data[f.name] = f.value;
        }
      });
      return data;
    },
    ok(response) {
      let { CMS } = Sling;
      if (window.self !== window.top) {
        CMS = window.top.Sling.CMS;
      }
      if (response.redirected && response.url.indexOf('/system/sling/form/login?resource=') !== -1) {
        CMS.ui.confirmMessage('301', 'Not logged in, please login again', () => {
          window.location = `/system/sling/form/login?resource=${encodeURIComponent(window.location)}`;
        });
        return false;
      }
      if (!response.ok) {
        CMS.ui.confirmMessage(response.status, response.statusText, () => {
          window.location = response.url;
        });
        return false;
      }
      return true;
    },
  },
};

if (window.performance
  && window.performance.navigation.type
  === window.performance.navigation.TYPE_BACK_FORWARD) {
  Sling.CMS.ui.reloadContext();
}

window.onbeforeunload = () => {
  if (document.querySelector('.modal form')) {
    return 'Are you sure you want to leave this page?';
  }
  return null;
};

if (document.querySelector('.breadcrumb .is-active') !== null) {
  const itemTitle = document.querySelector('.breadcrumb .is-active').textContent.trim();
  if (itemTitle.length > 0) {
    document.title = `${itemTitle} :: ${document.title}`;
  }
}

rava.bind('.sling-cms-include-config', {
  callbacks: {
    created() {
      const container = this;
      async function loadContent() {
        const srcEl = document.querySelector(container.dataset.source);
        const {
          config,
        } = srcEl.selectedOptions[0].dataset;
        if (config) {
          const response = await fetch(config + container.closest('form').attributes.action.value);
          if (Sling.CMS.utils.ok(response)) {
            const markup = await response.text();
            container.innerHTML = markup;
          }
          window.parent.parent.postMessage({
            action: 'slingcms.openmodal',
            url: link,
            title,
          }, window.location.origin);
        }
      }
      document.querySelector(container.dataset.source).addEventListener('change', loadContent);
      loadContent();
    },
  },
});
