/* (license-header)
 * hores
 * Copyright (c) 2023 Adrià Vilanova Martínez
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program.
 * If not, see http://www.gnu.org/licenses/.
 */
/**
  * Functions hasClass(), addClass() and removeClass() developed by Jake Trent (http://jaketrent.com/post/addremove-classes-raw-javascript/)
  */
function hasClass(el, className) {
  if (el.classList)
    return el.classList.contains(className)
  else
    return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'))
}

function addClass(el, className) {
  if (el.classList)
    el.classList.add(className)
  else if (!hasClass(el, className)) el.className += " " + className
}

function removeClass(el, className) {
  if (el.classList)
    el.classList.remove(className)
  else if (hasClass(el, className)) {
    var reg = new RegExp('(\\s|^)' + className + '(\\s|$)')
    el.className=el.className.replace(reg, ' ')
  }
}

// MultiSelect implementation:
var MultiSelect = function MultiSelect(element) {
  this.element_ = element;
  this.selected_ = [];

  var forElId = this.element_.getAttribute("for") || this.element_.getAttribute("data-for");
  if (forElId) {
    this.forEl_ = (forElId ? document.getElementById(this.element_.getAttribute("for")) : null);
  }

  this.init();
};

MultiSelect.prototype.renderSummary = function() {
  if (this.forEl_) {
    this.forEl_.innerText = this.selected_.join(", ") || "-";
  }
};

MultiSelect.prototype.init = function() {
  if (this.element_) {
    this.element_.addEventListener("click", e => {
      e.stopImmediatePropagation();
    }, true);

    this.element_.querySelectorAll(".mdl-custom-multiselect__item").forEach(item => {
      var checkbox = item.querySelector("input[type=\"checkbox\"]");
      var label = item.querySelector(".mdl-checkbox__label").innerText;
      checkbox.addEventListener("change", e => {
        if(checkbox.checked) {
          this.selected_.push(label);
        } else {
          this.selected_ = this.selected_.filter(item => item !== label);
        }
        this.renderSummary();

        var customEvent = new Event('custom-multiselect-change');
        this.element_.dispatchEvent(customEvent);
      });
    });
  }
};

var dynDialog = {
  didItInit: false,
  dialog: null,
  url: null,
  load: function(url, reload) {
    if (this.didItInit === false) {
      this.init();
    }

    if (this.url == url && reload !== true) {
      this.show();
      return;
    }

    this.url = url;

    fetch(url).then(response => response.text()).then(response => {
      if (this.dialog.open) {
        this.close();
      }

      this.dialog.innerHTML = response;
      componentHandler.upgradeElements(this.dialog);

      this.dialog.querySelectorAll("[data-required]").forEach(input => {
        input.setAttribute("required", "true");
      });

      var script = this.dialog.querySelectorAll("dynscript");
      if (script.length > 0) {
        for (var i = 0; i < script.length; i++) {
          eval(script[i].innerText);
        }
      }
      this.dialog.querySelectorAll("[data-dyndialog-close]").forEach(btn => {
        btn.addEventListener("click", e => {
          e.preventDefault();
          this.close();
        });
      });

      this.dialog.showModal();
    });
  },
  reload: function() {
    this.load(this.url, true);
  },
  show: function() {
    this.dialog.showModal();
  },
  close: function() {
    this.dialog.close();
  },
  init: function() {
    this.dialog = document.createElement("dialog");
    this.dialog.setAttribute("id", "dynDialog");
    this.dialog.setAttribute("class", "mdl-dialog");
    dialogPolyfill.registerDialog(this.dialog);
    document.body.appendChild(this.dialog);

    this.didItInit = true;
  }
};

// From nodep-date-input-polyfill
function isDateInputSupported() {
  const input = document.createElement("input");
  input.setAttribute("type", "date");

  const notADateValue = "not-a-date";
  input.setAttribute("value", notADateValue);

  return (input.value !== notADateValue);
}

document.addEventListener("DOMContentLoaded", function() {
  var dialogs = document.querySelectorAll("dialog");
  for (var i = 0; i < dialogs.length; i++) {
    dialogPolyfill.registerDialog(dialogs[i]);
  }

  document.querySelectorAll("[data-dyndialog-href]").forEach(link => {
    link.addEventListener("click", e => {
      e.preventDefault();
      dynDialog.load(link.getAttribute("data-dyndialog-href"));
    });
  });

  document.querySelectorAll(".mdl-custom-multiselect-js").forEach(menu => {
    new MultiSelect(menu);
  });
});

function importCSS(url) {
  var link = document.createElement("link");
  link.setAttribute("rel", "stylesheet");
  link.setAttribute("href", url);
  document.head.appendChild(link);
}

var loadScriptAsync = function(uri) {
  return new Promise((resolve, reject) => {
    var script = document.createElement('script');
    script.src = uri;
    script.async = true;
    script.onload = () => {
      resolve();
    };
    document.head.appendChild(script);
  });
}

function hasParentDialog(el) {
  while (el != document.documentElement) {
    if (el.tagName == "DIALOG") {
      return el;
    }

    el = el.parentNode;
  }

  return undefined;
}

function polyfillDateSupport(container) {
  container.querySelectorAll("input[type=\"date\"]").forEach(el => {
    el.setAttribute("type", "text");

    dialogParent = hasParentDialog(el);

    var options = {
      format: "yyyy-mm-dd",
      todayHighlight: true,
      weekStart: 1,
      zIndexOffset: 100,
      container: dialogParent || container
    };

    if (el.hasAttribute("max")) {
      options.endDate = el.getAttribute("max");
    }

    $(el).datepicker(options);
  });

  container.querySelectorAll("input[type=\"time\"]").forEach(el => {
    el.setAttribute("placeholder", "hh:mm");
  });
}

function initPolyfillDateSupport() {
  console.info("Polyfilling date support");

  importCSS("https://unpkg.com/bootstrap-datepicker@1.9.0/dist/css/bootstrap-datepicker3.standalone.min.css", "css");

  loadScriptAsync("https://unpkg.com/jquery@3.4.1/dist/jquery.min.js", "js").then(_ => {
    return loadScriptAsync("https://unpkg.com/bootstrap-datepicker@1.9.0/dist/js/bootstrap-datepicker.min.js");
  }).then(_ => {
    return loadScriptAsync("https://unpkg.com/bootstrap-datepicker@1.9.0/dist/locales/bootstrap-datepicker.es.min.js");
  }).then(_ => {
    console.log("[Date polyfill] Scripts loaded.");
    polyfillDateSupport(document.documentElement);
  });
}

window.addEventListener("load", function() {
  document.querySelectorAll("[data-required]").forEach(input => {
    input.setAttribute("required", "true");
  });

  if (!isDateInputSupported()) {
    initPolyfillDateSupport();
  }
});
